meteor 0.9.30 → 0.9.32
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.
- checksums.yaml +4 -4
- data/ChangeLog +8 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +34 -3
- data/demo/html.rb +32 -38
- data/demo/html4.rb +27 -33
- data/demo/xhtml.rb +29 -35
- data/demo/xhtml4.rb +27 -33
- data/demo/xml.rb +20 -20
- data/lib/meteor/attribute.rb +1 -4
- data/lib/meteor/attribute_map.rb +21 -22
- data/lib/meteor/core/kernel.rb +604 -727
- data/lib/meteor/core/util/file_reader.rb +37 -0
- data/lib/meteor/core/util/pattern_cache.rb +7 -7
- data/lib/meteor/element.rb +48 -67
- data/lib/meteor/elements.rb +6 -6
- data/lib/meteor/exception/no_such_element_exception.rb +15 -15
- data/lib/meteor/ml/html/parser_impl.rb +69 -71
- data/lib/meteor/ml/html4/parser_impl.rb +129 -144
- data/lib/meteor/ml/xhtml/parser_impl.rb +44 -46
- data/lib/meteor/ml/xhtml4/parser_impl.rb +85 -87
- data/lib/meteor/ml/xml/parser_impl.rb +29 -29
- data/lib/meteor/parsers.rb +92 -100
- data/lib/meteor/root_element.rb +5 -8
- data/lib/meteor.rb +62 -61
- data/meteor.gemspec +14 -13
- data/test/meteor_test.rb +4 -2
- data/test/test_helper.rb +3 -2
- metadata +4 -4
- data/Rakefile +0 -144
|
@@ -8,19 +8,19 @@ module Meteor
|
|
|
8
8
|
# XHTML parser (XHTMLパーサ)
|
|
9
9
|
#
|
|
10
10
|
class ParserImpl < Meteor::Ml::Xhtml4::ParserImpl
|
|
11
|
-
#[Array] boolean attributes (論理値で指定する属性)
|
|
12
|
-
ATTR_BOOL = [
|
|
11
|
+
# [Array] boolean attributes (論理値で指定する属性)
|
|
12
|
+
ATTR_BOOL = %w[disabled readonly checked selected multiple required].freeze
|
|
13
13
|
|
|
14
|
-
#[Array] elements with the disabled attribute (disabled属性のある要素)
|
|
15
|
-
DISABLE_ELEMENT = [
|
|
14
|
+
# [Array] elements with the disabled attribute (disabled属性のある要素)
|
|
15
|
+
DISABLE_ELEMENT = %w[input textarea select optgroup fieldset].freeze
|
|
16
16
|
|
|
17
|
-
#[Array] elements with a readonly attribute (required属性のある要素)
|
|
18
|
-
REQUIRE_ELEMENT = [
|
|
17
|
+
# [Array] elements with a readonly attribute (required属性のある要素)
|
|
18
|
+
REQUIRE_ELEMENT = %w[input textarea].freeze
|
|
19
19
|
|
|
20
|
-
REQUIRED_M =
|
|
21
|
-
REQUIRED_M1 =
|
|
22
|
-
REQUIRED_R =
|
|
23
|
-
REQUIRED_U =
|
|
20
|
+
REQUIRED_M = '\\srequired="[^"]*"\\s|\\srequired="[^"]*"$'
|
|
21
|
+
REQUIRED_M1 = '\\srequired="([^"]*)"\\s|\\srequired="([^"]*)"$'
|
|
22
|
+
REQUIRED_R = 'required="[^"]*"'
|
|
23
|
+
REQUIRED_U = 'required="required"'
|
|
24
24
|
|
|
25
25
|
@@pattern_required_m = Regexp.new(REQUIRED_M)
|
|
26
26
|
@@pattern_required_m1 = Regexp.new(REQUIRED_M1)
|
|
@@ -38,9 +38,9 @@ module Meteor
|
|
|
38
38
|
@doc_type = Parser::XHTML
|
|
39
39
|
case args.length
|
|
40
40
|
when ZERO
|
|
41
|
-
#
|
|
41
|
+
# initialize_zero
|
|
42
42
|
when ONE
|
|
43
|
-
|
|
43
|
+
initialize_one(args[0])
|
|
44
44
|
else
|
|
45
45
|
raise ArgumentError
|
|
46
46
|
end
|
|
@@ -49,16 +49,16 @@ module Meteor
|
|
|
49
49
|
#
|
|
50
50
|
# initializer (イニシャライザ)
|
|
51
51
|
#
|
|
52
|
-
# def
|
|
52
|
+
# def initialize_zero
|
|
53
53
|
# end
|
|
54
54
|
#
|
|
55
|
-
# private :
|
|
55
|
+
# private :initialize_zero
|
|
56
56
|
|
|
57
57
|
#
|
|
58
58
|
# initializer (イニシャライザ)
|
|
59
59
|
# @param [Meteor::Parser] ps parser (パーサ)
|
|
60
60
|
#
|
|
61
|
-
def
|
|
61
|
+
def initialize_one(ps)
|
|
62
62
|
@root.document = String.new(ps.document)
|
|
63
63
|
self.document_hook = String.new(ps.document_hook)
|
|
64
64
|
@root.content_type = String.new(ps.root_element.content_type)
|
|
@@ -66,7 +66,7 @@ module Meteor
|
|
|
66
66
|
@root.newline = ps.root_element.newline
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
private :
|
|
69
|
+
private :initialize_one
|
|
70
70
|
|
|
71
71
|
#
|
|
72
72
|
# analyze document , set content type (ドキュメントをパースし、コンテントタイプをセットする)
|
|
@@ -74,42 +74,39 @@ module Meteor
|
|
|
74
74
|
def analyze_content_type
|
|
75
75
|
@error_check = false
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
element_three('meta', 'charset', '[a-zA-Z-]+', false)
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
element_3("meta", "charset", "[a-zA-Z-]+", false)
|
|
81
|
-
end
|
|
79
|
+
element_three('meta', 'charset', '[a-zA-Z-]+', false) unless @elm_
|
|
82
80
|
|
|
83
81
|
@error_check = true
|
|
84
82
|
|
|
85
83
|
if @elm_
|
|
86
|
-
@root.charset = @elm_.attr(
|
|
87
|
-
|
|
88
|
-
@root.charset = "utf-8"
|
|
89
|
-
end
|
|
84
|
+
@root.charset = @elm_.attr('charset')
|
|
85
|
+
@root.charset = 'utf-8' unless @root.charset
|
|
90
86
|
else
|
|
91
|
-
@root.charset =
|
|
87
|
+
@root.charset = 'utf-8'
|
|
92
88
|
end
|
|
93
89
|
|
|
94
|
-
@root.content_type =
|
|
90
|
+
@root.content_type = 'text/html'
|
|
95
91
|
end
|
|
96
92
|
|
|
97
93
|
private :analyze_content_type
|
|
98
94
|
|
|
99
95
|
def edit_attrs_(elm, attr_name, attr_value)
|
|
100
|
-
if is_match(
|
|
101
|
-
|
|
102
|
-
elsif is_match(
|
|
103
|
-
|
|
104
|
-
elsif is_match(
|
|
105
|
-
|
|
106
|
-
elsif is_match(
|
|
107
|
-
|
|
108
|
-
elsif is_match(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
96
|
+
if is_match('selected', attr_name) && is_match('option', elm.name)
|
|
97
|
+
edit_attrs_five(elm, attr_value, @@pattern_selected_m, @@pattern_selected_r, SELECTED_U)
|
|
98
|
+
elsif is_match('multiple', attr_name) && is_match('select', elm.name)
|
|
99
|
+
edit_attrs_five(elm, attr_value, @@pattern_multiple_m, @@pattern_multiple_r, MULTIPLE_U)
|
|
100
|
+
elsif is_match('disabled', attr_name) && is_match(DISABLE_ELEMENT, elm.name)
|
|
101
|
+
edit_attrs_five(elm, attr_value, @@pattern_disabled_m, @@pattern_disabled_r, DISABLED_U)
|
|
102
|
+
elsif is_match('checked', attr_name) && is_match('input', elm.name) && is_match('radio', get_type(elm))
|
|
103
|
+
edit_attrs_five(elm, attr_value, @@pattern_checked_m, @@pattern_checked_r, CHECKED_U)
|
|
104
|
+
elsif is_match('readonly', attr_name) &&
|
|
105
|
+
(is_match('textarea',
|
|
106
|
+
elm.name) || (is_match('input', elm.name) && is_match(READONLY_TYPE, get_type(elm))))
|
|
107
|
+
edit_attrs_five(elm, attr_value, @@pattern_readonly_m, @@pattern_readonly_r, READONLY_U)
|
|
108
|
+
elsif is_match('required', attr_name) && is_match(REQUIRE_ELEMENT, elm.name)
|
|
109
|
+
edit_attrs_five(elm, attr_value, @@pattern_required_m, @@pattern_required_r, REQUIRED_U)
|
|
113
110
|
else
|
|
114
111
|
super(elm, attr_name, attr_value)
|
|
115
112
|
end
|
|
@@ -118,18 +115,19 @@ module Meteor
|
|
|
118
115
|
private :edit_attrs_
|
|
119
116
|
|
|
120
117
|
def get_attr_value_(elm, attr_name)
|
|
121
|
-
if is_match(
|
|
118
|
+
if is_match('selected', attr_name) && is_match('option', elm.name)
|
|
122
119
|
get_attr_value_r(elm, attr_name, @@pattern_selected_m1)
|
|
123
|
-
elsif is_match(
|
|
120
|
+
elsif is_match('multiple', attr_name) && is_match('select', elm.name)
|
|
124
121
|
get_attr_value_r(elm, attr_name, @@pattern_multiple_m1)
|
|
125
|
-
elsif is_match(
|
|
122
|
+
elsif is_match('disabled', attr_name) && is_match(DISABLE_ELEMENT, elm.name)
|
|
126
123
|
get_attr_value_r(elm, attr_name, @@pattern_disabled_m1)
|
|
127
|
-
elsif is_match(
|
|
124
|
+
elsif is_match('checked', attr_name) && is_match('input', elm.name) && is_match('radio', get_type(elm))
|
|
128
125
|
get_attr_value_r(elm, attr_name, @@pattern_checked_m1)
|
|
129
|
-
elsif is_match(
|
|
130
|
-
|
|
126
|
+
elsif is_match('readonly', attr_name) &&
|
|
127
|
+
(is_match('textarea',
|
|
128
|
+
elm.name) || (is_match('input', elm.name) && is_match(READONLY_TYPE, get_type(elm))))
|
|
131
129
|
get_attr_value_r(elm, attr_name, @@pattern_readonly_m1)
|
|
132
|
-
elsif is_match(
|
|
130
|
+
elsif is_match('required', attr_name) && is_match(REQUIRE_ELEMENT, elm.name)
|
|
133
131
|
get_attr_value_r(elm, attr_name, @@pattern_required_m1)
|
|
134
132
|
else
|
|
135
133
|
super(elm, attr_name)
|
|
@@ -9,44 +9,44 @@ module Meteor
|
|
|
9
9
|
#
|
|
10
10
|
class ParserImpl < Meteor::Core::Kernel
|
|
11
11
|
# KAIGYO_CODE = "\r?\n|\r"
|
|
12
|
-
KAIGYO_CODE = ["\r\n", "\n", "\r"]
|
|
13
|
-
BR =
|
|
14
|
-
BR_RE =
|
|
12
|
+
KAIGYO_CODE = ["\r\n", "\n", "\r"].freeze
|
|
13
|
+
BR = '<br/>'
|
|
14
|
+
BR_RE = '<br\\/>'
|
|
15
15
|
|
|
16
16
|
# @@match_tag_2 = "textarea|option|pre"
|
|
17
|
-
#[Array] elements where line breaks do not need to be converted to <br> (改行を<br/>に変換する必要のない要素)
|
|
18
|
-
@@match_tag_2 = [
|
|
17
|
+
# [Array] elements where line breaks do not need to be converted to <br> (改行を<br/>に変換する必要のない要素)
|
|
18
|
+
@@match_tag_2 = %w[textarea option pre]
|
|
19
19
|
|
|
20
|
-
#[Array] boolean attributes (論理値で指定する属性)
|
|
21
|
-
@@attr_bool = [
|
|
20
|
+
# [Array] boolean attributes (論理値で指定する属性)
|
|
21
|
+
@@attr_bool = %w[disabled readonly checked selected multiple]
|
|
22
22
|
|
|
23
23
|
# DISABLE_ELEMENT = "input|textarea|select|optgroup"
|
|
24
|
-
#[Array] element with disablled attribute (disabled属性のある要素)
|
|
25
|
-
DISABLE_ELEMENT = [
|
|
24
|
+
# [Array] element with disablled attribute (disabled属性のある要素)
|
|
25
|
+
DISABLE_ELEMENT = %w[input textarea select optgroup].freeze
|
|
26
26
|
# READONLY_TYPE = "text|password"
|
|
27
|
-
#[Array] the type of an input element with a readonly attribute (readonly属性のあるinput要素のタイプ)
|
|
28
|
-
READONLY_TYPE = [
|
|
29
|
-
|
|
30
|
-
SELECTED_M =
|
|
31
|
-
SELECTED_M1 =
|
|
32
|
-
SELECTED_R =
|
|
33
|
-
SELECTED_U =
|
|
34
|
-
CHECKED_M =
|
|
35
|
-
CHECKED_M1 =
|
|
36
|
-
CHECKED_R =
|
|
37
|
-
CHECKED_U =
|
|
38
|
-
DISABLED_M =
|
|
39
|
-
DISABLED_M1 =
|
|
40
|
-
DISABLED_R =
|
|
41
|
-
DISABLED_U =
|
|
42
|
-
READONLY_M =
|
|
43
|
-
READONLY_M1 =
|
|
44
|
-
READONLY_R =
|
|
45
|
-
READONLY_U =
|
|
46
|
-
MULTIPLE_M =
|
|
47
|
-
MULTIPLE_M1 =
|
|
48
|
-
MULTIPLE_R =
|
|
49
|
-
MULTIPLE_U =
|
|
27
|
+
# [Array] the type of an input element with a readonly attribute (readonly属性のあるinput要素のタイプ)
|
|
28
|
+
READONLY_TYPE = %w[text password].freeze
|
|
29
|
+
|
|
30
|
+
SELECTED_M = '\\sselected="[^"]*"\\s|\\sselected="[^"]*"$'
|
|
31
|
+
SELECTED_M1 = '\\sselected="([^"]*)"\\s|\\sselected="([^"]*)"$'
|
|
32
|
+
SELECTED_R = 'selected="[^"]*"'
|
|
33
|
+
SELECTED_U = 'selected="selected"'
|
|
34
|
+
CHECKED_M = '\\schecked="[^"]*"\\s|\\schecked="[^"]*"$'
|
|
35
|
+
CHECKED_M1 = '\\schecked="([^"]*)"\\s|\\schecked="([^"]*)"$'
|
|
36
|
+
CHECKED_R = 'checked="[^"]*"'
|
|
37
|
+
CHECKED_U = 'checked="checked"'
|
|
38
|
+
DISABLED_M = '\\sdisabled="[^"]*"\\s|\\sdisabled="[^"]*"$'
|
|
39
|
+
DISABLED_M1 = '\\sdisabled="([^"]*)"\\s|\\sdisabled="([^"]*)"$'
|
|
40
|
+
DISABLED_R = 'disabled="[^"]*"'
|
|
41
|
+
DISABLED_U = 'disabled="disabled"'
|
|
42
|
+
READONLY_M = '\\sreadonly="[^"]*"\\s|\\sreadonly="[^"]*"$'
|
|
43
|
+
READONLY_M1 = '\\sreadonly="([^"]*)"\\s|\\sreadonly="([^"]*)"$'
|
|
44
|
+
READONLY_R = 'readonly="[^"]*"'
|
|
45
|
+
READONLY_U = 'readonly="readonly"'
|
|
46
|
+
MULTIPLE_M = '\\smultiple="[^"]*"\\s|\\smultiple="[^"]*"$'
|
|
47
|
+
MULTIPLE_M1 = '\\smultiple="([^"]*)"\\s|\\smultiple="([^"]*)"$'
|
|
48
|
+
MULTIPLE_R = 'multiple="[^"]*"'
|
|
49
|
+
MULTIPLE_U = 'multiple="multiple"'
|
|
50
50
|
|
|
51
51
|
@@pattern_selected_m = Regexp.new(SELECTED_M)
|
|
52
52
|
@@pattern_selected_m1 = Regexp.new(SELECTED_M1)
|
|
@@ -78,9 +78,9 @@ module Meteor
|
|
|
78
78
|
@doc_type = Parser::XHTML4
|
|
79
79
|
case args.length
|
|
80
80
|
when ZERO
|
|
81
|
-
#
|
|
81
|
+
# initialize_zero
|
|
82
82
|
when ONE
|
|
83
|
-
|
|
83
|
+
initialize_one(args[0])
|
|
84
84
|
else
|
|
85
85
|
raise ArgumentError
|
|
86
86
|
end
|
|
@@ -89,16 +89,16 @@ module Meteor
|
|
|
89
89
|
#
|
|
90
90
|
# initializer (イニシャライザ)
|
|
91
91
|
#
|
|
92
|
-
# def
|
|
92
|
+
# def initialize_zero
|
|
93
93
|
# end
|
|
94
94
|
#
|
|
95
|
-
# private :
|
|
95
|
+
# private :initialize_zero
|
|
96
96
|
|
|
97
97
|
#
|
|
98
98
|
# initializer (イニシャライザ)
|
|
99
99
|
# @param [Meteor::Parser] ps parser (パーサ)
|
|
100
100
|
#
|
|
101
|
-
def
|
|
101
|
+
def initialize_one(ps)
|
|
102
102
|
@root.document = String.new(ps.document)
|
|
103
103
|
self.document_hook = String.new(ps.document_hook)
|
|
104
104
|
@root.content_type = String.new(ps.root_element.content_type)
|
|
@@ -106,7 +106,7 @@ module Meteor
|
|
|
106
106
|
@root.newline = ps.root_element.newline
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
-
private :
|
|
109
|
+
private :initialize_one
|
|
110
110
|
|
|
111
111
|
#
|
|
112
112
|
# parse document (ドキュメントを解析する)
|
|
@@ -115,6 +115,8 @@ module Meteor
|
|
|
115
115
|
analyze_ml
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
+
protected :parse
|
|
119
|
+
|
|
118
120
|
#
|
|
119
121
|
# analyze document (ドキュメントをパースする)
|
|
120
122
|
#
|
|
@@ -140,21 +142,19 @@ module Meteor
|
|
|
140
142
|
def analyze_content_type
|
|
141
143
|
@error_check = false
|
|
142
144
|
|
|
143
|
-
|
|
145
|
+
element_three('meta', 'http-equiv', 'Content-Type')
|
|
144
146
|
|
|
145
|
-
|
|
146
|
-
element_3("meta", "http-equiv", "Content-Type")
|
|
147
|
-
end
|
|
147
|
+
element_three('meta', 'http-equiv', 'Content-Type') unless @elm_
|
|
148
148
|
|
|
149
149
|
@error_check = true
|
|
150
150
|
|
|
151
151
|
if @elm_
|
|
152
|
-
content = @elm_.attr(
|
|
153
|
-
content_arr = content&.split(
|
|
154
|
-
@root.content_type = content_arr&.at(0) ||
|
|
155
|
-
@root.charset = content_arr&.at(1)&.split(
|
|
152
|
+
content = @elm_.attr('content')
|
|
153
|
+
content_arr = content&.split(';')
|
|
154
|
+
@root.content_type = content_arr&.at(0) || ''
|
|
155
|
+
@root.charset = content_arr&.at(1)&.split('=')&.at(1) || ''
|
|
156
156
|
else
|
|
157
|
-
@root.content_type =
|
|
157
|
+
@root.content_type = ''
|
|
158
158
|
end
|
|
159
159
|
end
|
|
160
160
|
|
|
@@ -164,27 +164,26 @@ module Meteor
|
|
|
164
164
|
# analyze document , set newline (ドキュメントをパースし、改行コードをセットする)
|
|
165
165
|
#
|
|
166
166
|
def analyze_newline
|
|
167
|
-
|
|
168
|
-
if @root.document.include?(a)
|
|
169
|
-
@root.newline = a
|
|
170
|
-
end
|
|
167
|
+
KAIGYO_CODE.each do |a|
|
|
168
|
+
@root.newline = a if @root.document.include?(a)
|
|
171
169
|
end
|
|
172
170
|
end
|
|
173
171
|
|
|
174
172
|
private :analyze_newline
|
|
175
173
|
|
|
176
174
|
def edit_attrs_(elm, attr_name, attr_value)
|
|
177
|
-
if is_match(
|
|
178
|
-
|
|
179
|
-
elsif is_match(
|
|
180
|
-
|
|
181
|
-
elsif is_match(
|
|
182
|
-
|
|
183
|
-
elsif is_match(
|
|
184
|
-
|
|
185
|
-
elsif is_match(
|
|
186
|
-
|
|
187
|
-
|
|
175
|
+
if is_match('selected', attr_name) && is_match('option', elm.name)
|
|
176
|
+
edit_attrs_five(elm, attr_value, @@pattern_selected_m, @@pattern_selected_r, SELECTED_U)
|
|
177
|
+
elsif is_match('multiple', attr_name) && is_match('select', elm.name)
|
|
178
|
+
edit_attrs_five(elm, attr_value, @@pattern_multiple_m, @@pattern_multiple_r, MULTIPLE_U)
|
|
179
|
+
elsif is_match('disabled', attr_name) && is_match(DISABLE_ELEMENT, elm.name)
|
|
180
|
+
edit_attrs_five(elm, attr_value, @@pattern_disabled_m, @@pattern_disabled_r, DISABLED_U)
|
|
181
|
+
elsif is_match('checked', attr_name) && is_match('input', elm.name) && is_match('radio', get_type(elm))
|
|
182
|
+
edit_attrs_five(elm, attr_value, @@pattern_checked_m, @@pattern_checked_r, CHECKED_U)
|
|
183
|
+
elsif is_match('readonly', attr_name) &&
|
|
184
|
+
(is_match('textarea',
|
|
185
|
+
elm.name) || (is_match('input', elm.name) && is_match(READONLY_TYPE, get_type(elm))))
|
|
186
|
+
edit_attrs_five(elm, attr_value, @@pattern_readonly_m, @@pattern_readonly_r, READONLY_U)
|
|
188
187
|
else
|
|
189
188
|
super(elm, attr_name, attr_value)
|
|
190
189
|
end
|
|
@@ -192,44 +191,45 @@ module Meteor
|
|
|
192
191
|
|
|
193
192
|
private :edit_attrs_
|
|
194
193
|
|
|
195
|
-
def
|
|
194
|
+
def edit_attrs_five(elm, attr_value, match_p, replace_regex, replace_update)
|
|
196
195
|
# attr_value = escape(attr_value)
|
|
197
196
|
|
|
198
|
-
if true.equal?(attr_value) || is_match(
|
|
197
|
+
if true.equal?(attr_value) || is_match('true', attr_value)
|
|
199
198
|
@res = match_p.match(elm.attributes)
|
|
200
199
|
|
|
201
200
|
if !@res
|
|
202
201
|
# add an attribute to attributes (属性文字列の最後に新規の属性を追加する)
|
|
203
|
-
if elm.attributes !=
|
|
204
|
-
elm.attributes = String.new(
|
|
202
|
+
if elm.attributes != ''
|
|
203
|
+
elm.attributes = String.new('') << ' ' << elm.attributes.strip
|
|
205
204
|
# else
|
|
206
205
|
end
|
|
207
206
|
|
|
208
|
-
elm.attributes <<
|
|
207
|
+
elm.attributes << ' ' << replace_update
|
|
209
208
|
else
|
|
210
209
|
# replace attribute (属性の置換)
|
|
211
210
|
elm.attributes.gsub!(replace_regex, replace_update)
|
|
212
211
|
end
|
|
213
|
-
elsif false.equal?(attr_value) || is_match(
|
|
212
|
+
elsif false.equal?(attr_value) || is_match('false', attr_value)
|
|
214
213
|
# delete if attribute_name attrubute exeists (attr_name属性が存在するなら削除)
|
|
215
214
|
# replace attribute (属性の置換)
|
|
216
|
-
elm.attributes.gsub!(replace_regex,
|
|
215
|
+
elm.attributes.gsub!(replace_regex, '')
|
|
217
216
|
end
|
|
218
217
|
end
|
|
219
218
|
|
|
220
|
-
private :
|
|
219
|
+
private :edit_attrs_five
|
|
221
220
|
|
|
222
221
|
def get_attr_value_(elm, attr_name)
|
|
223
|
-
if is_match(
|
|
222
|
+
if is_match('selected', attr_name) && is_match('option', elm.name)
|
|
224
223
|
get_attr_value_r(elm, attr_name, @@pattern_selected_m1)
|
|
225
|
-
elsif is_match(
|
|
224
|
+
elsif is_match('multiple', attr_name) && is_match('select', elm.name)
|
|
226
225
|
get_attr_value_r(elm, attr_name, @@pattern_multiple_m1)
|
|
227
|
-
elsif is_match(
|
|
226
|
+
elsif is_match('diabled', attr_name) && is_match(DISABLE_ELEMENT, elm.name)
|
|
228
227
|
get_attr_value_r(elm, attr_name, @@pattern_disabled_m1)
|
|
229
|
-
elsif is_match(
|
|
228
|
+
elsif is_match('checked', attr_name) && is_match('input', elm.name) && is_match('radio', get_type(elm))
|
|
230
229
|
get_attr_value_r(elm, attr_name, @@pattern_checked_m1)
|
|
231
|
-
elsif is_match(
|
|
232
|
-
|
|
230
|
+
elsif is_match('readonly', attr_name) &&
|
|
231
|
+
(is_match('textarea',
|
|
232
|
+
elm.name) || (is_match('input', elm.name) && is_match(READONLY_TYPE, get_type(elm))))
|
|
233
233
|
get_attr_value_r(elm, attr_name, @@pattern_readonly_m1)
|
|
234
234
|
else
|
|
235
235
|
super(elm, attr_name)
|
|
@@ -239,11 +239,9 @@ module Meteor
|
|
|
239
239
|
private :get_attr_value_
|
|
240
240
|
|
|
241
241
|
def get_type(elm)
|
|
242
|
-
|
|
243
|
-
elm.type_value = get_attr_value(elm,
|
|
244
|
-
|
|
245
|
-
elm.type_value = get_attr_value(elm, "TYPE")
|
|
246
|
-
end
|
|
242
|
+
unless elm.type_value
|
|
243
|
+
elm.type_value = get_attr_value(elm, 'type')
|
|
244
|
+
elm.type_value = get_attr_value(elm, 'TYPE') unless elm.type_value
|
|
247
245
|
end
|
|
248
246
|
|
|
249
247
|
elm.type_value
|
|
@@ -257,31 +255,31 @@ module Meteor
|
|
|
257
255
|
if @res
|
|
258
256
|
if @res[1]
|
|
259
257
|
if attr_name == @res[1]
|
|
260
|
-
|
|
258
|
+
'true'
|
|
261
259
|
else
|
|
262
260
|
@res[1]
|
|
263
261
|
end
|
|
264
262
|
elsif @res[2]
|
|
265
263
|
if attr_name == @res[2]
|
|
266
|
-
|
|
264
|
+
'true'
|
|
267
265
|
else
|
|
268
266
|
@res[2]
|
|
269
267
|
end
|
|
270
268
|
elsif @res[3]
|
|
271
269
|
if attr_name == @res[3]
|
|
272
|
-
|
|
270
|
+
'true'
|
|
273
271
|
else
|
|
274
272
|
@res[3]
|
|
275
273
|
end
|
|
276
274
|
elsif @res[4]
|
|
277
275
|
if attr_name == @res[4]
|
|
278
|
-
|
|
276
|
+
'true'
|
|
279
277
|
else
|
|
280
278
|
@res[4]
|
|
281
279
|
end
|
|
282
280
|
end
|
|
283
281
|
else
|
|
284
|
-
|
|
282
|
+
'false'
|
|
285
283
|
end
|
|
286
284
|
end
|
|
287
285
|
|
|
@@ -297,7 +295,7 @@ module Meteor
|
|
|
297
295
|
|
|
298
296
|
elm.attributes.scan(@@pattern_get_attrs_map) do |a, b|
|
|
299
297
|
if is_match(@@attr_bool, a) && a == b
|
|
300
|
-
attrs.store(a,
|
|
298
|
+
attrs.store(a, 'true')
|
|
301
299
|
else
|
|
302
300
|
attrs.store(a, unescape(b))
|
|
303
301
|
end
|
|
@@ -9,20 +9,20 @@ module Meteor
|
|
|
9
9
|
#
|
|
10
10
|
class ParserImpl < Meteor::Core::Kernel
|
|
11
11
|
# KAIGYO_CODE = "\r?\n|\r"
|
|
12
|
-
KAIGYO_CODE = ["\r\n", "\n", "\r"]
|
|
12
|
+
KAIGYO_CODE = ["\r\n", "\n", "\r"].freeze
|
|
13
13
|
|
|
14
14
|
TABLE_FOR_ESCAPE_ = {
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
"'" =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
15
|
+
'&' => '&',
|
|
16
|
+
'"' => '"',
|
|
17
|
+
"'" => ''',
|
|
18
|
+
'<' => '<',
|
|
19
|
+
'>' => '>'
|
|
20
|
+
}.freeze
|
|
21
21
|
|
|
22
22
|
PATTERN_ESCAPE = "[&\\\"'<>]"
|
|
23
23
|
@@pattern_escape = Regexp.new(PATTERN_ESCAPE)
|
|
24
24
|
|
|
25
|
-
PATTERN_UNESCAPE =
|
|
25
|
+
PATTERN_UNESCAPE = '&(amp|quot|apos|gt|lt);'
|
|
26
26
|
@@pattern_unescape = Regexp.new(PATTERN_UNESCAPE)
|
|
27
27
|
|
|
28
28
|
#
|
|
@@ -36,9 +36,9 @@ module Meteor
|
|
|
36
36
|
@doc_type = Parser::XML
|
|
37
37
|
case args.length
|
|
38
38
|
when ZERO
|
|
39
|
-
#
|
|
39
|
+
# initialize_zero
|
|
40
40
|
when ONE
|
|
41
|
-
|
|
41
|
+
initialize_one(args[0])
|
|
42
42
|
else
|
|
43
43
|
raise ArgumentError
|
|
44
44
|
end
|
|
@@ -47,23 +47,23 @@ module Meteor
|
|
|
47
47
|
#
|
|
48
48
|
# initializer (イニシャライザ)
|
|
49
49
|
#
|
|
50
|
-
# def
|
|
50
|
+
# def initialize_zero
|
|
51
51
|
# end
|
|
52
52
|
#
|
|
53
|
-
# private :
|
|
53
|
+
# private :initialize_zero
|
|
54
54
|
|
|
55
55
|
#
|
|
56
56
|
# initializer (イニシャライザ)
|
|
57
57
|
# @param [Meteor::Parser] ps parser (パーサ)
|
|
58
58
|
#
|
|
59
|
-
def
|
|
59
|
+
def initialize_one(ps)
|
|
60
60
|
@root.document = String.new(ps.document)
|
|
61
61
|
ps.document_hook = String.new(ps.document_hook)
|
|
62
62
|
@root.content_type = String.new(ps.root_element.content_type)
|
|
63
63
|
@root.newline = ps.root_element.newline
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
private :
|
|
66
|
+
private :initialize_one
|
|
67
67
|
|
|
68
68
|
#
|
|
69
69
|
# parse document (ドキュメントを解析する)
|
|
@@ -72,6 +72,8 @@ module Meteor
|
|
|
72
72
|
analyze_ml
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
protected :parse
|
|
76
|
+
|
|
75
77
|
#
|
|
76
78
|
# analyze document (ドキュメントをパースする)
|
|
77
79
|
#
|
|
@@ -96,7 +98,7 @@ module Meteor
|
|
|
96
98
|
# analuze document , set newline (ドキュメントをパースし、改行コードをセットする)
|
|
97
99
|
#
|
|
98
100
|
def analyze_newline
|
|
99
|
-
|
|
101
|
+
KAIGYO_CODE.each do |a|
|
|
100
102
|
if @root.document.include?(a)
|
|
101
103
|
@root.newline = a
|
|
102
104
|
# puts "kaigyo:" << @root.newline
|
|
@@ -110,16 +112,14 @@ module Meteor
|
|
|
110
112
|
# analyze document , set content type (ドキュメントをパースし、コンテントタイプをセットする)
|
|
111
113
|
#
|
|
112
114
|
def analyze_content_type
|
|
113
|
-
@root.content_type =
|
|
115
|
+
@root.content_type = 'text/xml'
|
|
114
116
|
end
|
|
115
117
|
|
|
116
118
|
private :analyze_content_type
|
|
117
119
|
|
|
118
120
|
def escape(content)
|
|
119
121
|
# replace special character (特殊文字の置換)
|
|
120
|
-
content
|
|
121
|
-
|
|
122
|
-
content
|
|
122
|
+
content.gsub(@@pattern_escape, TABLE_FOR_ESCAPE_)
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
private :escape
|
|
@@ -138,17 +138,17 @@ module Meteor
|
|
|
138
138
|
# 「'」<-「'」
|
|
139
139
|
# 「&」<-「&」
|
|
140
140
|
content.gsub(@@pattern_unescape) do
|
|
141
|
-
case
|
|
142
|
-
when
|
|
143
|
-
|
|
144
|
-
when
|
|
145
|
-
"
|
|
146
|
-
when
|
|
141
|
+
case ::Regexp.last_match(1)
|
|
142
|
+
when 'amp'
|
|
143
|
+
'&'
|
|
144
|
+
when 'quot'
|
|
145
|
+
'"'
|
|
146
|
+
when 'apos'
|
|
147
147
|
"'"
|
|
148
|
-
when
|
|
149
|
-
|
|
150
|
-
when
|
|
151
|
-
|
|
148
|
+
when 'gt'
|
|
149
|
+
'>'
|
|
150
|
+
when 'lt'
|
|
151
|
+
'<'
|
|
152
152
|
end
|
|
153
153
|
end
|
|
154
154
|
|