capybara 3.26.0 → 3.27.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +18 -0
  3. data/README.md +1 -2
  4. data/lib/capybara/minitest.rb +29 -29
  5. data/lib/capybara/node/element.rb +2 -1
  6. data/lib/capybara/node/matchers.rb +6 -6
  7. data/lib/capybara/node/simple.rb +2 -1
  8. data/lib/capybara/queries/ancestor_query.rb +5 -9
  9. data/lib/capybara/queries/selector_query.rb +2 -2
  10. data/lib/capybara/queries/sibling_query.rb +4 -10
  11. data/lib/capybara/registrations/servers.rb +4 -1
  12. data/lib/capybara/selector/regexp_disassembler.rb +7 -0
  13. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -1
  14. data/lib/capybara/selenium/atoms/src/isDisplayed.js +9 -9
  15. data/lib/capybara/selenium/driver.rb +2 -1
  16. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +9 -4
  17. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +8 -6
  18. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +9 -0
  19. data/lib/capybara/selenium/nodes/chrome_node.rb +41 -5
  20. data/lib/capybara/selenium/nodes/firefox_node.rb +16 -0
  21. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  22. data/lib/capybara/spec/session/node_spec.rb +40 -3
  23. data/lib/capybara/spec/views/with_html.erb +10 -0
  24. data/lib/capybara/version.rb +1 -1
  25. data/spec/basic_node_spec.rb +6 -6
  26. data/spec/capybara_spec.rb +28 -28
  27. data/spec/filter_set_spec.rb +5 -5
  28. data/spec/fixtures/selenium_driver_rspec_failure.rb +1 -1
  29. data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
  30. data/spec/rack_test_spec.rb +9 -9
  31. data/spec/regexp_dissassembler_spec.rb +12 -2
  32. data/spec/rspec/shared_spec_matchers.rb +2 -2
  33. data/spec/rspec_spec.rb +1 -1
  34. data/spec/selector_spec.rb +15 -15
  35. data/spec/selenium_spec_chrome.rb +38 -0
  36. data/spec/selenium_spec_firefox.rb +1 -1
  37. data/spec/server_spec.rb +18 -18
  38. data/spec/session_spec.rb +4 -4
  39. data/spec/shared_selenium_node.rb +36 -0
  40. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 799d14b5b1f64c06a58d962e7187f439332772f95d9d946d7452cf04d1710669
4
- data.tar.gz: 79d2dc83febaaae726776d509c01e591558a7a174c2e8b58733082981610c57c
3
+ metadata.gz: d2fb2005b8e78a2ee5cd0cf72bdfe2143988cce46abf19422f00bc78ac6336fa
4
+ data.tar.gz: 17f7b3eba5799d74ba90bddd6bacec90f1318e3c731097a4cb362f211272652b
5
5
  SHA512:
6
- metadata.gz: ccb7b53977549aaa7597577b74a5bde4ebcaee1fa9137b7aad1c7317f73b980cfb27552921386af12601febffc2326c481915d96ac6c56f87f594a9c726ea855
7
- data.tar.gz: 87c6490f0f8132750d30391aadb007ae9376d03d093c12f783ed32a3a373b33541c0ef66f7b0f7c8c069b982203542e92b33e294a80611b52dbc79e7d20021dc
6
+ metadata.gz: 28e92147279b5b2ee953853fd93071e143719ec099fb68187ea4fa666fbe3593606876968861c9104967e7b7bbd2033b2105ce9720bb00b4de94cd98c8473553
7
+ data.tar.gz: 25aee95fc26cc88c27e5229f73665a1cf6b2a8658ece2b8503809a520a45afe5622b28825206cff599ad7a2e749dbc168941dcc298995bc43fd61545b6a306a1
data/History.md CHANGED
@@ -1,3 +1,21 @@
1
+ # Version 3.27.0
2
+ Release date: 2019-07-28
3
+
4
+ ### Added
5
+
6
+ * Allow to use chromedriver/geckodriver native `is_element_displayed` endpoint via Selenium
7
+ driver `native_displayed` option for performance reasons. Disabled by default due to endpoints
8
+ currently not handling <details> element descendants visibility correctly.
9
+
10
+ ### Fixed
11
+
12
+ * Ignore negative lookahead/lookbehind regex when performing initial XPath text matching
13
+ * Reloading of elements found via `ancestor` and `sibling`
14
+ * Only default puma settings to `queue_requests: false` when using SSL
15
+ * Visibility of descendants of <details> elements is correctly determined when using rack_test
16
+ and the selenium driver with Capybara optimized atoms
17
+ * local/session storage clearance in Chrome when clearing only one of them - Issue #2233
18
+
1
19
  # Version 3.26.0
