capybara 3.3.0 → 3.40.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (308) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/History.md +803 -13
  4. data/License.txt +1 -1
  5. data/README.md +257 -84
  6. data/lib/capybara/config.rb +25 -9
  7. data/lib/capybara/cucumber.rb +1 -1
  8. data/lib/capybara/driver/base.rb +17 -3
  9. data/lib/capybara/driver/node.rb +31 -6
  10. data/lib/capybara/dsl.rb +9 -7
  11. data/lib/capybara/helpers.rb +31 -7
  12. data/lib/capybara/minitest/spec.rb +180 -88
  13. data/lib/capybara/minitest.rb +262 -149
  14. data/lib/capybara/node/actions.rb +202 -116
  15. data/lib/capybara/node/base.rb +34 -19
  16. data/lib/capybara/node/document.rb +14 -2
  17. data/lib/capybara/node/document_matchers.rb +10 -12
  18. data/lib/capybara/node/element.rb +269 -115
  19. data/lib/capybara/node/finders.rb +99 -77
  20. data/lib/capybara/node/matchers.rb +327 -151
  21. data/lib/capybara/node/simple.rb +48 -13
  22. data/lib/capybara/node/whitespace_normalizer.rb +81 -0
  23. data/lib/capybara/queries/active_element_query.rb +18 -0
  24. data/lib/capybara/queries/ancestor_query.rb +8 -9
  25. data/lib/capybara/queries/base_query.rb +23 -16
  26. data/lib/capybara/queries/current_path_query.rb +16 -6
  27. data/lib/capybara/queries/match_query.rb +1 -0
  28. data/lib/capybara/queries/selector_query.rb +587 -130
  29. data/lib/capybara/queries/sibling_query.rb +8 -6
  30. data/lib/capybara/queries/style_query.rb +6 -2
  31. data/lib/capybara/queries/text_query.rb +28 -14
  32. data/lib/capybara/queries/title_query.rb +2 -2
  33. data/lib/capybara/rack_test/browser.rb +92 -25
  34. data/lib/capybara/rack_test/driver.rb +16 -7
  35. data/lib/capybara/rack_test/errors.rb +6 -0
  36. data/lib/capybara/rack_test/form.rb +68 -41
  37. data/lib/capybara/rack_test/node.rb +106 -39
  38. data/lib/capybara/rails.rb +1 -1
  39. data/lib/capybara/registration_container.rb +41 -0
  40. data/lib/capybara/registrations/drivers.rb +42 -0
  41. data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
  42. data/lib/capybara/registrations/servers.rb +66 -0
  43. data/lib/capybara/result.rb +75 -52
  44. data/lib/capybara/rspec/features.rb +7 -7
  45. data/lib/capybara/rspec/matcher_proxies.rb +39 -18
  46. data/lib/capybara/rspec/matchers/base.rb +113 -0
  47. data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
  48. data/lib/capybara/rspec/matchers/compound.rb +88 -0
  49. data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
  50. data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
  51. data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
  52. data/lib/capybara/rspec/matchers/have_selector.rb +69 -0
  53. data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
  54. data/lib/capybara/rspec/matchers/have_text.rb +33 -0
  55. data/lib/capybara/rspec/matchers/have_title.rb +29 -0
  56. data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
  57. data/lib/capybara/rspec/matchers/match_style.rb +43 -0
  58. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  59. data/lib/capybara/rspec/matchers.rb +141 -339
  60. data/lib/capybara/rspec.rb +2 -0
  61. data/lib/capybara/selector/builders/css_builder.rb +84 -0
  62. data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
  63. data/lib/capybara/selector/css.rb +27 -25
  64. data/lib/capybara/selector/definition/button.rb +68 -0
  65. data/lib/capybara/selector/definition/checkbox.rb +26 -0
  66. data/lib/capybara/selector/definition/css.rb +10 -0
  67. data/lib/capybara/selector/definition/datalist_input.rb +35 -0
  68. data/lib/capybara/selector/definition/datalist_option.rb +25 -0
  69. data/lib/capybara/selector/definition/element.rb +28 -0
  70. data/lib/capybara/selector/definition/field.rb +40 -0
  71. data/lib/capybara/selector/definition/fieldset.rb +14 -0
  72. data/lib/capybara/selector/definition/file_field.rb +13 -0
  73. data/lib/capybara/selector/definition/fillable_field.rb +33 -0
  74. data/lib/capybara/selector/definition/frame.rb +17 -0
  75. data/lib/capybara/selector/definition/id.rb +6 -0
  76. data/lib/capybara/selector/definition/label.rb +62 -0
  77. data/lib/capybara/selector/definition/link.rb +55 -0
  78. data/lib/capybara/selector/definition/link_or_button.rb +16 -0
  79. data/lib/capybara/selector/definition/option.rb +27 -0
  80. data/lib/capybara/selector/definition/radio_button.rb +27 -0
  81. data/lib/capybara/selector/definition/select.rb +81 -0
  82. data/lib/capybara/selector/definition/table.rb +109 -0
  83. data/lib/capybara/selector/definition/table_row.rb +21 -0
  84. data/lib/capybara/selector/definition/xpath.rb +5 -0
  85. data/lib/capybara/selector/definition.rb +280 -0
  86. data/lib/capybara/selector/filter.rb +1 -0
  87. data/lib/capybara/selector/filter_set.rb +73 -25
  88. data/lib/capybara/selector/filters/base.rb +24 -5
  89. data/lib/capybara/selector/filters/expression_filter.rb +3 -3
  90. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  91. data/lib/capybara/selector/filters/node_filter.rb +16 -2
  92. data/lib/capybara/selector/regexp_disassembler.rb +211 -0
  93. data/lib/capybara/selector/selector.rb +85 -348
  94. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  95. data/lib/capybara/selector.rb +474 -447
  96. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
  97. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
  98. data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
  99. data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
  100. data/lib/capybara/selenium/driver.rb +255 -143
  101. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +93 -11
  102. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
  103. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +84 -0
  104. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
  105. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
  106. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  107. data/lib/capybara/selenium/extensions/find.rb +110 -0
  108. data/lib/capybara/selenium/extensions/html5_drag.rb +229 -0
  109. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  110. data/lib/capybara/selenium/extensions/scroll.rb +76 -0
  111. data/lib/capybara/selenium/node.rb +436 -134
  112. data/lib/capybara/selenium/nodes/chrome_node.rb +125 -0
  113. data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
  114. data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
  115. data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
  116. data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
  117. data/lib/capybara/selenium/patches/atoms.rb +18 -0
  118. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  119. data/lib/capybara/selenium/patches/logs.rb +45 -0
  120. data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
  121. data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
  122. data/lib/capybara/server/animation_disabler.rb +56 -19
  123. data/lib/capybara/server/checker.rb +9 -3
  124. data/lib/capybara/server/middleware.rb +28 -12
  125. data/lib/capybara/server.rb +33 -10
  126. data/lib/capybara/session/config.rb +34 -10
  127. data/lib/capybara/session/matchers.rb +23 -16
  128. data/lib/capybara/session.rb +230 -170
  129. data/lib/capybara/spec/public/jquery.js +5 -5
  130. data/lib/capybara/spec/public/offset.js +6 -0
  131. data/lib/capybara/spec/public/test.js +121 -8
  132. data/lib/capybara/spec/session/accept_alert_spec.rb +11 -11
  133. data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -3
  134. data/lib/capybara/spec/session/accept_prompt_spec.rb +9 -10
  135. data/lib/capybara/spec/session/active_element_spec.rb +31 -0
  136. data/lib/capybara/spec/session/all_spec.rb +127 -40
  137. data/lib/capybara/spec/session/ancestor_spec.rb +24 -19
  138. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +67 -38
  139. data/lib/capybara/spec/session/assert_current_path_spec.rb +21 -18
  140. data/lib/capybara/spec/session/assert_selector_spec.rb +52 -58
  141. data/lib/capybara/spec/session/assert_style_spec.rb +7 -7
  142. data/lib/capybara/spec/session/assert_text_spec.rb +74 -50
  143. data/lib/capybara/spec/session/assert_title_spec.rb +12 -12
  144. data/lib/capybara/spec/session/attach_file_spec.rb +126 -72
  145. data/lib/capybara/spec/session/body_spec.rb +6 -6
  146. data/lib/capybara/spec/session/check_spec.rb +102 -47
  147. data/lib/capybara/spec/session/choose_spec.rb +58 -32
  148. data/lib/capybara/spec/session/click_button_spec.rb +219 -163
  149. data/lib/capybara/spec/session/click_link_or_button_spec.rb +49 -23
  150. data/lib/capybara/spec/session/click_link_spec.rb +77 -54
  151. data/lib/capybara/spec/session/current_scope_spec.rb +8 -8
  152. data/lib/capybara/spec/session/current_url_spec.rb +38 -29
  153. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
  154. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -2
  155. data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +8 -8
  156. data/lib/capybara/spec/session/element/match_css_spec.rb +16 -10
  157. data/lib/capybara/spec/session/element/match_xpath_spec.rb +6 -6
  158. data/lib/capybara/spec/session/element/matches_selector_spec.rb +68 -56
  159. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +7 -7
  160. data/lib/capybara/spec/session/evaluate_script_spec.rb +28 -8
  161. data/lib/capybara/spec/session/execute_script_spec.rb +8 -7
  162. data/lib/capybara/spec/session/fill_in_spec.rb +101 -46
  163. data/lib/capybara/spec/session/find_button_spec.rb +23 -23
  164. data/lib/capybara/spec/session/find_by_id_spec.rb +7 -7
  165. data/lib/capybara/spec/session/find_field_spec.rb +32 -30
  166. data/lib/capybara/spec/session/find_link_spec.rb +31 -21
  167. data/lib/capybara/spec/session/find_spec.rb +244 -141
  168. data/lib/capybara/spec/session/first_spec.rb +43 -43
  169. data/lib/capybara/spec/session/frame/frame_title_spec.rb +5 -5
  170. data/lib/capybara/spec/session/frame/frame_url_spec.rb +5 -5
  171. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +30 -18
  172. data/lib/capybara/spec/session/frame/within_frame_spec.rb +45 -18
  173. data/lib/capybara/spec/session/go_back_spec.rb +1 -1
  174. data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
  175. data/lib/capybara/spec/session/has_all_selectors_spec.rb +23 -23
  176. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  177. data/lib/capybara/spec/session/has_any_selectors_spec.rb +29 -0
  178. data/lib/capybara/spec/session/has_button_spec.rb +94 -13
  179. data/lib/capybara/spec/session/has_css_spec.rb +272 -132
  180. data/lib/capybara/spec/session/has_current_path_spec.rb +50 -35
  181. data/lib/capybara/spec/session/has_element_spec.rb +47 -0
  182. data/lib/capybara/spec/session/has_field_spec.rb +137 -58
  183. data/lib/capybara/spec/session/has_link_spec.rb +44 -4
  184. data/lib/capybara/spec/session/has_none_selectors_spec.rb +31 -31
  185. data/lib/capybara/spec/session/has_select_spec.rb +84 -50
  186. data/lib/capybara/spec/session/has_selector_spec.rb +111 -71
  187. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  188. data/lib/capybara/spec/session/has_table_spec.rb +181 -4
  189. data/lib/capybara/spec/session/has_text_spec.rb +101 -53
  190. data/lib/capybara/spec/session/has_title_spec.rb +19 -14
  191. data/lib/capybara/spec/session/has_xpath_spec.rb +56 -38
  192. data/lib/capybara/spec/session/headers_spec.rb +1 -1
  193. data/lib/capybara/spec/session/html_spec.rb +13 -6
  194. data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
  195. data/lib/capybara/spec/session/node_spec.rb +894 -142
  196. data/lib/capybara/spec/session/node_wrapper_spec.rb +10 -7
  197. data/lib/capybara/spec/session/refresh_spec.rb +9 -7
  198. data/lib/capybara/spec/session/reset_session_spec.rb +63 -35
  199. data/lib/capybara/spec/session/response_code_spec.rb +1 -1
  200. data/lib/capybara/spec/session/save_and_open_page_spec.rb +2 -2
  201. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
  202. data/lib/capybara/spec/session/save_page_spec.rb +37 -37
  203. data/lib/capybara/spec/session/save_screenshot_spec.rb +10 -10
  204. data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
  205. data/lib/capybara/spec/session/scroll_spec.rb +119 -0
  206. data/lib/capybara/spec/session/select_spec.rb +85 -85
  207. data/lib/capybara/spec/session/selectors_spec.rb +49 -18
  208. data/lib/capybara/spec/session/sibling_spec.rb +9 -9
  209. data/lib/capybara/spec/session/text_spec.rb +25 -24
  210. data/lib/capybara/spec/session/title_spec.rb +7 -6
  211. data/lib/capybara/spec/session/uncheck_spec.rb +33 -21
  212. data/lib/capybara/spec/session/unselect_spec.rb +37 -37
  213. data/lib/capybara/spec/session/visit_spec.rb +68 -49
  214. data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
  215. data/lib/capybara/spec/session/window/current_window_spec.rb +1 -1
  216. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +20 -16
  217. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +6 -2
  218. data/lib/capybara/spec/session/window/window_spec.rb +62 -63
  219. data/lib/capybara/spec/session/window/windows_spec.rb +5 -1
  220. data/lib/capybara/spec/session/window/within_window_spec.rb +14 -14
  221. data/lib/capybara/spec/session/within_spec.rb +79 -42
  222. data/lib/capybara/spec/spec_helper.rb +41 -53
  223. data/lib/capybara/spec/test_app.rb +132 -43
  224. data/lib/capybara/spec/views/animated.erb +49 -0
  225. data/lib/capybara/spec/views/form.erb +139 -42
  226. data/lib/capybara/spec/views/frame_child.erb +4 -3
  227. data/lib/capybara/spec/views/frame_one.erb +2 -1
  228. data/lib/capybara/spec/views/frame_parent.erb +1 -1
  229. data/lib/capybara/spec/views/frame_two.erb +1 -1
  230. data/lib/capybara/spec/views/initial_alert.erb +2 -1
  231. data/lib/capybara/spec/views/layout.erb +10 -0
  232. data/lib/capybara/spec/views/obscured.erb +47 -0
  233. data/lib/capybara/spec/views/offset.erb +33 -0
  234. data/lib/capybara/spec/views/path.erb +2 -2
  235. data/lib/capybara/spec/views/popup_one.erb +1 -1
  236. data/lib/capybara/spec/views/popup_two.erb +1 -1
  237. data/lib/capybara/spec/views/react.erb +45 -0
  238. data/lib/capybara/spec/views/scroll.erb +21 -0
  239. data/lib/capybara/spec/views/spatial.erb +31 -0
  240. data/lib/capybara/spec/views/tables.erb +67 -0
  241. data/lib/capybara/spec/views/with_animation.erb +39 -4
  242. data/lib/capybara/spec/views/with_base_tag.erb +2 -2
  243. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  244. data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
  245. data/lib/capybara/spec/views/with_hover.erb +3 -2
  246. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  247. data/lib/capybara/spec/views/with_html.erb +37 -9
  248. data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
  249. data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
  250. data/lib/capybara/spec/views/with_js.erb +26 -5
  251. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  252. data/lib/capybara/spec/views/with_namespace.erb +1 -0
  253. data/lib/capybara/spec/views/with_scope.erb +2 -2
  254. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  255. data/lib/capybara/spec/views/with_shadow.erb +31 -0
  256. data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
  257. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  258. data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
  259. data/lib/capybara/spec/views/with_windows.erb +1 -1
  260. data/lib/capybara/spec/views/within_frames.erb +1 -1
  261. data/lib/capybara/version.rb +1 -1
  262. data/lib/capybara/window.rb +19 -25
  263. data/lib/capybara.rb +126 -111
  264. data/spec/basic_node_spec.rb +59 -34
  265. data/spec/capybara_spec.rb +56 -44
  266. data/spec/counter_spec.rb +35 -0
  267. data/spec/css_builder_spec.rb +101 -0
  268. data/spec/css_splitter_spec.rb +8 -8
  269. data/spec/dsl_spec.rb +79 -52
  270. data/spec/filter_set_spec.rb +9 -9
  271. data/spec/fixtures/selenium_driver_rspec_failure.rb +4 -4
  272. data/spec/fixtures/selenium_driver_rspec_success.rb +4 -4
  273. data/spec/minitest_spec.rb +45 -7
  274. data/spec/minitest_spec_spec.rb +87 -64
  275. data/spec/per_session_config_spec.rb +6 -6
  276. data/spec/rack_test_spec.rb +172 -116
  277. data/spec/regexp_dissassembler_spec.rb +250 -0
  278. data/spec/result_spec.rb +80 -72
  279. data/spec/rspec/features_spec.rb +21 -16
  280. data/spec/rspec/scenarios_spec.rb +10 -6
  281. data/spec/rspec/shared_spec_matchers.rb +407 -365
  282. data/spec/rspec/views_spec.rb +3 -3
  283. data/spec/rspec_matchers_spec.rb +35 -10
  284. data/spec/rspec_spec.rb +63 -41
  285. data/spec/sauce_spec_chrome.rb +43 -0
  286. data/spec/selector_spec.rb +334 -89
  287. data/spec/selenium_spec_chrome.rb +176 -62
  288. data/spec/selenium_spec_chrome_remote.rb +54 -14
  289. data/spec/selenium_spec_edge.rb +41 -8
  290. data/spec/selenium_spec_firefox.rb +228 -0
  291. data/spec/selenium_spec_firefox_remote.rb +94 -0
  292. data/spec/selenium_spec_ie.rb +129 -11
  293. data/spec/selenium_spec_safari.rb +162 -0
  294. data/spec/server_spec.rb +171 -97
  295. data/spec/session_spec.rb +34 -18
  296. data/spec/shared_selenium_node.rb +79 -0
  297. data/spec/shared_selenium_session.rb +344 -80
  298. data/spec/spec_helper.rb +124 -2
  299. data/spec/whitespace_normalizer_spec.rb +54 -0
  300. data/spec/xpath_builder_spec.rb +93 -0
  301. metadata +326 -28
  302. data/lib/capybara/rspec/compound.rb +0 -94
  303. data/lib/capybara/selenium/driver_specializations/marionette_driver.rb +0 -31
  304. data/lib/capybara/selenium/nodes/marionette_node.rb +0 -31
  305. data/lib/capybara/spec/session/has_style_spec.rb +0 -25
  306. data/lib/capybara/spec/session/source_spec.rb +0 -0
  307. data/lib/capybara/spec/views/with_title.erb +0 -5
  308. data/spec/selenium_spec_marionette.rb +0 -167
