Class | HTMLConformanceChecker |
In: |
lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb
|
Parent: | HTML5::Filters::Base |
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 267 267: def initialize(stream, *args) 268: super(HTML5::HTMLTokenizer.new(stream, *args)) 269: @things_that_define_an_id = [] 270: @things_that_point_to_an_id = [] 271: @ids_we_have_known_and_loved = [] 272: end
Attribute validation
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 655 655: def check_attribute_values(token) 656: tag_name = token.fetch(:name, "") 657: for attr_name, attr_value in token.fetch(:data, []) 658: attr_name = attr_name.downcase 659: method = "validate_attribute_value_#{tag_name.to_s.underscore}_#{attr_name.to_s.underscore}" 660: if respond_to?(method) 661: send(method, token, tag_name, attr_name, attr_value) do |t| 662: yield t 663: end 664: else 665: method = "validate_attribute_value_#{attr_name.to_s.underscore}" 666: if respond_to?(method) 667: send(method, token, tag_name, attr_name, attr_value) do |t| 668: yield t 669: end 670: end 671: end 672: end 673: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 514 514: def check_boolean(token, tag_name, attr_name, attr_value) 515: enumerated_values = [attr_name, ''] 516: if !enumerated_values.include?(attr_value) 517: yield( {:type => "ParseError", 518: :data => "invalid-boolean-value", 519: :datavars => {"tagName" => tag_name, 520: "attributeName" => attr_name, 521: "enumeratedValues" => enumerated_values}}) 522: yield( {:type => "ParseError", 523: :data => "invalid-attribute-value", 524: :datavars => {"tagName" => tag_name, 525: "attributeName" => attr_name}}) 526: end 527: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 581 581: def check_browsing_context(token, tag_name, attr_name, attr_value) 582: return if not attr_value 583: return if attr_value[0] != ?_ 584: attr_value.downcase! 585: return if ['_self', '_parent', '_top', '_blank'].include?(attr_value) 586: yield({:type => "ParseError", 587: :data => "invalid-browsing-context", 588: :datavars => {"tagName" => tag_name, 589: "attributeName" => attr_name}}) 590: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 640 640: def check_date_time(token, tag_name, attr_name, attr_value) 641: # XXX 642: state = 'begin' # ('begin', '... 643: # for c in attr_value 644: # if state == 'begin' => 645: # if SPACE_CHARACTERS.include?(c) 646: # continue 647: # elsif digits.include?(c) 648: # state = ... 649: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 492 492: def check_enumerated_value(token, tag_name, attr_name, attr_value, enumerated_values) 493: if !attr_value || attr_value.length == 0 494: yield( {:type => "ParseError", 495: :data => "attribute-value-can-not-be-blank", 496: :datavars => {"tagName" => tag_name, 497: "attributeName" => attr_name}}) 498: return 499: end 500: attr_value.downcase! 501: if !enumerated_values.include?(attr_value) 502: yield( {:type => "ParseError", 503: :data => "invalid-enumerated-value", 504: :datavars => {"tagName" => tag_name, 505: "attribute_name" => attr_name, 506: "enumeratedValues" => enumerated_values}}) 507: yield( {:type => "ParseError", 508: :data => "invalid-attribute-value", 509: :datavars => {"tagName" => tag_name, 510: "attributeName" => attr_name}}) 511: end 512: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 577 577: def check_floating_point_number(token, tag_name, attr_name, attr_value) 578: # XXX 579: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 429 429: def check_id(token, tag_name, attr_name, attr_value) 430: if !attr_value || attr_value.length == 0 431: yield({:type => "ParseError", 432: :data => "attribute-value-can-not-be-blank", 433: :datavars => {"tagName" => tag_name, 434: "attributeName" => attr_name}}) 435: end 436: attr_value.each_byte do |b| 437: c = [b].pack('c*') 438: if HTML5::SPACE_CHARACTERS.include?(c) 439: yield( {:type => "ParseError", 440: :data => "space-in-id", 441: :datavars => {"tagName" => tag_name, 442: "attributeName" => attr_name}}) 443: yield( {:type => "ParseError", 444: :data => "invalid-attribute-value", 445: :datavars => {"tagName" => tag_name, 446: "attributeName" => attr_name}}) 447: break 448: end 449: end 450: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 529 529: def check_integer(token, tag_name, attr_name, attr_value) 530: sign = 1 531: number_string = '' 532: state = 'begin' # ('begin', 'initial-number', 'number', 'trailing-junk') 533: error = {:type => "ParseError", 534: :data => "invalid-integer-value", 535: :datavars => {"tagName" => tag_name, 536: "attributeName" => attr_name, 537: "attributeValue" => attr_value}} 538: attr_value.scan(/./) do |c| 539: if state == 'begin' 540: if HTML5::SPACE_CHARACTERS.include?(c) 541: next 542: elsif c == '-' 543: sign = -1 544: state = 'initial-number' 545: elsif HTML5::DIGITS.include?(c) 546: number_string += c 547: state = 'in-number' 548: else 549: yield error 550: return 551: end 552: elsif state == 'initial-number' 553: if !HTML5::DIGITS.include?(c) 554: yield error 555: return 556: end 557: number_string += c 558: state = 'in-number' 559: elsif state == 'in-number' 560: if HTML5::DIGITS.include?(c) 561: number_string += c 562: else 563: state = 'trailing-junk' 564: end 565: elsif state == 'trailing-junk' 566: next 567: end 568: end 569: if number_string.length == 0 570: yield( {:type => "ParseError", 571: :data => "attribute-value-can-not-be-blank", 572: :datavars => {"tagName" => tag_name, 573: "attributeName" => attr_name}}) 574: end 575: end
def checkURI(token, tag_name, attr_name, attr_value)
is_valid, error_code = rfc3987.is_valid_uri(attr_value) if not is_valid yield {:type => "ParseError", :data => error_code, :datavars => {"tagName" => tag_name, "attributeName" => attr_name}} yield {:type => "ParseError", :data => "invalid-attribute-value", :datavars => {"tagName" => tag_name, "attributeName" => attr_name}}
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 415 415: def check_iri(token, tag_name, attr_name, attr_value) 416: is_valid, error_code = is_valid_iri(attr_value) 417: if !is_valid 418: yield({:type => "ParseError", 419: :data => error_code, 420: :datavars => {"tagName" => tag_name, 421: "attributeName" => attr_name}}) 422: yield({:type => "ParseError", 423: :data => "invalid-attribute-value", 424: :datavars => {"tagName" => tag_name, 425: "attributeName" => attr_name}}) 426: end 427: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 592 592: def check_lang_code(token, tag_name, attr_name, attr_value) 593: return if !attr_value || attr_value == '' # blank is OK 594: if not is_valid_lang_code(attr_value) 595: yield( {:type => "ParseError", 596: :data => "invalid-lang-code", 597: :datavars => {"tagName" => tag_name, 598: "attributeName" => attr_name, 599: "attributeValue" => attr_value}}) 600: end 601: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 624 624: def check_link_relation(token, tag_name, attr_name, attr_value) 625: check_token_list(tag_name, attr_name, attr_value) do |t| 626: yield t 627: end 628: value_list = parse_token_list(attr_value) 629: allowed_values = tag_name == 'link' ? @@link_rel_values : @@a_rel_values 630: for current_value in value_list 631: if !allowed_values.include?(current_value) 632: yield({:type => "ParseError", 633: :data => "invalid-rel", 634: :datavars => {"tagName" => tag_name, 635: "attributeName" => attr_name}}) 636: end 637: end 638: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 620 620: def check_media_query(token, tag_name, attr_name, attr_value) 621: # XXX 622: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 603 603: def check_mime_type(token, tag_name, attr_name, attr_value) 604: # XXX needs tests 605: if not attr_value 606: yield( {:type => "ParseError", 607: :data => "attribute-value-can-not-be-blank", 608: :datavars => {"tagName" => tag_name, 609: "attributeName" => attr_name}}) 610: end 611: if not is_valid_mime_type(attr_value) 612: yield( {:type => "ParseError", 613: :data => "invalid-mime-type", 614: :datavars => {"tagName" => tag_name, 615: "attributeName" => attr_name, 616: "attributeValue" => attr_value}}) 617: end 618: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 369 369: def check_start_tag_required_attributes(token) 370: # check for presence of required attributes 371: name = (token[:name] || "").downcase 372: if @@required_attribute_map.keys().include?(name) 373: attrs_present = (token[:data] || []).collect{|t| t[0]} 374: for attr_name in @@required_attribute_map[name] 375: if !attrs_present.include?(attr_name) 376: yield( {:type => "ParseError", 377: :data => "missing-required-attribute", 378: :datavars => {"tagName" => name, 379: "attributeName" => attr_name}}) 380: end 381: end 382: end 383: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 385 385: def check_start_tag_unknown_attributes(token) 386: # check for recognized attribute names 387: name = token[:name].downcase 388: allowed_attributes = @@global_attributes | @@allowed_attribute_map.fetch(name, []) 389: for attr_name, attr_value in token.fetch(:data, []) 390: if !allowed_attributes.include?(attr_name.downcase()) 391: yield( {:type => "ParseError", 392: :data => "unknown-attribute", 393: :datavars => {"tagName" => name, 394: "attributeName" => attr_name}}) 395: end 396: end 397: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 472 472: def check_token_list(tag_name, attr_name, attr_value) 473: # The "token" in the method name refers to tokens in an attribute value 474: # i.e. http://www.whatwg.org/specs/web-apps/current-work/#set-of 475: # but the "token" parameter refers to the token generated from 476: # HTMLTokenizer. Sorry for the confusion. 477: value_list = parse_token_list(attr_value) 478: value_dict = {} 479: for current_value in value_list 480: if value_dict.has_key?(current_value) 481: yield({:type => "ParseError", 482: :data => "duplicate-value-in-token-list", 483: :datavars => {"tagName" => tag_name, 484: "attributeName" => attr_name, 485: "attributeValue" => current_value}}) 486: break 487: end 488: value_dict[current_value] = 1 489: end 490: end
Start tag validation helpers
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 359 359: def check_unknown_start_tag(token) 360: # check for recognized tag name 361: name = (token[:name] || "").downcase 362: if !@@allowed_attribute_map.keys.include?(name) 363: yield({:type => "ParseError", 364: :data => "unknown-start-tag", 365: :datavars => {"tagName" => name}}) 366: end 367: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 274 274: def each 275: __getobj__.each do |token| 276: method = "validate_#{token.fetch(:type, '-').to_s.underscore}_#{token.fetch(:name, '-').to_s.underscore}" 277: if respond_to?(method) 278: send(method, token){|t| yield t } 279: else 280: method = "validate_#{token.fetch(:type, '-').to_s.underscore}" 281: if respond_to?(method) 282: send(method, token) do |t| 283: yield t 284: end 285: end 286: end 287: yield token 288: end 289: eof do |t| 290: yield t 291: end 292: end
Whole document validation (IDs, etc.)
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 801 801: def eof 802: for token in @things_that_point_to_an_id 803: tag_name = token.fetch(:name, "").downcase 804: attrs_dict = token[:data] # by now html5parser has "normalized" the attrs list into a dict. 805: # hooray for obscure side effects! 806: attr_value = attrs_dict.fetch("contextmenu", "") 807: if attr_value and (!@ids_we_have_known_and_loved.include?(attr_value)) 808: yield( {:type => "ParseError", 809: :data => "id-does-not-exist", 810: :datavars => {"tagName" => tag_name, 811: "attributeName" => "contextmenu", 812: "attributeValue" => attr_value}}) 813: else 814: for ref_token in @things_that_define_an_id 815: id = ref_token.fetch(:data, {}).fetch("id", "") 816: if not id 817: continue 818: end 819: if id == attr_value 820: if ref_token.fetch(:name, "").downcase != "men" 821: yield( {:type => "ParseError", 822: :data => "contextmenu-must-point-to-menu"}) 823: end 824: break 825: end 826: end 827: end 828: end 829: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 452 452: def parse_token_list(value) 453: valueList = [] 454: currentValue = '' 455: (value + ' ').each_byte do |b| 456: c = [b].pack('c*') 457: if HTML5::SPACE_CHARACTERS.include?(c) 458: if currentValue.length > 0 459: valueList << currentValue 460: currentValue = '' 461: end 462: else 463: currentValue += c 464: end 465: end 466: if currentValue.length > 0 467: valueList << currentValue 468: end 469: valueList 470: end
Alias for check_lang_code
Alias for check_media_query
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 769 769: def validate_attribute_value_a_ping(token, tag_name, attr_name, attr_value) 770: value_list = parse_token_list(attr_value) 771: for current_value in value_list 772: checkIRI(token, tag_name, attr_name, attr_value) do |t| 773: yield t 774: end 775: end 776: end
Alias for check_link_relation
Alias for check_browsing_context
Alias for check_browsing_context
Alias for check_iri
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 675 675: def validate_attribute_value_class(token, tag_name, attr_name, attr_value) 676: check_token_list(tag_name, attr_name, attr_value) do |t| 677: yield t 678: yield( {:type => "ParseError", 679: :data => "invalid-attribute-value", 680: :datavars => {"tagName" => tag_name, 681: "attributeName" => attr_name}}) 682: end 683: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 685 685: def validate_attribute_value_contenteditable(token, tag_name, attr_name, attr_value) 686: check_enumerated_value(token, tag_name, attr_name, attr_value, ['true', 'false', '']) do |t| 687: yield t 688: end 689: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 706 706: def validate_attribute_value_contextmenu(token, tag_name, attr_name, attr_value) 707: check_id(token, tag_name, attr_name, attr_value) do |t| 708: yield t 709: end 710: @things_that_point_to_an_id << token 711: end
Alias for check_date_time
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 691 691: def validate_attribute_value_dir(token, tag_name, attr_name, attr_value) 692: check_enumerated_value(token, tag_name, attr_name, attr_value, ['ltr', 'rtl']) do |t| 693: yield t 694: end 695: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 697 697: def validate_attribute_value_draggable(token, tag_name, attr_name, attr_value) 698: check_enumerated_value(token, tag_name, attr_name, attr_value, ['true', 'false']) do |t| 699: yield t 700: end 701: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 742 742: def validate_attribute_value_html_xmlns(token, tag_name, attr_name, attr_value) 743: if attr_value != "http://www.w3.org/1999/xhtml" 744: yield( {:type => "ParseError", 745: :data => "invalid-root-namespace", 746: :datavars => {"tagName" => tag_name, 747: "attributeName" => attr_name}}) 748: end 749: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 713 713: def validate_attribute_value_id(token, tag_name, attr_name, attr_value) 714: # This method has side effects. It adds 'token' to the list of 715: # things that define an ID (@things_that_define_an_id) so that we can 716: # later check 1) whether an ID is duplicated, and 2) whether all the 717: # things that point to something else by ID (like <label for> or 718: # <span contextmenu>) point to an ID that actually exists somewhere. 719: check_id(token, tag_name, attr_name, attr_value) do |t| 720: yield t 721: end 722: return if not attr_value 723: if @ids_we_have_known_and_loved.include?(attr_value) 724: yield( {:type => "ParseError", 725: :data => "duplicate-id", 726: :datavars => {"tagName" => tag_name}}) 727: end 728: @ids_we_have_known_and_loved << attr_value 729: @things_that_define_an_id << token 730: end
Alias for check_date_time
Alias for check_lang_code
Alias for check_media_query
Alias for check_link_relation
Alias for check_mime_type
Alias for check_floating_point_number
Alias for check_floating_point_number
Alias for check_floating_point_number
Alias for check_floating_point_number
Alias for check_floating_point_number
Alias for check_floating_point_number
Alias for check_floating_point_number
Alias for check_floating_point_number
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 734 734: def validate_attribute_value_ref(token, tag_name, attr_name, attr_value) 735: # XXX 736: end
Alias for check_media_query
Alias for check_boolean
Alias for check_mime_type
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 738 738: def validate_attribute_value_template(token, tag_name, attr_name, attr_value) 739: # XXX 740: end
Alias for check_date_time
Start tag validation
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 298 298: def validate_start_tag(token) 299: check_unknown_start_tag(token){|t| yield t} 300: check_start_tag_required_attributes(token) do |t| 301: yield t 302: end 303: check_start_tag_unknown_attributes(token) do |t| 304: yield t 305: end 306: check_attribute_values(token) do |t| 307: yield t 308: end 309: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 311 311: def validate_start_tag_embed(token) 312: check_start_tag_required_attributes(token) do |t| 313: yield t 314: end 315: check_attribute_values(token) do |t| 316: yield t 317: end 318: # spec says "any attributes w/o namespace" 319: # so don't call check_start_tag_unknown_attributes 320: end
# File lib/feed_tools/vendor/html5/lib/html5/filters/validator.rb, line 322 322: def validate_start_tag_input(token) 323: check_attribute_values(token) do |t| 324: yield t 325: end 326: attr_dict = Hash[*token[:data].collect{|(name, value)| [name.downcase, value]}.flatten] 327: input_type = attr_dict.fetch('type', "text") 328: if !@@input_type_allowed_attribute_map.keys().include?(input_type) 329: yield({:type => "ParseError", 330: :data => "unknown-input-type", 331: :datavars => {:attrValue => input_type}}) 332: end 333: allowed_attributes = @@input_type_allowed_attribute_map.fetch(input_type, []) 334: attr_dict.each do |attr_name, attr_value| 335: if !@@allowed_attribute_map['input'].include?(attr_name) 336: yield({:type => "ParseError", 337: :data => "unknown-attribute", 338: :datavars => {"tagName" => "input", 339: "attributeName" => attr_name}}) 340: elsif !allowed_attributes.include?(attr_name) 341: yield({:type => "ParseError", 342: :data => "attribute-not-allowed-on-this-input-type", 343: :datavars => {"attributeName" => attr_name, 344: "inputType" => input_type}}) 345: end 346: if @@input_type_deprecated_attribute_map.fetch(input_type, []).include?(attr_name) 347: yield({:type => "ParseError", 348: :data => "deprecated-attribute", 349: :datavars => {"attributeName" => attr_name, 350: "inputType" => input_type}}) 351: end 352: end 353: end