2
20
  Release date: 2019-07-15
3
21
 
data/README.md CHANGED
@@ -7,8 +7,7 @@
7
7
  [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
8
8
  [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=capybara&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=capybara&package-manager=bundler&version-scheme=semver)
9
9
 
10
- **Note** You are viewing the README for the 3.26.x version of Capybara.
11
-
10
+ **Note** You are viewing the README for the 3.27.x version of Capybara
12
11
 
13
12
  Capybara helps you test web applications by simulating how a real user would
14
13
  interact with your app. It is agnostic about the driver running your tests and
@@ -9,38 +9,38 @@ module Capybara
9
9
  ## Assert text exists
10
10
  #
11
11
  # @!method assert_text
12
- # see {Capybara::Node::Matchers#assert_text}
12
+ # @see Capybara::Node::Matchers#assert_text
13
13
 
14
14
  ## Assert text does not exist
15
15
  #
16
16
  # @!method assert_no_text
17
- # see {Capybara::Node::Matchers#assert_no_text}
17
+ # @see Capybara::Node::Matchers#assert_no_text
18
18
 
19
19
  ##
20
20
  # Assertion that page title does match
21
21
  #
22
22
  # @!method assert_title
23
- # see {Capybara::Node::DocumentMatchers#assert_title}
23
+ # @see Capybara::Node::DocumentMatchers#assert_title
24
24
 
25
25
  ##
26
26
  # Assertion that page title does not match
27
27
  #
28
28
  # @!method refute_title
29
29
  # @!method assert_no_title
30
- # see {Capybara::Node::DocumentMatchers#assert_no_title}
30
+ # @see Capybara::Node::DocumentMatchers#assert_no_title
31
31
 
32
32
  ##
33
33
  # Assertion that current path matches
34
34
  #
35
35
  # @!method assert_current_path
36
- # see {Capybara::SessionMatchers#assert_current_path}
36
+ # @see Capybara::SessionMatchers#assert_current_path
37
37
 
38
38
  ##
39
39
  # Assertion that current page does not match
40
40
  #
41
41
  # @!method refute_current_path
42
42
  # @!method assert_no_current_path
43
- # see {Capybara::SessionMatchers#assert_no_current_path}
43
+ # @see Capybara::SessionMatchers#assert_no_current_path
44
44
 
45
45
  %w[text no_text title no_title current_path no_current_path].each do |assertion_name|
46
46
  class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
@@ -64,37 +64,37 @@ module Capybara
64
64
  ## Assert selector exists on page
65
65
  #
66
66
  # @!method assert_selector
67
- # see {Capybara::Node::Matchers#assert_selector}
67
+ # @see Capybara::Node::Matchers#assert_selector
68
68
 
69
69
  ## Assert selector does not exist on page
70
70
  #
71
71
  # @!method assert_no_selector
72
- # see {Capybara::Node::Matchers#assert_no_selector}
72
+ # @see Capybara::Node::Matchers#assert_no_selector
73
73
 
74
74
  ## Assert element matches selector
75
75
  #
76
76
  # @!method assert_matches_selector
77
- # see {Capybara::Node::Matchers#assert_matches_selector}
77
+ # @see Capybara::Node::Matchers#assert_matches_selector
78
78
 
79
79
  ## Assert element does not match selector
80
80
  #
81
81
  # @!method assert_xpath
82
- # see {Capybara::Node::Matchers#assert_not_matches_selector}
82
+ # @see Capybara::Node::Matchers#assert_not_matches_selector
83
83
 
84
84
  ## Assert element has the provided CSS styles
85
85
  #
86
86
  # @!method assert_matches_style
87
- # see {Capybara::Node::Matchers#assert_matches_style}
87
+ # @see Capybara::Node::Matchers#assert_matches_style
88
88
 
89
89
  ## Assert element has a matching sibling
90
90
  #
91
91
  # @!method assert_sibling
92
- # see {Capybara::Node::Matchers#assert_sibling}
92
+ # @see Capybara::Node::Matchers#assert_sibling
93
93
 
94
94
  ## Assert element has a matching ancestor
95
95
  #
96
96
  # @!method assert_ancestor
97
- # see {Capybara::Node::Matchers#assert_ancestor}
97
+ # @see Capybara::Node::Matchers#assert_ancestor
98
98
 
99
99
  %w[selector no_selector matches_style
100
100
  all_of_selectors none_of_selectors any_of_selectors
@@ -163,72 +163,72 @@ module Capybara
163
163
  # Assertion that there is xpath
164
164
  #
165
165
  # @!method assert_xpath
166
- # see {Capybara::Node::Matchers#has_xpath?}
166
+ # @see Capybara::Node::Matchers#has_xpath?
167
167
 
168
168
  ##
169
169
  # Assertion that there is no xpath
170
170
  #
171
171
  # @!method refute_xpath
172
172
  # @!method assert_no_xpath
173
- # see {Capybara::Node::Matchers#has_no_xpath?}
173
+ # @see Capybara::Node::Matchers#has_no_xpath?
174
174
 
175
175
  ##
176
176
  # Assertion that there is css
177
177
  #
178
178
  # @!method assert_css
179
- # see {Capybara::Node::Matchers#has_css?}
179
+ # @see Capybara::Node::Matchers#has_css?
180
180
 
181
181
  ##
182
182
  # Assertion that there is no css
183
183
  #
184
184
  # @!method refute_css
185
185
  # @!method assert_no_css
186
- # see {Capybara::Node::Matchers#has_no_css?}
186
+ # @see Capybara::Node::Matchers#has_no_css?
187
187
 
188
188
  ##
189
189
  # Assertion that there is link
190
190
  #
191
191
  # @!method assert_link
192
- # see {Capybara::Node::Matchers#has_link?}
192
+ # @see Capybara::Node::Matchers#has_link?
193
193
 
194
194
  ##
195
195
  # Assertion that there is no link
196
196
  #
197
197
  # @!method assert_no_link
198
198
  # @!method refute_link
199
- # see {Capybara::Node::Matchers#has_no_link?}
199
+ # @see Capybara::Node::Matchers#has_no_link?
200
200
 
201
201
  ##
202
202
  # Assertion that there is button
203
203
  #
204
204
  # @!method assert_button
205
- # see {Capybara::Node::Matchers#has_button?}
205
+ # @see Capybara::Node::Matchers#has_button?
206
206
 
207
207
  ##
208
208
  # Assertion that there is no button
209
209
  #
210
210
  # @!method refute_button
211
211
  # @!method assert_no_button
212
- # see {Capybara::Node::Matchers#has_no_button?}
212
+ # @see Capybara::Node::Matchers#has_no_button?
213
213
 
214
214
  ##
215
215
  # Assertion that there is field
216
216
  #
217
217
  # @!method assert_field
218
- # see {Capybara::Node::Matchers#has_field?}
218
+ # @see Capybara::Node::Matchers#has_field?
219
219
 
220
220
  ##
221
221
  # Assertion that there is no field
222
222
  #
223
223
  # @!method refute_field
224
224
  # @!method assert_no_field
225
- # see {Capybara::Node::Matchers#has_no_field?}
225
+ # @see Capybara::Node::Matchers#has_no_field?
226
226
 
227
227
  ##
228
228
  # Assertion that there is checked_field
229
229
  #
230
230
  # @!method assert_checked_field
231
- # see {Capybara::Node::Matchers#has_checked_field?}
231
+ # @see Capybara::Node::Matchers#has_checked_field?
232
232
 
233
233
  ##
234
234
  # Assertion that there is no checked_field
@@ -240,7 +240,7 @@ module Capybara
240
240
  # Assertion that there is unchecked_field
241
241
  #
242
242
  # @!method assert_unchecked_field
243
- # see {Capybara::Node::Matchers#has_unchecked_field?}
243
+ # @see Capybara::Node::Matchers#has_unchecked_field?
244
244
 
245
245
  ##
246
246
  # Assertion that there is no unchecked_field
@@ -252,27 +252,27 @@ module Capybara
252
252
  # Assertion that there is select
253
253
  #
254
254
  # @!method assert_select
255
- # see {Capybara::Node::Matchers#has_select?}
255
+ # @see Capybara::Node::Matchers#has_select?
256
256
 
257
257
  ##
258
258
  # Assertion that there is no select
259
259
  #
260
260
  # @!method refute_select
261
261
  # @!method assert_no_select
262
- # see {Capybara::Node::Matchers#has_no_select?}
262
+ # @see Capybara::Node::Matchers#has_no_select?
263
263
 
264
264
  ##
265
265
  # Assertion that there is table
266
266
  #
267
267
  # @!method assert_table
268
- # see {Capybara::Node::Matchers#has_table?}
268
+ # @see Capybara::Node::Matchers#has_table?
269
269
 
270
270
  ##
271
271
  # Assertion that there is no table
272
272
  #
273
273
  # @!method refute_table
274
274
  # @!method assert_no_table
275
- # see {Capybara::Node::Matchers#has_no_table?}
275
+ # @see Capybara::Node::Matchers#has_no_table?
276
276
 
277
277
  private
278
278
 
@@ -514,7 +514,8 @@ module Capybara
514
514
  def reload
515
515
  if @allow_reload
516
516
  begin
517
- reloaded = query_scope.reload.first(@query.name, @query.locator, @query.options)
517
+ reloaded = @query.resolve_for(query_scope.reload)&.first
518
+
518
519
  @base = reloaded.base if reloaded
519
520
  rescue StandardError => e
520
521
  raise e unless catch_error?(e)
@@ -141,8 +141,8 @@ module Capybara
141
141
  # or descendants of the current node. If options are provided, the assertion
142
142
  # will check that each locator is present with those options as well (other than `:wait`).
143
143
  #
144
- # page.assert_all_of_selectors(:custom, 'Tom', 'Joe', visible: all)
145
- # page.assert_all_of_selectors(:css, '#my_div', 'a.not_clicked')
144
+ # page.assert_all_of_selectors(:custom, 'Tom', 'Joe', visible: all)
145
+ # page.assert_all_of_selectors(:css, '#my_div', 'a.not_clicked')
146
146
  #
147
147
  # It accepts all options that {Capybara::Node::Finders#all} accepts,
148
148
  # such as `:text` and `:visible`.
@@ -162,8 +162,8 @@ module Capybara
162
162
  # or descendants of the current node. If options are provided, the assertion
163
163
  # will check that each locator is not present with those options as well (other than `:wait`).
164
164
  #
165
- # page.assert_none_of_selectors(:custom, 'Tom', 'Joe', visible: all)
166
- # page.assert_none_of_selectors(:css, '#my_div', 'a.not_clicked')
165
+ # page.assert_none_of_selectors(:custom, 'Tom', 'Joe', visible: all)
166
+ # page.assert_none_of_selectors(:css, '#my_div', 'a.not_clicked')
167
167
  #
168
168
  # It accepts all options that {Capybara::Node::Finders#all} accepts,
169
169
  # such as `:text` and `:visible`.
@@ -183,8 +183,8 @@ module Capybara
183
183
  # or descendants of the current node. If options are provided, the assertion
184
184
  # will check that each locator is present with those options as well (other than `:wait`).
185
185
  #
186
- # page.assert_any_of_selectors(:custom, 'Tom', 'Joe', visible: all)
187
- # page.assert_any_of_selectors(:css, '#my_div', 'a.not_clicked')
186
+ # page.assert_any_of_selectors(:custom, 'Tom', 'Joe', visible: all)
187
+ # page.assert_any_of_selectors(:css, '#my_div', 'a.not_clicked')
188
188
  #
189
189
  # It accepts all options that {Capybara::Node::Finders#all} accepts,
190
190
  # such as `:text` and `:visible`.
@@ -197,7 +197,8 @@ module Capybara
197
197
  x.ancestor_or_self[
198
198
  x.attr(:style)[x.contains('display:none') | x.contains('display: none')] |
199
199
  x.attr(:hidden) |
200
- x.qname.one_of('script', 'head')
200
+ x.qname.one_of('script', 'head') |
201
+ (~x.self(:summary) & XPath.parent(:details))
201
202
  ].boolean
202
203
  end.to_s.freeze
203
204
  end
@@ -3,20 +3,16 @@
3
3
  module Capybara
4
4
  module Queries
5
5
  class AncestorQuery < Capybara::Queries::SelectorQuery
6
- def initialize(*args)
7
- super
8
- @count_options = {}
9
- COUNT_KEYS.each do |key|
10
- @count_options[key] = @options.delete(key) if @options.key?(key)
11
- end
12
- end
13
-
14
6
  # @api private
15
7
  def resolve_for(node, exact = nil)
16
8
  @child_node = node
9
+
17
10
  node.synchronize do
18
11
  match_results = super(node.session.current_scope, exact)
19
- node.all(:xpath, XPath.ancestor, **@count_options) { |el| match_results.include?(el) }
12
+ ancestors = node.find_xpath(XPath.ancestor.to_s)
13
+ .map(&method(:to_element))
14
+ .select { |el| match_results.include?(el) }
15
+ Capybara::Result.new(ancestors, self)
20
16
  end
21
17
  end
22
18
 
@@ -451,9 +451,9 @@ module Capybara
451
451
  return (visible != :hidden) && (node.initial_cache[:visible] != false) && !node.obscured? if obscured == false
452
452
 
453
453
  vis = case visible
454
- when :visible then
454
+ when :visible
455
455
  node.initial_cache[:visible] || (node.initial_cache[:visible].nil? && node.visible?)
456
- when :hidden then
456
+ when :hidden
457
457
  (node.initial_cache[:visible] == false) || (node.initial_cache[:visbile].nil? && !node.visible?)
458
458
  else
459
459
  true
@@ -3,21 +3,15 @@
3
3
  module Capybara
4
4
  module Queries
5
5
  class SiblingQuery < SelectorQuery
6
- def initialize(*args)
7
- super
8
- @count_options = {}
9
- COUNT_KEYS.each do |key|
10
- @count_options[key] = @options.delete(key) if @options.key?(key)
11
- end
12
- end
13
-
14
6
  # @api private
15
7
  def resolve_for(node, exact = nil)
16
8
  @sibling_node = node
17
9
  node.synchronize do
18
10
  match_results = super(node.session.current_scope, exact)
19
- xpath = XPath.preceding_sibling + XPath.following_sibling
20
- node.all(:xpath, xpath, **@count_options) { |el| match_results.include?(el) }
11
+ siblings = node.find_xpath((XPath.preceding_sibling + XPath.following_sibling).to_s)
12
+ .map(&method(:to_element))
13
+ .select { |el| match_results.include?(el) }
14
+ Capybara::Result.new(siblings, self)
21
15
  end
22
16
  end
23
17
 
@@ -23,7 +23,10 @@ Capybara.register_server :puma do |app, port, host, **options|
23
23
  # If we just run the Puma Rack handler it installs signal handlers which prevent us from being able to interrupt tests.
24
24
  # Therefore construct and run the Server instance ourselves.
25
25
  # Rack::Handler::Puma.run(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
26
- options = { Host: host, Port: port, Threads: '0:4', workers: 0, daemon: false, queue_requests: false }.merge(options)
26
+ default_options = { Host: host, Port: port, Threads: '0:4', workers: 0, daemon: false, queue_requests: false }
27
+ default_options[:queue_requests] = false if options[:Host]&.start_with?('ssl://')
28
+ options = default_options.merge(options)
29
+
27
30
  conf = Rack::Handler::Puma.config(app, options)
28
31
  events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
29
32
 
@@ -100,6 +100,8 @@ module Capybara
100
100
  def extract_strings(process_alternatives)
101
101
  strings = []
102
102
  each do |exp|
103
+ next if exp.ignore?
104
+
103
105
  next strings.push(nil) if exp.optional? && !process_alternatives
104
106
 
105
107
  next strings.push(exp.alternative_strings) if exp.alternation? && process_alternatives
@@ -159,6 +161,11 @@ module Capybara
159
161
  alts.all?(&:any?) ? Set.new(alts) : nil
160
162
  end
161
163
 
164
+ def ignore?
165
+ [Regexp::Expression::Assertion::NegativeLookahead,
166
+ Regexp::Expression::Assertion::NegativeLookbehind].any? { |klass| @exp.is_a? klass }
167
+ end
168
+
162
169
  private
163
170
 
164
171
  def indeterminate?
@@ -1 +1 @@
1
- (function(){function f(t,e,n){function r(t){var e=x(t);if(0<e.height&&0<e.width)return!0;if("PATH"==t.tagName.toUpperCase()&&(0<e.height||0<e.width)){var n=window.getComputedStyle(t)["stroke-width"];return!!n&&0<parseInt(n,10)}return"hidden"!=window.getComputedStyle(t).overflow&&Array.prototype.slice.call(t.childNodes).some(function(t){return t.nodeType==Node.TEXT_NODE||t.nodeType==Node.ELEMENT_NODE&&r(t)})}function i(t){return C(t)==T.HIDDEN&&Array.prototype.slice.call(t.childNodes).every(function(t){return t.nodeType!=Node.ELEMENT_NODE||i(t)||!r(t)})}var o=t.tagName.toUpperCase();if("BODY"==o)return!0;var a=D(t);if(a&&a.tagName&&"DETAILS"==a.tagName.toUpperCase()&&!a.open&&"SUMMARY"!=o)return!1;if("OPTION"==o||"OPTGROUP"==o){var u=v(t,function(t){return"SELECT"==t.tagName.toUpperCase()});return!!u&&f(u,!0,n)}var l=c(t);if(l)return!!l.image&&0<l.rect.width&&0<l.rect.height&&f(l.image,e,n);if("INPUT"==o&&"hidden"==t.type.toLowerCase())return!1;if("NOSCRIPT"==o)return!1;var d=window.getComputedStyle(t).visibility;return"collapse"!=d&&"hidden"!=d&&(!!n(t)&&(!(!e&&0==h(t))&&(!!r(t)&&!i(t))))}function E(t){var e=x(t);return{left:e.left,right:e.left+e.width,top:e.top,bottom:e.top+e.height}}function D(t){return t.parentElement}function C(t){function e(t){function e(t){if(t==u)return!0;var e=window.getComputedStyle(t),n=e.display;return 0!=n.indexOf("inline")&&"contents"!=n&&("absolute"!=r||"static"!=e.position)}var r=window.getComputedStyle(t).position;if("fixed"==r)return i=!0,t==u?null:u;for(var n=D(t);n&&!e(n);)n=D(n);return n}function n(t){var e=t;if("visible"==d)if(t==u&&l)e=l;else if(t==l)return{x:"visible",y:"visible"};var n=window.getComputedStyle(e),r={x:n["overflow-x"],y:n["overflow-y"]};return t==u&&(r.x="visible"==r.x?"auto":r.x,r.y="visible"==r.y?"auto":r.y),r}function r(t){return t==u?{x:window.scrollX,y:window.scrollY}:{x:t.scrollLeft,y:t.scrollTop}}for(var i,o=E(t),a=t.ownerDocument,u=a.documentElement,l=a.body,d=window.getComputedStyle(u).overflow,f=e(t);f;f=e(f)){var h=n(f);if("visible"!=h.x||"visible"!=h.y){var s=x(f);if(0==s.width||0==s.height)return T.HIDDEN;var p=o.right<s.left,c=o.bottom<s.top;if(p&&"hidden"==h.x||c&&"hidden"==h.y)return T.HIDDEN;if(p&&"visible"!=h.x||c&&"visible"!=h.y){var v=r(f),g=o.right<s.left-v.x,w=o.bottom<s.top-v.y;return g&&"visible"!=h.x||w&&"visible"!=h.x?T.HIDDEN:C(f)==T.HIDDEN?T.HIDDEN:T.SCROLL}var N=o.left>=s.left+s.width,m=o.top>=s.top+s.height;if(N&&"hidden"==h.x||m&&"hidden"==h.y)return T.HIDDEN;if(N&&"visible"!=h.x||m&&"visible"!=h.y){if(i){var y=r(f);if(o.left>=u.scrollWidth-y.x||o.right>=u.scrollHeight-y.y)return T.HIDDEN}return C(f)==T.HIDDEN?T.HIDDEN:T.SCROLL}}}return T.NONE}function o(t){var e=t.document.documentElement;return{width:e.clientWidth,height:e.clientHeight}}function p(t,e,n,r){return{left:t,top:e,width:n,height:r}}function x(t){var e,n=c(t);if(n)return n.rect;if("HTML"==t.tagName.toUpperCase()){t.ownerDocument;var r=o(window);return p(0,0,r.width,r.height)}try{e=t.getBoundingClientRect()}catch(i){return p(0,0,0,0)}return p(e.left,e.top,e.right-e.left,e.bottom-e.top)}function h(t){var e=1,n=window.getComputedStyle(t).opacity;n&&(e=Number(n));var r=D(t);return r&&r.nodeType==Node.ELEMENT_NODE&&(e*=h(r)),e}function s(t){var e=t.shape.toLowerCase(),n=t.coords.split(",");if("rect"==e&&4==n.length){var r=n[0],i=n[1];return p(r,i,n[2]-r,n[3]-i)}if("circle"==e&&3==n.length){var o=n[0],a=n[1],u=n[2];return p(o-u,a-u,2*u,2*u)}if("poly"==e&&2<n.length){for(var l=n[0],d=n[1],f=l,h=d,s=2;s+1<n.length;s+=2)l=Math.min(l,n[s]),f=Math.max(f,n[s]),d=Math.min(d,n[s+1]),h=Math.max(h,n[s+1]);return p(l,d,f-l,h-d)}return p(0,0,0,0)}function c(t){var e=t.tagName.toUpperCase(),n="MAP"==e;if(!n&&"AREA"!=e)return null;var r=n?t:"MAP"==D(t).tagName.toUpperCase()?D(t):null,i=null,o=null;if(r&&r.name&&((i=r.ownerDocument.querySelector("*[usemap='#"+r.name+"']"))&&(o=x(i),!n&&"default"!=t.shape.toLowerCase()))){var a=s(t),u=Math.min(Math.max(a.left,0),o.width),l=Math.min(Math.max(a.top,0),o.height),d=Math.min(a.width,o.width-u),f=Math.min(a.height,o.height-l);o=p(u+o.left,l+o.top,d,f)}return{image:i,rect:o||p(0,0,0,0)}}function v(t,e){for(t&&(t=D(t));t;){if(e(t))return t;t=D(t)}return null}function r(t){var e=t.parentNode;if(e&&e.shadowRoot&&t.assignedSlot!==undefined)return t.assignedSlot?t.assignedSlot.parentNode:null;if(t.getDestinationInsertionPoints){var n=t.getDestinationInsertionPoints();if(0<n.length)return n[n.length-1]}return e}var T={NONE:"none",HIDDEN:"hidden",SCROLL:"scroll"};return function i(t,e){function n(t){if("none"==window.getComputedStyle(t).display)return!1;var e=r(t);if("function"==typeof ShadowRoot&&e instanceof ShadowRoot){if(e.host.shadowRoot!==e)return!1;e=e.host}return!(!e||e.nodeType!=Node.DOCUMENT_NODE&&e.nodeType!=Node.DOCUMENT_FRAGMENT_NODE)||e&&n(e)}return f(t,!!e,n)}})()
1
+ (function(){function d(t,e,n){function r(t){var e=x(t);if(0<e.height&&0<e.width)return!0;if("PATH"==t.tagName.toUpperCase()&&(0<e.height||0<e.width)){var n=window.getComputedStyle(t)["stroke-width"];return!!n&&0<parseInt(n,10)}return"hidden"!=window.getComputedStyle(t).overflow&&Array.prototype.slice.call(t.childNodes).some(function(t){return t.nodeType==Node.TEXT_NODE||t.nodeType==Node.ELEMENT_NODE&&r(t)})}function i(t){return C(t)==T.HIDDEN&&Array.prototype.slice.call(t.childNodes).every(function(t){return t.nodeType!=Node.ELEMENT_NODE||i(t)||!r(t)})}var o=t.tagName.toUpperCase();if("BODY"==o)return!0;if("OPTION"==o||"OPTGROUP"==o){var a=c(t,function(t){return"SELECT"==t.tagName.toUpperCase()});return!!a&&d(a,!0,n)}var u=s(t);if(u)return!!u.image&&0<u.rect.width&&0<u.rect.height&&d(u.image,e,n);if("INPUT"==o&&"hidden"==t.type.toLowerCase())return!1;if("NOSCRIPT"==o)return!1;var l=window.getComputedStyle(t).visibility;return"collapse"!=l&&"hidden"!=l&&(!!n(t)&&(!(!e&&0==f(t))&&(!!r(t)&&!i(t))))}function E(t){var e=x(t);return{left:e.left,right:e.left+e.width,top:e.top,bottom:e.top+e.height}}function D(t){return t.parentElement}function C(t){function e(t){function e(t){if(t==u)return!0;var e=window.getComputedStyle(t),n=e.display;return 0!=n.indexOf("inline")&&"contents"!=n&&("absolute"!=r||"static"!=e.position)}var r=window.getComputedStyle(t).position;if("fixed"==r)return i=!0,t==u?null:u;for(var n=D(t);n&&!e(n);)n=D(n);return n}function n(t){var e=t;if("visible"==d)if(t==u&&l)e=l;else if(t==l)return{x:"visible",y:"visible"};var n=window.getComputedStyle(e),r={x:n["overflow-x"],y:n["overflow-y"]};return t==u&&(r.x="visible"==r.x?"auto":r.x,r.y="visible"==r.y?"auto":r.y),r}function r(t){return t==u?{x:window.scrollX,y:window.scrollY}:{x:t.scrollLeft,y:t.scrollTop}}for(var i,o=E(t),a=t.ownerDocument,u=a.documentElement,l=a.body,d=window.getComputedStyle(u).overflow,f=e(t);f;f=e(f)){var h=n(f);if("visible"!=h.x||"visible"!=h.y){var s=x(f);if(0==s.width||0==s.height)return T.HIDDEN;var p=o.right<s.left,c=o.bottom<s.top;if(p&&"hidden"==h.x||c&&"hidden"==h.y)return T.HIDDEN;if(p&&"visible"!=h.x||c&&"visible"!=h.y){var v=r(f),g=o.right<s.left-v.x,w=o.bottom<s.top-v.y;return g&&"visible"!=h.x||w&&"visible"!=h.x?T.HIDDEN:C(f)==T.HIDDEN?T.HIDDEN:T.SCROLL}var N=o.left>=s.left+s.width,m=o.top>=s.top+s.height;if(N&&"hidden"==h.x||m&&"hidden"==h.y)return T.HIDDEN;if(N&&"visible"!=h.x||m&&"visible"!=h.y){if(i){var y=r(f);if(o.left>=u.scrollWidth-y.x||o.right>=u.scrollHeight-y.y)return T.HIDDEN}return C(f)==T.HIDDEN?T.HIDDEN:T.SCROLL}}}return T.NONE}function o(t){var e=t.document.documentElement;return{width:e.clientWidth,height:e.clientHeight}}function p(t,e,n,r){return{left:t,top:e,width:n,height:r}}function x(t){var e,n=s(t);if(n)return n.rect;if("HTML"==t.tagName.toUpperCase()){t.ownerDocument;var r=o(window);return p(0,0,r.width,r.height)}try{e=t.getBoundingClientRect()}catch(i){return p(0,0,0,0)}return p(e.left,e.top,e.right-e.left,e.bottom-e.top)}function f(t){var e=1,n=window.getComputedStyle(t).opacity;n&&(e=Number(n));var r=D(t);return r&&r.nodeType==Node.ELEMENT_NODE&&(e*=f(r)),e}function h(t){var e=t.shape.toLowerCase(),n=t.coords.split(",");if("rect"==e&&4==n.length){var r=n[0],i=n[1];return p(r,i,n[2]-r,n[3]-i)}if("circle"==e&&3==n.length){var o=n[0],a=n[1],u=n[2];return p(o-u,a-u,2*u,2*u)}if("poly"==e&&2<n.length){for(var l=n[0],d=n[1],f=l,h=d,s=2;s+1<n.length;s+=2)l=Math.min(l,n[s]),f=Math.max(f,n[s]),d=Math.min(d,n[s+1]),h=Math.max(h,n[s+1]);return p(l,d,f-l,h-d)}return p(0,0,0,0)}function s(t){var e=t.tagName.toUpperCase(),n="MAP"==e;if(!n&&"AREA"!=e)return null;var r=n?t:"MAP"==D(t).tagName.toUpperCase()?D(t):null,i=null,o=null;if(r&&r.name&&((i=r.ownerDocument.querySelector("*[usemap='#"+r.name+"']"))&&(o=x(i),!n&&"default"!=t.shape.toLowerCase()))){var a=h(t),u=Math.min(Math.max(a.left,0),o.width),l=Math.min(Math.max(a.top,0),o.height),d=Math.min(a.width,o.width-u),f=Math.min(a.height,o.height-l);o=p(u+o.left,l+o.top,d,f)}return{image:i,rect:o||p(0,0,0,0)}}function c(t,e){for(t&&(t=D(t));t;){if(e(t))return t;t=D(t)}return null}function r(t){var e=t.parentNode;if(e&&e.shadowRoot&&t.assignedSlot!==undefined)return t.assignedSlot?t.assignedSlot.parentNode:null;if(t.getDestinationInsertionPoints){var n=t.getDestinationInsertionPoints();if(0<n.length)return n[n.length-1]}return e}var T={NONE:"none",HIDDEN:"hidden",SCROLL:"scroll"};return function i(t,e){function n(t){if("none"==window.getComputedStyle(t).display)return!1;var e=r(t);if("function"==typeof ShadowRoot&&e instanceof ShadowRoot){if(e.host.shadowRoot!==e)return!1;e=e.host}return!(!e||e.nodeType!=Node.DOCUMENT_NODE&&e.nodeType!=Node.DOCUMENT_FRAGMENT_NODE)||!(e&&e.tagName&&"DETAILS"==e.tagName.toUpperCase()&&!e.open&&"SUMMARY"!=t.tagName)&&(e&&n(e))}return d(t,!!e,n)}})()
@@ -14,15 +14,6 @@
14
14
  return true;
15
15
  }
16
16
 
17
- // Child of DETAILS element is not shown unless the DETAILS element is open
18
- // or the child is a SUMMARY element.
19
-
20
- var parent = getParentElement(elem);
21
- if (parent && parent.tagName && (parent.tagName.toUpperCase() == "DETAILS") &&
22
- !parent.open && !(elemTagName == "SUMMARY")) {
23
- return false;
24
- }
25
-
26
17
  // Option or optgroup is shown if enclosing select is shown (ignoring the
27
18
  // select's opacity).
28
19
  if ((elemTagName == "OPTION") ||
@@ -73,12 +64,14 @@
73
64
  if (rect.height > 0 && rect.width > 0) {
74
65
  return true;
75
66
  }
67
+
76
68
  // A vertical or horizontal SVG Path element will report zero width or
77
69
  // height but is "shown" if it has a positive stroke-width.
78
70
  if ((e.tagName.toUpperCase() == "PATH") && (rect.height > 0 || rect.width > 0)) {
79
71
  var strokeWidth = window.getComputedStyle(e)["stroke-width"];
80
72
  return !!strokeWidth && (parseInt(strokeWidth, 10) > 0);
81
73
  }
74
+
82
75
  // Zero-sized elements should still be considered to have positive size
83
76
  // if they have a child element or text node with positive size, unless
84
77
  // the element has an 'overflow' style of "hidden".
@@ -446,6 +439,13 @@
446
439
  return true;
447
440
  }
448
441
 
442
+ // Child of DETAILS element is not shown unless the DETAILS element is open
443
+ // or the child is a SUMMARY element.
444
+ if (parent && parent.tagName && (parent.tagName.toUpperCase() == "DETAILS") &&
445
+ !parent.open && !(e.tagName == "SUMMARY")) {
446
+ return false;
447
+ }
448
+
449
449
  return parent && displayed(parent);
450
450
  }
451
451