@@ -0,0 +1 @@
1
+ (function(){function u(e){var t=e.tagName.toUpperCase();if("OPTION"==t)return!0;if("INPUT"!=t)return!1;var r=e.type.toLowerCase();return"checkbox"==r||"radio"==r}function s(e){var t="selected",r=e.type&&e.type.toLowerCase();return"checkbox"!=r&&"radio"!=r||(t="checked"),!!e[t]}function c(e,t){var r=e.getAttributeNode(t);return r&&r.specified?r.value:null}var i=["allowfullscreen","allowpaymentrequest","allowusermedia","async","autofocus","autoplay","checked","compact","complete","controls","declare","default","defaultchecked","defaultselected","defer","disabled","ended","formnovalidate","hidden","indeterminate","iscontenteditable","ismap","itemscope","loop","multiple","muted","nohref","nomodule","noresize","noshade","novalidate","nowrap","open","paused","playsinline","pubdate","readonly","required","reversed","scoped","seamless","seeking","selected","truespeed","typemustmatch","willvalidate"],d={"class":"className",readonly:"readOnly"};return function f(e,t){var r=null,a=t.toLowerCase();if("style"==a)return(r=e.style)&&"string"!=typeof r&&(r=r.cssText),r;if(("selected"==a||"checked"==a)&&u(e))return s(e)?"true":null;if(tagName=e.tagName.toUpperCase(),"IMG"==tagName&&"src"==a||"A"==tagName&&"href"==a)return(r=c(e,a))&&(r=e[a]),r;if("spellcheck"==a){if(null!==(r=c(e,a))){if("false"==r.toLowerCase())return"false";if("true"==r.toLowerCase())return"true"}return e[a]+""}var l,n=d[t]||t;if(i.some(function(e){e==a}))return(r=!(null===(r=c(e,a)))||e[n])?"true":null;try{l=e[n]}catch(o){}return null!=(r=null==l||"object"==typeof l||"function"==typeof l?c(e,t):l)?r.toString():null}})()
@@ -0,0 +1 @@
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)}})()
@@ -0,0 +1,161 @@
1
+ (function(){
2
+ var BOOLEAN_PROPERTIES = [
3
+ "allowfullscreen",
4
+ "allowpaymentrequest",
5
+ "allowusermedia",
6
+ "async",
7
+ "autofocus",
8
+ "autoplay",
9
+ "checked",
10
+ "compact",
11
+ "complete",
12
+ "controls",
13
+ "declare",
14
+ "default",
15
+ "defaultchecked",
16
+ "defaultselected",
17
+ "defer",
18
+ "disabled",
19
+ "ended",
20
+ "formnovalidate",
21
+ "hidden",
22
+ "indeterminate",
23
+ "iscontenteditable",
24
+ "ismap",
25
+ "itemscope",
26
+ "loop",
27
+ "multiple",
28
+ "muted",
29
+ "nohref",
30
+ "nomodule",
31
+ "noresize",
32
+ "noshade",
33
+ "novalidate",
34
+ "nowrap",
35
+ "open",
36
+ "paused",
37
+ "playsinline",
38
+ "pubdate",
39
+ "readonly",
40
+ "required",
41
+ "reversed",
42
+ "scoped",
43
+ "seamless",
44
+ "seeking",
45
+ "selected",
46
+ "truespeed",
47
+ "typemustmatch",
48
+ "willvalidate"
49
+ ];
50
+
51
+ var PROPERTY_ALIASES = {
52
+ "class": "className",
53
+ "readonly": "readOnly"
54
+ };
55
+
56
+ function isSelectable(element){
57
+ var tagName = element.tagName.toUpperCase();
58
+
59
+ if (tagName == "OPTION"){
60
+ return true;
61
+ }
62
+
63
+ if (tagName == "INPUT") {
64
+ var type = element.type.toLowerCase();
65
+ return type == "checkbox" || type == "radio";
66
+ }
67
+
68
+ return false;
69
+ }
70
+
71
+ function isSelected(element){
72
+ var propertyName = "selected";
73
+ var type = element.type && element.type.toLowerCase();
74
+ if ("checkbox" == type || "radio" == type) {
75
+ propertyName = "checked";
76
+ }
77
+
78
+ return !!element[propertyName];
79
+ }
80
+
81
+ function getAttributeValue(element, name){
82
+ var attr = element.getAttributeNode(name);
83
+ return (attr && attr.specified) ? attr.value : null;
84
+ }
85
+
86
+ return function get(element, attribute){
87
+ var value = null;
88
+ var name = attribute.toLowerCase();
89
+
90
+ if ("style" == name) {
91
+ value = element.style;
92
+
93
+ if (value && (typeof value != "string")) {
94
+ value = value.cssText;
95
+ }
96
+
97
+ return value;
98
+ }
99
+
100
+ if (("selected" == name || "checked" == name) &&
101
+ isSelectable(element)) {
102
+ return isSelected(element) ? "true" : null;
103
+ }
104
+
105
+ tagName = element.tagName.toUpperCase();
106
+
107
+ // The property is consistent. Return that in preference to the attribute for links and images.
108
+ if (((tagName == "IMG") && name == "src") ||
109
+ ((tagName == "A") && name == "href")) {
110
+ value = getAttributeValue(element, name);
111
+ if (value) {
112
+ // We want the full URL if present
113
+ value = element[name];
114
+ }
115
+ return value;
116
+ }
117
+
118
+ if ("spellcheck" == name) {
119
+ value = getAttributeValue(element, name);
120
+ if (!(value === null)) {
121
+ if (value.toLowerCase() == "false") {
122
+ return "false";
123
+ } else if (value.toLowerCase() == "true") {
124
+ return "true";
125
+ }
126
+ }
127
+ // coerce the property value to a string
128
+ return element[name] + "";
129
+ }
130
+ var propName = PROPERTY_ALIASES[attribute] || attribute;
131
+ if (BOOLEAN_PROPERTIES.some(function(prop){ prop == name })) {
132
+ value = getAttributeValue(element, name);
133
+ value = !(value === null) || element[propName];
134
+ return value ? "true" : null;
135
+ }
136
+ var property;
137
+ try {
138
+ property = element[propName]
139
+ } catch (e) {
140
+ // Leaves property undefined or null
141
+ }
142
+ // 1- Call getAttribute if getProperty fails,
143
+ // i.e. property is null or undefined.
144
+ // This happens for event handlers in Firefox.
145
+ // For example, calling getProperty for 'onclick' would
146
+ // fail while getAttribute for 'onclick' will succeed and
147
+ // return the JS code of the handler.
148
+ //
149
+ // 2- When property is an object we fall back to the
150
+ // actual attribute instead.
151
+ // See issue http://code.google.com/p/selenium/issues/detail?id=966
152
+ if ((property == null) || (typeof property == "object") || (typeof property == "function")) {
153
+ value = getAttributeValue(element, attribute);
154
+ } else {
155
+ value = property;
156
+ };
157
+
158
+ // The empty string is a valid return value.
159
+ return value != null ? value.toString() : null;
160
+ };
161
+ })()
@@ -0,0 +1,454 @@
1
+ (function(){
2
+ var OverflowState = {
3
+ NONE: "none",
4
+ HIDDEN: "hidden",
5
+ SCROLL: "scroll"
6
+ };
7
+
8
+ function isShown_(elem, ignoreOpacity, parentsDisplayedFn) {
9
+ // By convention, BODY element is always shown: BODY represents the document
10
+ // and even if there's nothing rendered in there, user can always see there's
11
+ // the document.
12
+ var elemTagName = elem.tagName.toUpperCase();
13
+ if (elemTagName == "BODY") {
14
+ return true;
15
+ }
16
+
17
+ // Option or optgroup is shown if enclosing select is shown (ignoring the
18
+ // select's opacity).
19
+ if ((elemTagName == "OPTION") ||
20
+ (elemTagName == "OPTGROUP")) {
21
+ var select = getAncestor(elem, function(e) {
22
+ return e.tagName.toUpperCase() == "SELECT";
23
+ });
24
+ return !!select && isShown_(select, true, parentsDisplayedFn);
25
+ }
26
+
27
+ // Image map elements are shown if image that uses it is shown, and
28
+ // the area of the element is positive.
29
+ var imageMap = maybeFindImageMap_(elem);
30
+ if (imageMap) {
31
+ return !!imageMap.image &&
32
+ imageMap.rect.width > 0 && imageMap.rect.height > 0 &&
33
+ isShown_(imageMap.image, ignoreOpacity, parentsDisplayedFn);
34
+ }
35
+
36
+ // Any hidden input is not shown.
37
+ if ((elemTagName == "INPUT") && (elem.type.toLowerCase() == "hidden")) {
38
+ return false;
39
+ }
40
+
41
+ // Any NOSCRIPT element is not shown.
42
+ if (elemTagName == "NOSCRIPT") {
43
+ return false;
44
+ }
45
+
46
+ // Any element with hidden/collapsed visibility is not shown.
47
+ var visibility = window.getComputedStyle(elem)["visibility"];
48
+ if (visibility == "collapse" || visibility == "hidden") {
49
+ return false;
50
+ }
51
+
52
+ if (!parentsDisplayedFn(elem)) {
53
+ return false;
54
+ }
55
+
56
+ // Any transparent element is not shown.
57
+ if (!ignoreOpacity && getOpacity(elem) == 0) {
58
+ return false;
59
+ }
60
+
61
+ // Any element without positive size dimensions is not shown.
62
+ function positiveSize(e) {
63
+ var rect = getClientRect(e);
64
+ if (rect.height > 0 && rect.width > 0) {
65
+ return true;
66
+ }
67
+
68
+ // A vertical or horizontal SVG Path element will report zero width or
69
+ // height but is "shown" if it has a positive stroke-width.
70
+ if ((e.tagName.toUpperCase() == "PATH") && (rect.height > 0 || rect.width > 0)) {
71
+ var strokeWidth = window.getComputedStyle(e)["stroke-width"];
72
+ return !!strokeWidth && (parseInt(strokeWidth, 10) > 0);
73
+ }
74
+
75
+ // Zero-sized elements should still be considered to have positive size
76
+ // if they have a child element or text node with positive size, unless
77
+ // the element has an 'overflow' style of "hidden".
78
+ return window.getComputedStyle(e)["overflow"] != "hidden" &&
79
+ Array.prototype.slice.call(e.childNodes).some(function(n) {
80
+ return (n.nodeType == Node.TEXT_NODE) ||
81
+ ((n.nodeType == Node.ELEMENT_NODE) && positiveSize(n));
82
+ });
83
+ }
84
+
85
+ if (!positiveSize(elem)) {
86
+ return false;
87
+ }
88
+
89
+ // Elements that are hidden by overflow are not shown.
90
+ function hiddenByOverflow(e) {
91
+ return getOverflowState(e) == OverflowState.HIDDEN &&
92
+ Array.prototype.slice.call(e.childNodes).every(function(n) {
93
+ return (n.nodeType != Node.ELEMENT_NODE) || hiddenByOverflow(n) ||
94
+ !positiveSize(n);
95
+ });
96
+ }
97
+ return !hiddenByOverflow(elem);
98
+ }
99
+
100
+ function getClientRegion(elem) {
101
+ var region = getClientRect(elem);
102
+ return { left: region.left,
103
+ right: region.left + region.width,
104
+ top: region.top,
105
+ bottom: region.top + region.height };
106
+ }
107
+
108
+ function getParentElement(node) {
109
+ return node.parentElement
110
+ }
111
+
112
+ function getOverflowState(elem) {
113
+ var region = getClientRegion(elem);
114
+ var ownerDoc = elem.ownerDocument;
115
+ var htmlElem = ownerDoc.documentElement;
116
+ var bodyElem = ownerDoc.body;
117
+ var htmlOverflowStyle = window.getComputedStyle(htmlElem)["overflow"];
118
+ var treatAsFixedPosition;
119
+
120
+ // Return the closest ancestor that the given element may overflow.
121
+ function getOverflowParent(e) {
122
+ function canBeOverflowed(container) {
123
+ // The HTML element can always be overflowed.
124
+ if (container == htmlElem) {
125
+ return true;
126
+ }
127
+ var containerStyle = window.getComputedStyle(container);
128
+ // An element cannot overflow an element with an inline or contents display style.
129
+ var containerDisplay = containerStyle["display"];
130
+ if ((containerDisplay.indexOf("inline") == 0) ||
131
+ (containerDisplay == "contents")) {
132
+ return false;
133
+ }
134
+ // An absolute-positioned element cannot overflow a static-positioned one.
135
+ if ((position == "absolute") && (containerStyle["position"] == "static")) {
136
+ return false;
137
+ }
138
+ return true;
139
+ }
140
+
141
+ var position = window.getComputedStyle(e)["position"];
142
+ if (position == "fixed") {
143
+ treatAsFixedPosition = true;
144
+ // Fixed-position element may only overflow the viewport.
145
+ return e == htmlElem ? null : htmlElem;
146
+ } else {
147
+ var parent = getParentElement(e);
148
+ while (parent && !canBeOverflowed(parent)) {
149
+ parent = getParentElement(parent);
150
+ }
151
+ return parent;
152
+ }
153
+ };
154
+
155
+ // Return the x and y overflow styles for the given element.
156
+ function getOverflowStyles(e) {
157
+ // When the <html> element has an overflow style of 'visible', it assumes
158
+ // the overflow style of the body, and the body is really overflow:visible.
159
+ var overflowElem = e;
160
+ if (htmlOverflowStyle == "visible") {
161
+ // NOTE: bodyElem will be null/undefined in SVG documents.
162
+ if (e == htmlElem && bodyElem) {
163
+ overflowElem = bodyElem;
164
+ } else if (e == bodyElem) {
165
+ return {x: "visible", y: "visible"};
166
+ }
167
+ }
168
+ var overflowElemStyle = window.getComputedStyle(overflowElem);
169
+ var overflow = {
170
+ x: overflowElemStyle["overflow-x"],
171
+ y: overflowElemStyle["overflow-y"]
172
+ };
173
+ // The <html> element cannot have a genuine 'visible' overflow style,
174
+ // because the viewport can't expand; 'visible' is really 'auto'.
175
+ if (e == htmlElem) {
176
+ overflow.x = overflow.x == "visible" ? "auto" : overflow.x;
177
+ overflow.y = overflow.y == "visible" ? "auto" : overflow.y;
178
+ }
179
+ return overflow;
180
+ };
181
+
182
+ // Returns the scroll offset of the given element.
183
+ function getScroll(e) {
184
+ if (e == htmlElem) {
185
+ return { x: window.scrollX, y: window.scrollY }
186
+ }
187
+ return { x: e.scrollLeft, y: e.scrollTop }
188
+ }
189
+
190
+ // Check if the element overflows any ancestor element.
191
+ for (var container = getOverflowParent(elem);
192
+ !!container;
193
+ container = getOverflowParent(container)) {
194
+ var containerOverflow = getOverflowStyles(container);
195
+
196
+ // If the container has overflow:visible, the element cannot overflow it.
197
+ if (containerOverflow.x == "visible" && containerOverflow.y == "visible") {
198
+ continue;
199
+ }
200
+
201
+ var containerRect = getClientRect(container);
202
+
203
+ // Zero-sized containers without overflow:visible hide all descendants.
204
+ if (containerRect.width == 0 || containerRect.height == 0) {
205
+ return OverflowState.HIDDEN;
206
+ }
207
+
208
+ // Check "underflow": if an element is to the left or above the container
209
+ var underflowsX = region.right < containerRect.left;
210
+ var underflowsY = region.bottom < containerRect.top;
211
+ if ((underflowsX && containerOverflow.x == "hidden") ||
212
+ (underflowsY && containerOverflow.y == "hidden")) {
213
+ return OverflowState.HIDDEN;
214
+ } else if ((underflowsX && containerOverflow.x != "visible") ||
215
+ (underflowsY && containerOverflow.y != "visible")) {
216
+ // When the element is positioned to the left or above a container, we
217
+ // have to distinguish between the element being completely outside the
218
+ // container and merely scrolled out of view within the container.
219
+ var containerScroll = getScroll(container);
220
+ var unscrollableX = region.right < containerRect.left - containerScroll.x;
221
+ var unscrollableY = region.bottom < containerRect.top - containerScroll.y;
222
+ if ((unscrollableX && containerOverflow.x != "visible") ||
223
+ (unscrollableY && containerOverflow.x != "visible")) {
224
+ return OverflowState.HIDDEN;
225
+ }
226
+ var containerState = getOverflowState(container);
227
+ return containerState == OverflowState.HIDDEN ?
228
+ OverflowState.HIDDEN : OverflowState.SCROLL;
229
+ }
230
+
231
+ // Check "overflow": if an element is to the right or below a container
232
+ var overflowsX = region.left >= containerRect.left + containerRect.width;
233
+ var overflowsY = region.top >= containerRect.top + containerRect.height;
234
+ if ((overflowsX && containerOverflow.x == "hidden") ||
235
+ (overflowsY && containerOverflow.y == "hidden")) {
236
+ return OverflowState.HIDDEN;
237
+ } else if ((overflowsX && containerOverflow.x != "visible") ||
238
+ (overflowsY && containerOverflow.y != "visible")) {
239
+ // If the element has fixed position and falls outside the scrollable area
240
+ // of the document, then it is hidden.
241
+ if (treatAsFixedPosition) {
242
+ var docScroll = getScroll(container);
243
+ if ((region.left >= htmlElem.scrollWidth - docScroll.x) ||
244
+ (region.right >= htmlElem.scrollHeight - docScroll.y)) {
245
+ return OverflowState.HIDDEN;
246
+ }
247
+ }
248
+ // If the element can be scrolled into view of the parent, it has a scroll
249
+ // state; unless the parent itself is entirely hidden by overflow, in
250
+ // which it is also hidden by overflow.
251
+ var containerState = getOverflowState(container);
252
+ return containerState == OverflowState.HIDDEN ?
253
+ OverflowState.HIDDEN : OverflowState.SCROLL;
254
+ }
255
+ }
256
+
257
+ // Does not overflow any ancestor.
258
+ return OverflowState.NONE;
259
+ }
260
+
261
+ function getViewportSize(win) {
262
+ var el = win.document.documentElement;
263
+ return { width: el.clientWidth, height: el.clientHeight };
264
+ }
265
+
266
+ function rect_(x, y, w, h){
267
+ return { left: x, top: y, width: w, height: h };
268
+ }
269
+
270
+ function getClientRect(elem) {
271
+ var imageMap = maybeFindImageMap_(elem);
272
+ if (imageMap) {
273
+ return imageMap.rect;
274
+ } else if (elem.tagName.toUpperCase() == "HTML") {
275
+ // Define the client rect of the <html> element to be the viewport.
276
+ var doc = elem.ownerDocument;
277
+ // TODO: Is this too simplified???
278
+ var viewportSize = getViewportSize(window);
279
+ return rect_(0, 0, viewportSize.width, viewportSize.height);
280
+ } else {
281
+ var nativeRect;
282
+ try {
283
+ nativeRect = elem.getBoundingClientRect();
284
+ } catch (e) {
285
+ return rect_(0, 0, 0, 0);
286
+ }
287
+
288
+ return rect_(nativeRect.left, nativeRect.top,
289
+ nativeRect.right - nativeRect.left, nativeRect.bottom - nativeRect.top);
290
+ }
291
+ }
292
+
293
+ function getOpacity(elem) {
294
+ // By default the element is opaque.
295
+ var elemOpacity = 1;
296
+
297
+ var opacityStyle = window.getComputedStyle(elem)["opacity"];
298
+ if (opacityStyle) {
299
+ elemOpacity = Number(opacityStyle);
300
+ }
301
+
302
+ // Let's apply the parent opacity to the element.
303
+ var parentElement = getParentElement(elem);
304
+ if (parentElement && parentElement.nodeType == Node.ELEMENT_NODE) {
305
+ elemOpacity = elemOpacity * getOpacity(parentElement);
306
+ }
307
+ return elemOpacity;
308
+ }
309
+
310
+ function getAreaRelativeRect_(area) {
311
+ var shape = area.shape.toLowerCase();
312
+ var coords = area.coords.split(",");
313
+ if (shape == "rect" && coords.length == 4) {
314
+ var x = coords[0], y = coords[1];
315
+ return rect_(x, y, coords[2] - x, coords[3] - y);
316
+ } else if (shape == "circle" && coords.length == 3) {
317
+ var centerX = coords[0], centerY = coords[1], radius = coords[2];
318
+ return rect_(centerX - radius, centerY - radius, 2 * radius, 2 * radius);
319
+ } else if (shape == "poly" && coords.length > 2) {
320
+ var minX = coords[0], minY = coords[1], maxX = minX, maxY = minY;
321
+ for (var i = 2; i + 1 < coords.length; i += 2) {
322
+ minX = Math.min(minX, coords[i]);
323
+ maxX = Math.max(maxX, coords[i]);
324
+ minY = Math.min(minY, coords[i + 1]);
325
+ maxY = Math.max(maxY, coords[i + 1]);
326
+ }
327
+ return rect_(minX, minY, maxX - minX, maxY - minY);
328
+ }
329
+ return rect_(0, 0, 0, 0);
330
+ }
331
+
332
+ function maybeFindImageMap_(elem) {
333
+ // If not a <map> or <area>, return null indicating so.
334
+ var elemTagName = elem.tagName.toUpperCase();
335
+ var isMap = elemTagName == "MAP";
336
+ if (!isMap && (elemTagName != "AREA")) {
337
+ return null;
338
+ }
339
+
340
+ // Get the <map> associated with this element, or null if none.
341
+ var map = isMap ? elem :
342
+ ((getParentElement(elem).tagName.toUpperCase() == "MAP") ?
343
+ getParentElement(elem) : null);
344
+
345
+ var image = null, rect = null;
346
+ if (map && map.name) {
347
+ var mapDoc = map.ownerDocument;
348
+
349
+ image = mapDoc.querySelector("*[usemap='#" + map.name + "']");
350
+
351
+ if (image) {
352
+ rect = getClientRect(image);
353
+ if (!isMap && elem.shape.toLowerCase() != "default") {
354
+ // Shift and crop the relative area rectangle to the map.
355
+ var relRect = getAreaRelativeRect_(elem);
356
+ var relX = Math.min(Math.max(relRect.left, 0), rect.width);
357
+ var relY = Math.min(Math.max(relRect.top, 0), rect.height);
358
+ var w = Math.min(relRect.width, rect.width - relX);
359
+ var h = Math.min(relRect.height, rect.height - relY);
360
+ rect = rect_(relX + rect.left, relY + rect.top, w, h);
361
+ }
362
+ }
363
+ }
364
+
365
+ return {image: image, rect: rect || rect_(0, 0, 0, 0)};
366
+ }
367
+
368
+ function getAncestor(element, matcher) {
369
+ if (element) {
370
+ element = getParentElement(element);
371
+ }
372
+ while (element) {
373
+ if (matcher(element)) {
374
+ return element;
375
+ }
376
+ element = getParentElement(element);
377
+ }
378
+ // Reached the root of the DOM without a match
379
+ return null;
380
+ }
381
+
382
+
383
+ function isElement(node, opt_tagName) {
384
+ // because we call this with deprecated tags such as SHADOW
385
+ if (opt_tagName && (typeof opt_tagName !== "string")) {
386
+ opt_tagName = opt_tagName.toString();
387
+ }
388
+ return !!node && node.nodeType == Node.ELEMENT_NODE &&
389
+ (!opt_tagName || node.tagName.toUpperCase() == opt_tagName);
390
+ }
391
+
392
+ function getParentNodeInComposedDom(node) {
393
+ var /**@type {Node}*/ parent = node.parentNode;
394
+
395
+ // Shadow DOM v1
396
+ if (parent && parent.shadowRoot && node.assignedSlot !== undefined) {
397
+ // Can be null on purpose, meaning it has no parent as
398
+ // it hasn't yet been slotted
399
+ return node.assignedSlot ? node.assignedSlot.parentNode : null;
400
+ }
401
+
402
+ // Shadow DOM V0 (deprecated)
403
+ if (node.getDestinationInsertionPoints) {
404
+ var destinations = node.getDestinationInsertionPoints();
405
+ if (destinations.length > 0) {
406
+ return destinations[destinations.length - 1];
407
+ }
408
+ }
409
+
410
+ return parent;
411
+ }
412
+
413
+ return function isShown(elem, opt_ignoreOpacity) {
414
+ /**
415
+ * Determines whether an element or its parents have `display: none` set
416
+ * @param {!Node} e the element
417
+ * @return {boolean}
418
+ */
419
+ function displayed(e) {
420
+ if (window.getComputedStyle(e)["display"] == "none"){
421
+ return false;
422
+ }
423
+
424
+ var parent = getParentNodeInComposedDom(e);
425
+
426
+ if ((typeof ShadowRoot === "function") && (parent instanceof ShadowRoot)) {
427
+ if (parent.host.shadowRoot !== parent) {
428
+ // There is a younger shadow root, which will take precedence over
429
+ // the shadow this element is in, thus this element won't be
430
+ // displayed.
431
+ return false;
432
+ } else {
433
+ parent = parent.host;
434
+ }
435
+ }
436
+
437
+ if (parent && (parent.nodeType == Node.DOCUMENT_NODE ||
438
+ parent.nodeType == Node.DOCUMENT_FRAGMENT_NODE)) {
439
+ return true;
440
+ }
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
+ return parent && displayed(parent);
450
+ }
451
+
452
+ return isShown_(elem, !!opt_ignoreOpacity, displayed);
453
+ };
454
+ })()