alexdunae-w3c_validators 1.0.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.
- data/CHANGELOG +19 -0
- data/LICENSE +60 -0
- data/README.rdoc +122 -0
- data/lib/w3c_validators.rb +6 -0
- data/lib/w3c_validators/constants.rb +80 -0
- data/lib/w3c_validators/css_validator.rb +149 -0
- data/lib/w3c_validators/exceptions.rb +4 -0
- data/lib/w3c_validators/feed_validator.rb +110 -0
- data/lib/w3c_validators/markup_validator.rb +227 -0
- data/lib/w3c_validators/message.rb +82 -0
- data/lib/w3c_validators/nu_validator.rb +144 -0
- data/lib/w3c_validators/results.rb +62 -0
- data/lib/w3c_validators/validator.rb +160 -0
- data/test/test_css_validator.rb +51 -0
- data/test/test_exceptions.rb +35 -0
- data/test/test_feed_validator.rb +61 -0
- data/test/test_helper.rb +6 -0
- data/test/test_html5_validator.rb +64 -0
- data/test/test_markup_validator.rb +94 -0
- metadata +77 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
module W3CValidators
|
2
|
+
class FeedValidator < Validator
|
3
|
+
FEED_VALIDATOR_URI = 'http://validator.w3.org/feed/check.cgi'
|
4
|
+
|
5
|
+
# Create a new instance of the FeedValidator.
|
6
|
+
#
|
7
|
+
# ==== Options
|
8
|
+
# You can pass in your own validator's URI (i.e.
|
9
|
+
# <tt>FeedValidator.new(:validator_uri => 'http://localhost/check')</tt>).
|
10
|
+
def initialize(options = {})
|
11
|
+
if options[:validator_uri]
|
12
|
+
@validator_uri = URI.parse(options[:validator_uri])
|
13
|
+
options.delete(options[:validator_uri])
|
14
|
+
else
|
15
|
+
@validator_uri = URI.parse(FEED_VALIDATOR_URI)
|
16
|
+
end
|
17
|
+
super(options)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Validate a feed URI using a +SOAP+ request.
|
21
|
+
#
|
22
|
+
# Returns W3CValidators::Results.
|
23
|
+
def validate_uri(url)
|
24
|
+
return validate({:url => url})
|
25
|
+
end
|
26
|
+
|
27
|
+
# Validate a feed from a string.
|
28
|
+
#
|
29
|
+
# Returns W3CValidators::Results.
|
30
|
+
def validate_text(text)
|
31
|
+
return validate({:rawdata => text})
|
32
|
+
end
|
33
|
+
|
34
|
+
# Validate a local feed file.
|
35
|
+
#
|
36
|
+
# +file_path+ may be either the fully-expanded path to the file or
|
37
|
+
# an IO object (like File).
|
38
|
+
#
|
39
|
+
# Returns W3CValidators::Results.
|
40
|
+
def validate_file(file_path)
|
41
|
+
if file_path.respond_to? :read
|
42
|
+
src = file_path.read
|
43
|
+
else
|
44
|
+
src = read_local_file(file_path)
|
45
|
+
end
|
46
|
+
return validate_text(src)
|
47
|
+
end
|
48
|
+
|
49
|
+
protected
|
50
|
+
def validate(options) # :nodoc:
|
51
|
+
options = get_request_options(options)
|
52
|
+
response = send_request(options, :get)
|
53
|
+
@results = parse_soap_response(response.body)
|
54
|
+
@results
|
55
|
+
end
|
56
|
+
|
57
|
+
# Perform sanity checks on request params
|
58
|
+
def get_request_options(options) # :nodoc:
|
59
|
+
options = @options.merge(options)
|
60
|
+
|
61
|
+
options[:output] = SOAP_OUTPUT_PARAM
|
62
|
+
|
63
|
+
unless options[:url] or options[:rawdata]
|
64
|
+
raise ArgumentError, "an url or rawdata is required."
|
65
|
+
end
|
66
|
+
|
67
|
+
# URL should be a string. If it is a URL object, .to_s will
|
68
|
+
# be seamless; if it is not an exception will be raised.
|
69
|
+
if options[:url] and not options[:url].kind_of?(String)
|
70
|
+
options[:url] = options[:url].to_s
|
71
|
+
end
|
72
|
+
|
73
|
+
options
|
74
|
+
end
|
75
|
+
|
76
|
+
# Parse the SOAP XML response.
|
77
|
+
#
|
78
|
+
# +response+ must be a Net::HTTPResponse.
|
79
|
+
#
|
80
|
+
# Returns W3CValidators::Results.
|
81
|
+
def parse_soap_response(response) # :nodoc:
|
82
|
+
doc = REXML::Document.new(response)
|
83
|
+
|
84
|
+
result_params = {}
|
85
|
+
|
86
|
+
{:uri => 'uri', :checked_by => 'checkedby', :validity => 'validity'}.each do |local_key, remote_key|
|
87
|
+
if val = doc.elements["//*[local-name()='feedvalidationresponse']/*[local-name()='#{remote_key.to_s}']"]
|
88
|
+
result_params[local_key] = val.text
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
results = Results.new(result_params)
|
93
|
+
|
94
|
+
[:warning, :error].each do |msg_type|
|
95
|
+
doc.elements.each("//*[local-name()='#{msg_type.to_s}']") do |message|
|
96
|
+
message_params = {}
|
97
|
+
message.each_element_with_text do |el|
|
98
|
+
message_params[el.name.to_sym] = el.text
|
99
|
+
end
|
100
|
+
results.add_message(msg_type, message_params)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
return results
|
105
|
+
|
106
|
+
rescue Exception => e
|
107
|
+
handle_exception e
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
module W3CValidators
|
2
|
+
class MarkupValidator < Validator
|
3
|
+
MARKUP_VALIDATOR_URI = 'http://validator.w3.org/check'
|
4
|
+
|
5
|
+
# Create a new instance of the MarkupValidator.
|
6
|
+
#
|
7
|
+
# ==== Options
|
8
|
+
# The +options+ hash allows you to set request parameters (see
|
9
|
+
# http://validator.w3.org/docs/api.html#requestformat) quickly. Request
|
10
|
+
# parameters can also be set using set_charset!, set_debug! and set_doctype!.
|
11
|
+
#
|
12
|
+
# You can pass in your own validator's URI (i.e.
|
13
|
+
# <tt>MarkupValidator.new(:validator_uri => 'http://localhost/check')</tt>).
|
14
|
+
def initialize(options = {})
|
15
|
+
if options[:validator_uri]
|
16
|
+
@validator_uri = URI.parse(options[:validator_uri])
|
17
|
+
options.delete(options[:validator_uri])
|
18
|
+
else
|
19
|
+
@validator_uri = URI.parse(MARKUP_VALIDATOR_URI)
|
20
|
+
end
|
21
|
+
super(options)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Specify the character encoding to use when parsing the document.
|
25
|
+
#
|
26
|
+
# When +only_as_fallback+ is +true+, the given encoding will only be
|
27
|
+
# used as a fallback value, in case the +charset+ is absent or unrecognized.
|
28
|
+
#
|
29
|
+
# +charset+ can be a string (e.g. <tt>set_charset!('utf-8')</tt>) or
|
30
|
+
# a symbol (e.g. <tt>set_charset!(:utf_8)</tt>) from the
|
31
|
+
# W3CValidators::CHARSETS hash.
|
32
|
+
#
|
33
|
+
# Has no effect when using validate_uri_quickly.
|
34
|
+
def set_charset!(charset, only_as_fallback = false)
|
35
|
+
if charset.kind_of?(Symbol)
|
36
|
+
if CHARSETS.has_key?(charset)
|
37
|
+
charset = CHARSETS[charset]
|
38
|
+
else
|
39
|
+
return
|
40
|
+
end
|
41
|
+
end
|
42
|
+
@options[:charset] = charset
|
43
|
+
@options[:fbc] = only_as_fallback
|
44
|
+
end
|
45
|
+
|
46
|
+
# Specify the Document Type (+DOCTYPE+) to use when parsing the document.
|
47
|
+
#
|
48
|
+
# When +only_as_fallback+ is +true+, the given document type will only be
|
49
|
+
# used as a fallback value, in case the document's +DOCTYPE+ declaration
|
50
|
+
# is missing or unrecognized.
|
51
|
+
#
|
52
|
+
# +doctype+ can be a string (e.g. <tt>set_doctype!('HTML 3.2')</tt>) or
|
53
|
+
# a symbol (e.g. <tt>set_doctype!(:html32)</tt>) from the
|
54
|
+
# W3CValidators::DOCTYPES hash.
|
55
|
+
#
|
56
|
+
# Has no effect when using validate_uri_quickly.
|
57
|
+
def set_doctype!(doctype, only_as_fallback = false)
|
58
|
+
if doctype.kind_of?(Symbol)
|
59
|
+
if DOCTYPES.has_key?(doctype)
|
60
|
+
doctype = DOCTYPES[doctype]
|
61
|
+
else
|
62
|
+
return
|
63
|
+
end
|
64
|
+
end
|
65
|
+
@options[:doctype] = doctype
|
66
|
+
@options[:fbd] = only_as_fallback
|
67
|
+
end
|
68
|
+
|
69
|
+
# When set the validator will output some extra debugging information on
|
70
|
+
# the validated resource (such as HTTP headers) and validation process
|
71
|
+
# (such as parser used, parse mode, etc.).
|
72
|
+
#
|
73
|
+
# Debugging information is stored in the Results +debug_messages+ hash.
|
74
|
+
# Custom debugging messages can be set with Results#add_debug_message.
|
75
|
+
#
|
76
|
+
# Has no effect when using validate_uri_quickly.
|
77
|
+
def set_debug!(debug = true)
|
78
|
+
@options[:debug] = debug
|
79
|
+
end
|
80
|
+
|
81
|
+
# Validate the markup of an URI using a +SOAP+ request.
|
82
|
+
#
|
83
|
+
# Returns W3CValidators::Results.
|
84
|
+
def validate_uri(uri)
|
85
|
+
return validate({:uri => uri}, false)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Validate the markup of an URI using a +HEAD+ request.
|
89
|
+
#
|
90
|
+
# Returns W3CValidators::Results with an error count, not full error messages.
|
91
|
+
def validate_uri_quickly(uri)
|
92
|
+
return validate({:uri => uri}, true)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Validate the markup of a string.
|
96
|
+
#
|
97
|
+
# Returns W3CValidators::Results.
|
98
|
+
def validate_text(text)
|
99
|
+
return validate({:fragment => text}, false)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Validate the markup of a local file.
|
103
|
+
#
|
104
|
+
# +file_path+ may be either the fully-expanded path to the file or
|
105
|
+
# an IO object (like File).
|
106
|
+
#
|
107
|
+
# Returns W3CValidators::Results.
|
108
|
+
def validate_file(file_path)
|
109
|
+
if file_path.respond_to? :read
|
110
|
+
src = file_path.read
|
111
|
+
else
|
112
|
+
src = read_local_file(file_path)
|
113
|
+
end
|
114
|
+
|
115
|
+
return validate({:uploaded_file => src, :file_path => file_path}, false)
|
116
|
+
end
|
117
|
+
|
118
|
+
protected
|
119
|
+
def validate(options, quick = false) # :nodoc:
|
120
|
+
options = get_request_options(options)
|
121
|
+
|
122
|
+
if quick
|
123
|
+
response = send_request(options, :head)
|
124
|
+
@results = parse_head_response(response, options[:uri])
|
125
|
+
else
|
126
|
+
if options.has_key?(:uri) or options.has_key?(:fragment)
|
127
|
+
response = send_request(options, :get)
|
128
|
+
else
|
129
|
+
response = send_request(options, :post)
|
130
|
+
end
|
131
|
+
|
132
|
+
@results = parse_soap_response(response.body)
|
133
|
+
end
|
134
|
+
@results
|
135
|
+
end
|
136
|
+
|
137
|
+
# Perform sanity checks on request params
|
138
|
+
def get_request_options(options) # :nodoc:
|
139
|
+
options = @options.merge(options)
|
140
|
+
|
141
|
+
options[:output] = SOAP_OUTPUT_PARAM
|
142
|
+
|
143
|
+
unless options[:uri] or options[:uploaded_file] or options[:fragment]
|
144
|
+
raise ArgumentError, "an uri, uploaded file or fragment is required."
|
145
|
+
end
|
146
|
+
|
147
|
+
# URI should be a string. If it is a URI object, .to_s will
|
148
|
+
# be seamless; if it is not an exception will be raised.
|
149
|
+
if options[:uri] and not options[:uri].kind_of?(String)
|
150
|
+
options[:uri] = options[:uri].to_s
|
151
|
+
end
|
152
|
+
|
153
|
+
# Convert booleans to integers
|
154
|
+
[:fbc, :fbd, :verbose, :debug, :ss, :outline].each do |k|
|
155
|
+
if options.has_key?(k) and not options[k].kind_of?(Fixnum)
|
156
|
+
options[k] = options[k] ? 1 : 0
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
options
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
# Parse the SOAP XML response.
|
165
|
+
#
|
166
|
+
# +response+ must be a Net::HTTPResponse.
|
167
|
+
#
|
168
|
+
# Returns W3CValidators::Results.
|
169
|
+
def parse_soap_response(response) # :nodoc:
|
170
|
+
doc = REXML::Document.new(response)
|
171
|
+
|
172
|
+
result_params = {}
|
173
|
+
|
174
|
+
{:doctype => 'm:doctype', :uri => 'm:uri', :charset => 'm:charset',
|
175
|
+
:checked_by => 'm:checkedby', :validity => 'm:validity'}.each do |local_key, remote_key|
|
176
|
+
if val = doc.elements["env:Envelope/env:Body/m:markupvalidationresponse/#{remote_key}"]
|
177
|
+
result_params[local_key] = val.text
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
results = Results.new(result_params)
|
182
|
+
|
183
|
+
{:warning => 'm:warnings/m:warninglist/m:warning', :error => 'm:errors/m:errorlist/m:error'}.each do |local_type, remote_type|
|
184
|
+
doc.elements.each("env:Envelope/env:Body/m:markupvalidationresponse/#{remote_type}") do |message|
|
185
|
+
message_params = {}
|
186
|
+
message.each_element_with_text do |el|
|
187
|
+
message_params[el.name.to_sym] = el.text
|
188
|
+
end
|
189
|
+
results.add_message(local_type, message_params)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
doc.elements.each("env:Envelope/env:Body/env:Fault/env:Reason") do |message|
|
194
|
+
message.elements.each("env:Text") do |m|
|
195
|
+
results.add_message(:error, {:mesage => m.text})
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
doc.elements.each("env:Envelope/env:Body/m:markupvalidationresponse/m:debug") do |debug|
|
200
|
+
results.add_debug_message(debug.attribute('name').value, debug.text)
|
201
|
+
end
|
202
|
+
return results
|
203
|
+
|
204
|
+
rescue Exception => e
|
205
|
+
handle_exception e
|
206
|
+
end
|
207
|
+
|
208
|
+
# Parse the HEAD response into HTMLValidator::Results.
|
209
|
+
#
|
210
|
+
# +response+ must be a Net::HTTPResponse.
|
211
|
+
#
|
212
|
+
# Returns Results.
|
213
|
+
def parse_head_response(response, validated_uri = nil) # :nodoc:
|
214
|
+
validity = (response[HEAD_STATUS_HEADER].downcase == 'valid')
|
215
|
+
|
216
|
+
results = Results.new(:uri => validated_uri, :validity => validity)
|
217
|
+
|
218
|
+
# Fill the results with empty error messages so we can count them
|
219
|
+
errors = response[HEAD_ERROR_COUNT_HEADER].to_i
|
220
|
+
errors.times { results.add_error }
|
221
|
+
|
222
|
+
results
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module W3CValidators
|
2
|
+
class Message
|
3
|
+
attr_accessor :type, :line, :col, :source, :explanation, :message, :message_id
|
4
|
+
attr_accessor :message_count, :element, :parent, :value
|
5
|
+
|
6
|
+
MESSAGE_TYPES = [:warning, :error]
|
7
|
+
|
8
|
+
# Due to the responses received from the W3C's validators, different data
|
9
|
+
# are available for different validation types.
|
10
|
+
#
|
11
|
+
# ==== Feed validation
|
12
|
+
# * +line+
|
13
|
+
# * +col+
|
14
|
+
# * +message+ (originally +text+)
|
15
|
+
# * +message_count+
|
16
|
+
# * +element+
|
17
|
+
# * +parent+
|
18
|
+
# * +value+
|
19
|
+
# See http://validator.w3.org/feed/docs/soap.html#soap12message for full explanations.
|
20
|
+
#
|
21
|
+
# ==== Markup validation
|
22
|
+
# * +line+
|
23
|
+
# * +col+
|
24
|
+
# * +message+
|
25
|
+
# * +message_id+
|
26
|
+
# * +explanation+
|
27
|
+
# * +source+
|
28
|
+
# See http://validator.w3.org/docs/api.html#soap12message for full explanations.
|
29
|
+
#
|
30
|
+
# ==== CSS validation (http://jigsaw.w3.org/css-validator/api.html#soap12message)
|
31
|
+
# * +level+
|
32
|
+
# * +line+
|
33
|
+
# * +message+
|
34
|
+
# See http://jigsaw.w3.org/css-validator/api.html#soap12message for full explanations.
|
35
|
+
def initialize(uri, message_type, options = {})
|
36
|
+
@type = message_type
|
37
|
+
@uri = uri
|
38
|
+
|
39
|
+
# All validators
|
40
|
+
@line = options[:line]
|
41
|
+
@col = options[:col]
|
42
|
+
|
43
|
+
# MarkupValidator
|
44
|
+
@source = options[:source]
|
45
|
+
@explanation = options[:explanation]
|
46
|
+
@message = options[:message]
|
47
|
+
@message_id = options[:messageid]
|
48
|
+
|
49
|
+
# FeedValidator
|
50
|
+
@message = options[:text] unless @message
|
51
|
+
@message_count = options[:message_count]
|
52
|
+
@element = options[:element]
|
53
|
+
@parent = options[:parent]
|
54
|
+
@value = options[:value]
|
55
|
+
|
56
|
+
# CSSValidator
|
57
|
+
@level = options[:level]
|
58
|
+
end
|
59
|
+
|
60
|
+
def is_warning?
|
61
|
+
@type == :warning
|
62
|
+
end
|
63
|
+
|
64
|
+
def is_error?
|
65
|
+
@type == :error
|
66
|
+
end
|
67
|
+
|
68
|
+
# Return the message as a string.
|
69
|
+
def to_s
|
70
|
+
str = @type.to_s.upcase
|
71
|
+
if @uri and not @uri.empty?
|
72
|
+
str << "; URI: #{@uri}"
|
73
|
+
end
|
74
|
+
str << "; line #{@line}"
|
75
|
+
if @message and not @message.empty?
|
76
|
+
str << ": #{@message}"
|
77
|
+
end
|
78
|
+
return str
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module W3CValidators
|
4
|
+
class NuValidator < Validator
|
5
|
+
MARKUP_VALIDATOR_URI = 'http://validator.nu/'
|
6
|
+
|
7
|
+
# Create a new instance of the NuValidator.
|
8
|
+
#
|
9
|
+
# ==== Options
|
10
|
+
# The +options+ hash allows you to set request parameters (see
|
11
|
+
# http://wiki.whatwg.org/wiki/Validator.nu_Common_Input_Parameters) quickly. Request
|
12
|
+
# parameters can also be set using set_charset! and set_doctype!.
|
13
|
+
#
|
14
|
+
# You can pass in your own validator's URI (i.e.
|
15
|
+
# <tt>NuValidator.new(:validator_uri => 'http://localhost/check')</tt>).
|
16
|
+
def initialize(options = {})
|
17
|
+
if options[:validator_uri]
|
18
|
+
@validator_uri = URI.parse(options[:validator_uri])
|
19
|
+
options.delete(options[:validator_uri])
|
20
|
+
else
|
21
|
+
@validator_uri = URI.parse(MARKUP_VALIDATOR_URI)
|
22
|
+
end
|
23
|
+
super(options)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
# Validate the markup of an URI.
|
28
|
+
#
|
29
|
+
# Returns W3CValidators::Results.
|
30
|
+
def validate_uri(uri)
|
31
|
+
return validate({:doc => uri})
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
# Validate the markup of a string.
|
36
|
+
#
|
37
|
+
# Returns W3CValidators::Results.
|
38
|
+
def validate_text(text)
|
39
|
+
return validate({:content => text})
|
40
|
+
end
|
41
|
+
|
42
|
+
# Validate the markup of a local file.
|
43
|
+
#
|
44
|
+
# +file_path+ may be either the fully-expanded path to the file or
|
45
|
+
# an IO object (like File).
|
46
|
+
#
|
47
|
+
# Returns W3CValidators::Results.
|
48
|
+
def validate_file(file)
|
49
|
+
if file.respond_to? :read
|
50
|
+
src = file.read
|
51
|
+
file_path = file.path ||= nil
|
52
|
+
else
|
53
|
+
src = read_local_file(file)
|
54
|
+
file_path = file
|
55
|
+
end
|
56
|
+
|
57
|
+
return validate({:file => src, :file_path => file_path})
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
def validate(options) # :nodoc:
|
62
|
+
options = get_request_options(options)
|
63
|
+
|
64
|
+
if options.has_key?(:doc)
|
65
|
+
response = send_request(options, :get)
|
66
|
+
else
|
67
|
+
response = send_request(options, :post)
|
68
|
+
end
|
69
|
+
|
70
|
+
@results = parse_json_response(response.body)
|
71
|
+
@results
|
72
|
+
end
|
73
|
+
|
74
|
+
# Perform sanity checks on request params
|
75
|
+
def get_request_options(options) # :nodoc:
|
76
|
+
options = @options.merge(options)
|
77
|
+
|
78
|
+
options[:out] = 'json'
|
79
|
+
|
80
|
+
# only option that is currently supported
|
81
|
+
options[:showsource] = 'yes'
|
82
|
+
|
83
|
+
unless options[:doc] or options[:file] or options[:content]
|
84
|
+
raise ArgumentError, "an uri, file or block of text is required."
|
85
|
+
end
|
86
|
+
|
87
|
+
# URI should be a string. If it is a URI object, .to_s will
|
88
|
+
# be seamless; if it is not an exception will be raised.
|
89
|
+
if options[:doc] and not options[:doc].kind_of?(String)
|
90
|
+
options[:doc] = options[:doc].to_s
|
91
|
+
end
|
92
|
+
options
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
# Parse the JSON response.
|
97
|
+
#
|
98
|
+
# +response+ must be a Net::HTTPResponse.
|
99
|
+
#
|
100
|
+
# Returns W3CValidators::Results.
|
101
|
+
def parse_json_response(response) # :nodoc:
|
102
|
+
doc = JSON.parse(response)
|
103
|
+
|
104
|
+
result_params = {
|
105
|
+
:doctype => :html5,
|
106
|
+
:checked_by => MARKUP_VALIDATOR_URI
|
107
|
+
}
|
108
|
+
|
109
|
+
result_params[:uri] = doc['url'] ||= nil
|
110
|
+
if doc['source']
|
111
|
+
result_params[:charset] = doc['source']['encoding'] ||= nil
|
112
|
+
end
|
113
|
+
|
114
|
+
result_params[:validity] = !doc['messages'].any? { |msg| msg['type'] =~ /^error$/i }
|
115
|
+
|
116
|
+
results = Results.new(result_params)
|
117
|
+
|
118
|
+
doc['messages'].each do |msg|
|
119
|
+
if msg['type'] =~ /^error$/i
|
120
|
+
msg_type = :error
|
121
|
+
elsif msg['subType'] =~ /^warning$/
|
122
|
+
msg_type = :warning
|
123
|
+
else
|
124
|
+
next
|
125
|
+
# TODO: should throw exceptions here
|
126
|
+
end
|
127
|
+
|
128
|
+
message_params = {
|
129
|
+
:line => msg['firstLine'],
|
130
|
+
:col => msg['firstColumn'],
|
131
|
+
:message => msg['message'],
|
132
|
+
:source => msg['extract']
|
133
|
+
}
|
134
|
+
|
135
|
+
results.add_message(msg_type, message_params)
|
136
|
+
end
|
137
|
+
|
138
|
+
return results
|
139
|
+
|
140
|
+
rescue Exception => e
|
141
|
+
handle_exception e
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|