From b801d61852912897cd736f48c64bd9b275f4fd31 Mon Sep 17 00:00:00 2001 From: Matt Huntington Date: Mon, 23 Jun 2014 17:58:27 -0400 Subject: [PATCH] adding selenium --- node_modules/selenium-webdriver/CHANGES.md | 169 + node_modules/selenium-webdriver/COPYING | 204 + node_modules/selenium-webdriver/README.md | 77 + node_modules/selenium-webdriver/_base.js | 165 + node_modules/selenium-webdriver/builder.js | 113 + node_modules/selenium-webdriver/chrome.js | 473 ++ .../docs/class_bot_Error.html | 6 + .../docs/class_goog_Uri.html | 63 + .../docs/class_goog_Uri_QueryData.html | 34 + .../class_goog_asserts_AssertionError.html | 4 + .../docs/class_goog_debug_Error.html | 2 + .../class_goog_iter_GroupByIterator_.html | 12 + .../docs/class_goog_iter_Iterator.html | 11 + .../docs/class_goog_json_Serializer.html | 4 + .../class_goog_labs_testing_AllOfMatcher.html | 2 + .../class_goog_labs_testing_AnyOfMatcher.html | 1 + ...lass_goog_labs_testing_CloseToMatcher.html | 1 + ...og_labs_testing_ContainsStringMatcher.html | 1 + ...ass_goog_labs_testing_EndsWithMatcher.html | 1 + ...ting_EqualToIgnoringWhitespaceMatcher.html | 1 + ...lass_goog_labs_testing_EqualToMatcher.html | 1 + ...class_goog_labs_testing_EqualsMatcher.html | 1 + ...abs_testing_GreaterThanEqualToMatcher.html | 1 + ..._goog_labs_testing_GreaterThanMatcher.html | 1 + ..._goog_labs_testing_HasPropertyMatcher.html | 1 + ...s_goog_labs_testing_InstanceOfMatcher.html | 1 + .../class_goog_labs_testing_IsNotMatcher.html | 1 + ...class_goog_labs_testing_IsNullMatcher.html | 1 + ...labs_testing_IsNullOrUndefinedMatcher.html | 1 + ..._goog_labs_testing_IsUndefinedMatcher.html | 1 + ...g_labs_testing_LessThanEqualToMatcher.html | 1 + ...ass_goog_labs_testing_LessThanMatcher.html | 1 + .../class_goog_labs_testing_MatcherError.html | 3 + ...goog_labs_testing_ObjectEqualsMatcher.html | 1 + .../class_goog_labs_testing_RegexMatcher.html | 1 + ...s_goog_labs_testing_StartsWithMatcher.html | 1 + ..._testing_StringContainsInOrderMatcher.html | 1 + .../class_goog_net_DefaultXmlHttpFactory.html | 4 + .../class_goog_net_WrapperXmlHttpFactory.html | 7 + .../docs/class_goog_net_XmlHttpFactory.html | 4 + .../docs/class_goog_structs_Map.html | 28 + .../docs/class_webdriver_AbstractBuilder.html | 21 + .../docs/class_webdriver_ActionSequence.html | 87 + .../docs/class_webdriver_Alert.html | 85 + .../docs/class_webdriver_Builder.html | 22 + .../docs/class_webdriver_Capabilities.html | 9 + .../docs/class_webdriver_Command.html | 1 + .../docs/class_webdriver_EventEmitter.html | 7 + .../class_webdriver_FirefoxDomExecutor.html | 2 + .../docs/class_webdriver_Locator.html | 2 + .../docs/class_webdriver_Session.html | 3 + .../class_webdriver_UnhandledAlertError.html | 6 + .../docs/class_webdriver_WebDriver.html | 259 + .../docs/class_webdriver_WebDriver_Logs.html | 10 + .../class_webdriver_WebDriver_Navigation.html | 5 + .../class_webdriver_WebDriver_Options.html | 17 + ...ass_webdriver_WebDriver_TargetLocator.html | 27 + .../class_webdriver_WebDriver_Timeouts.html | 21 + .../class_webdriver_WebDriver_Window.html | 11 + .../docs/class_webdriver_WebElement.html | 231 + .../docs/class_webdriver_http_CorsClient.html | 33 + .../docs/class_webdriver_http_Executor.html | 8 + .../docs/class_webdriver_http_Request.html | 4 + .../docs/class_webdriver_http_Response.html | 3 + .../docs/class_webdriver_http_XhrClient.html | 1 + .../docs/class_webdriver_logging_Entry.html | 4 + ..._webdriver_promise_CanceledTaskError_.html | 4 + .../class_webdriver_promise_ControlFlow.html | 117 + .../class_webdriver_promise_Deferred.html | 86 + .../docs/class_webdriver_promise_Frame_.html | 118 + .../docs/class_webdriver_promise_Node_.html | 73 + .../docs/class_webdriver_promise_Promise.html | 64 + .../docs/class_webdriver_promise_Task_.html | 77 + .../class_webdriver_stacktrace_Frame.html | 8 + .../class_webdriver_stacktrace_Snapshot.html | 5 + .../class_webdriver_testing_Assertion.html | 32 + ..._testing_Assertion_DelegatingMatcher_.html | 3 + ...ass_webdriver_testing_ContainsMatcher.html | 1 + ...ss_webdriver_testing_NegatedAssertion.html | 26 + .../selenium-webdriver/docs/dossier.css | 1 + .../selenium-webdriver/docs/dossier.js | 135 + .../docs/enum_bot_ErrorCode.html | 2 + .../docs/enum_bot_Error_State.html | 1 + .../docs/enum_goog_dom_NodeType.html | 10 + .../enum_goog_net_XmlHttp_OptionType.html | 4 + .../enum_goog_net_XmlHttp_ReadyState.html | 3 + .../docs/enum_goog_string_Unicode.html | 1 + .../docs/enum_goog_uri_utils_CharCode_.html | 1 + .../enum_goog_uri_utils_ComponentIndex.html | 1 + ...num_goog_uri_utils_StandardQueryParam.html | 1 + .../docs/enum_webdriver_Browser.html | 1 + .../docs/enum_webdriver_Button.html | 1 + .../docs/enum_webdriver_Capability.html | 14 + .../docs/enum_webdriver_CommandName.html | 2 + ...bdriver_FirefoxDomExecutor_Attribute_.html | 1 + ...bdriver_FirefoxDomExecutor_EventType_.html | 1 + .../docs/enum_webdriver_Key.html | 9 + .../docs/enum_webdriver_logging_Level.html | 1 + .../enum_webdriver_logging_LevelName.html | 1 + .../docs/enum_webdriver_logging_Type.html | 1 + ...bdriver_promise_ControlFlow_EventType.html | 4 + ...num_webdriver_promise_Deferred_State_.html | 1 + .../selenium-webdriver/docs/index.html | 62 + .../interface_goog_labs_testing_Matcher.html | 2 + .../docs/interface_goog_net_XhrLike.html | 3 + .../interface_webdriver_CommandExecutor.html | 5 + .../docs/interface_webdriver_http_Client.html | 6 + .../selenium-webdriver/docs/license.html | 205 + .../docs/module_selenium-webdriver.html | 4 + .../docs/module_selenium-webdriver__base.html | 14 + .../module_selenium-webdriver_builder.html | 1 + ...enium-webdriver_builder_class_Builder.html | 13 + .../module_selenium-webdriver_chrome.html | 5 + ...lenium-webdriver_chrome_class_Options.html | 22 + ...webdriver_chrome_class_ServiceBuilder.html | 13 + .../docs/module_selenium-webdriver_error.html | 4 + .../module_selenium-webdriver_executors.html | 3 + .../docs/module_selenium-webdriver_http.html | 4 + ...enium-webdriver_http_class_HttpClient.html | 2 + .../module_selenium-webdriver_http_util.html | 5 + .../docs/module_selenium-webdriver_io.html | 4 + .../docs/module_selenium-webdriver_net.html | 1 + ...ule_selenium-webdriver_net_portprober.html | 6 + .../module_selenium-webdriver_phantomjs.html | 1 + .../docs/module_selenium-webdriver_proxy.html | 24 + .../module_selenium-webdriver_remote.html | 19 + ...-webdriver_remote_class_DriverService.html | 19 + ...webdriver_remote_class_SeleniumServer.html | 31 + .../module_selenium-webdriver_testing.html | 73 + ...ule_selenium-webdriver_testing_assert.html | 19 + .../docs/namespace_bot.html | 4 + .../docs/namespace_bot_json.html | 4 + .../docs/namespace_bot_response.html | 5 + .../docs/namespace_bot_userAgent.html | 21 + .../docs/namespace_goog.html | 242 + .../docs/namespace_goog_array.html | 337 ++ .../docs/namespace_goog_asserts.html | 22 + .../docs/namespace_goog_debug.html | 1 + .../docs/namespace_goog_dom.html | 1 + .../docs/namespace_goog_functions.html | 30 + .../docs/namespace_goog_iter.html | 189 + .../docs/namespace_goog_json.html | 10 + .../docs/namespace_goog_labs.html | 1 + .../docs/namespace_goog_labs_testing.html | 1 + .../docs/namespace_goog_labs_userAgent.html | 1 + ...namespace_goog_labs_userAgent_browser.html | 15 + .../namespace_goog_labs_userAgent_engine.html | 4 + .../namespace_goog_labs_userAgent_util.html | 9 + .../docs/namespace_goog_math.html | 61 + .../docs/namespace_goog_net.html | 1 + .../docs/namespace_goog_net_XmlHttp.html | 4 + .../namespace_goog_net_XmlHttpDefines.html | 1 + .../docs/namespace_goog_object.html | 77 + .../docs/namespace_goog_string.html | 188 + .../docs/namespace_goog_structs.html | 38 + .../docs/namespace_goog_uri.html | 1 + .../docs/namespace_goog_uri_utils.html | 192 + .../docs/namespace_goog_userAgent.html | 35 + .../namespace_goog_userAgent_product.html | 9 + .../docs/namespace_webdriver.html | 4 + .../docs/namespace_webdriver_By.html | 26 + .../docs/namespace_webdriver_http.html | 4 + .../docs/namespace_webdriver_logging.html | 4 + .../docs/namespace_webdriver_process.html | 8 + .../docs/namespace_webdriver_promise.html | 79 + .../docs/namespace_webdriver_stacktrace.html | 39 + .../docs/namespace_webdriver_testing.html | 1 + .../namespace_webdriver_testing_assert.html | 3 + .../namespace_webdriver_testing_asserts.html | 10 + .../docs/source/_base.js.src.html | 1 + .../docs/source/builder.js.src.html | 1 + .../docs/source/chrome.js.src.html | 1 + .../docs/source/error.js.src.html | 1 + .../docs/source/executors.js.src.html | 1 + .../docs/source/http/index.js.src.html | 1 + .../docs/source/http/util.js.src.html | 1 + .../docs/source/index.js.src.html | 1 + .../docs/source/io/index.js.src.html | 1 + .../docs/source/lib/atoms/error.js.src.html | 1 + .../docs/source/lib/atoms/json.js.src.html | 1 + .../source/lib/atoms/response.js.src.html | 1 + .../source/lib/atoms/userAgent.js.src.html | 1 + .../source/lib/goog/array/array.js.src.html | 1 + .../lib/goog/asserts/asserts.js.src.html | 1 + .../docs/source/lib/goog/base.js.src.html | 1 + .../source/lib/goog/debug/error.js.src.html | 1 + .../docs/source/lib/goog/deps.js.src.html | 1 + .../source/lib/goog/dom/nodetype.js.src.html | 1 + .../lib/goog/functions/functions.js.src.html | 1 + .../source/lib/goog/iter/iter.js.src.html | 1 + .../source/lib/goog/json/json.js.src.html | 1 + .../goog/labs/testing/assertthat.js.src.html | 1 + .../labs/testing/logicmatcher.js.src.html | 1 + .../lib/goog/labs/testing/matcher.js.src.html | 1 + .../labs/testing/numbermatcher.js.src.html | 1 + .../labs/testing/objectmatcher.js.src.html | 1 + .../labs/testing/stringmatcher.js.src.html | 1 + .../goog/labs/useragent/browser.js.src.html | 1 + .../goog/labs/useragent/engine.js.src.html | 1 + .../lib/goog/labs/useragent/util.js.src.html | 1 + .../source/lib/goog/math/math.js.src.html | 1 + .../net/wrapperxmlhttpfactory.js.src.html | 1 + .../source/lib/goog/net/xhrlike.js.src.html | 1 + .../source/lib/goog/net/xmlhttp.js.src.html | 1 + .../lib/goog/net/xmlhttpfactory.js.src.html | 1 + .../source/lib/goog/object/object.js.src.html | 1 + .../source/lib/goog/string/string.js.src.html | 1 + .../source/lib/goog/structs/map.js.src.html | 1 + .../lib/goog/structs/structs.js.src.html | 1 + .../docs/source/lib/goog/uri/uri.js.src.html | 1 + .../source/lib/goog/uri/utils.js.src.html | 1 + .../lib/goog/useragent/product.js.src.html | 1 + .../useragent/product_isversion.js.src.html | 1 + .../lib/goog/useragent/useragent.js.src.html | 1 + .../lib/webdriver/abstractbuilder.js.src.html | 1 + .../lib/webdriver/actionsequence.js.src.html | 1 + .../source/lib/webdriver/builder.js.src.html | 1 + .../source/lib/webdriver/button.js.src.html | 1 + .../lib/webdriver/capabilities.js.src.html | 1 + .../source/lib/webdriver/command.js.src.html | 1 + .../source/lib/webdriver/events.js.src.html | 1 + .../webdriver/firefoxdomexecutor.js.src.html | 1 + .../lib/webdriver/http/corsclient.js.src.html | 1 + .../lib/webdriver/http/http.js.src.html | 1 + .../lib/webdriver/http/xhrclient.js.src.html | 1 + .../docs/source/lib/webdriver/key.js.src.html | 1 + .../source/lib/webdriver/locators.js.src.html | 1 + .../source/lib/webdriver/logging.js.src.html | 1 + .../source/lib/webdriver/process.js.src.html | 1 + .../source/lib/webdriver/promise.js.src.html | 1 + .../source/lib/webdriver/session.js.src.html | 1 + .../lib/webdriver/stacktrace.js.src.html | 1 + .../lib/webdriver/testing/asserts.js.src.html | 1 + .../lib/webdriver/webdriver.js.src.html | 1 + .../docs/source/net/index.js.src.html | 1 + .../docs/source/net/portprober.js.src.html | 1 + .../docs/source/phantomjs.js.src.html | 1 + .../docs/source/proxy.js.src.html | 1 + .../docs/source/remote/index.js.src.html | 1 + .../docs/source/testing/assert.js.src.html | 1 + .../docs/source/testing/index.js.src.html | 1 + node_modules/selenium-webdriver/docs/types.js | 1 + node_modules/selenium-webdriver/error.js | 25 + .../example/google_search.js | 40 + .../example/google_search_test.js | 50 + node_modules/selenium-webdriver/executors.js | 59 + node_modules/selenium-webdriver/http/index.js | 159 + node_modules/selenium-webdriver/http/util.js | 133 + node_modules/selenium-webdriver/index.js | 128 + node_modules/selenium-webdriver/io/index.js | 52 + node_modules/selenium-webdriver/lib/README | 2 + .../selenium-webdriver/lib/atoms/error.js | 205 + .../selenium-webdriver/lib/atoms/json.js | 78 + .../selenium-webdriver/lib/atoms/response.js | 107 + .../selenium-webdriver/lib/atoms/userAgent.js | 255 + .../selenium-webdriver/lib/goog/LICENSE | 176 + .../lib/goog/array/array.js | 1570 +++++ .../lib/goog/asserts/asserts.js | 316 + .../selenium-webdriver/lib/goog/base.js | 1706 ++++++ .../lib/goog/debug/error.js | 54 + .../selenium-webdriver/lib/goog/deps.js | 55 + .../lib/goog/dom/nodetype.js | 48 + .../lib/goog/functions/functions.js | 311 + .../selenium-webdriver/lib/goog/iter/iter.js | 1314 +++++ .../selenium-webdriver/lib/goog/json/json.js | 370 ++ .../lib/goog/labs/testing/assertthat.js | 60 + .../lib/goog/labs/testing/logicmatcher.js | 212 + .../lib/goog/labs/testing/matcher.js | 80 + .../lib/goog/labs/testing/numbermatcher.js | 346 ++ .../lib/goog/labs/testing/objectmatcher.js | 318 + .../lib/goog/labs/testing/stringmatcher.js | 416 ++ .../lib/goog/labs/useragent/browser.js | 271 + .../lib/goog/labs/useragent/engine.js | 130 + .../lib/goog/labs/useragent/util.js | 154 + .../selenium-webdriver/lib/goog/math/math.js | 435 ++ .../lib/goog/net/wrapperxmlhttpfactory.js | 71 + .../lib/goog/net/xhrlike.js | 124 + .../lib/goog/net/xmlhttp.js | 246 + .../lib/goog/net/xmlhttpfactory.js | 67 + .../lib/goog/object/object.js | 637 ++ .../lib/goog/string/string.js | 1476 +++++ .../lib/goog/structs/map.js | 461 ++ .../lib/goog/structs/structs.js | 354 ++ .../selenium-webdriver/lib/goog/uri/uri.js | 1501 +++++ .../selenium-webdriver/lib/goog/uri/utils.js | 1076 ++++ .../lib/goog/useragent/product.js | 253 + .../lib/goog/useragent/product_isversion.js | 140 + .../lib/goog/useragent/useragent.js | 553 ++ .../selenium-webdriver/lib/test/build.js | 151 + ...kTest_testClicksASurroundingStrongTag.html | 11 + .../lib/test/data/Page.aspx | 17 + .../lib/test/data/Page.aspx.cs | 22 + .../lib/test/data/Redirect.aspx | 11 + .../lib/test/data/Redirect.aspx.cs | 9 + .../lib/test/data/Settings.StyleCop | 759 +++ .../lib/test/data/Web.Config | 59 + .../lib/test/data/actualXhtmlPage.xhtml | 14 + .../lib/test/data/ajaxy_page.html | 81 + .../lib/test/data/alerts.html | 85 + .../lib/test/data/banner.gif | Bin 0 -> 2109 bytes .../lib/test/data/beach.jpg | Bin 0 -> 14085 bytes .../lib/test/data/blank.html | 1 + .../lib/test/data/bodyTypingTest.html | 41 + .../lib/test/data/booleanAttributes.html | 19 + .../lib/test/data/child/childPage.html | 8 + .../data/child/grandchild/grandchildPage.html | 8 + .../lib/test/data/clickEventPage.html | 26 + .../lib/test/data/click_frames.html | 10 + .../lib/test/data/click_jacker.html | 38 + .../lib/test/data/click_out_of_bounds.html | 23 + .../data/click_out_of_bounds_overflow.html | 85 + .../lib/test/data/click_rtl.html | 19 + .../lib/test/data/click_source.html | 18 + .../test/data/click_tests/click_iframe.html | 6 + .../data/click_tests/click_in_iframe.html | 8 + .../lib/test/data/click_tests/google_map.html | 15 + .../lib/test/data/click_tests/google_map.png | Bin 0 -> 26209 bytes .../click_tests/html5_submit_buttons.html | 15 + .../lib/test/data/click_tests/issue5237.html | 9 + .../data/click_tests/issue5237_frame.html | 1 + .../data/click_tests/issue5237_target.html | 10 + .../data/click_tests/link_that_wraps.html | 11 + .../test/data/click_tests/mapped_page1.html | 9 + .../test/data/click_tests/mapped_page2.html | 9 + .../test/data/click_tests/mapped_page3.html | 9 + .../data/click_tests/span_that_wraps.html | 11 + .../test/data/click_tests/submitted_page.html | 9 + .../lib/test/data/click_too_big.html | 10 + .../lib/test/data/click_too_big_in_frame.html | 11 + .../lib/test/data/clicks.html | 35 + .../lib/test/data/closeable_window.html | 8 + .../lib/test/data/cn-test.html | 156 + .../lib/test/data/colorPage.html | 20 + .../lib/test/data/cookies.html | 30 + .../coordinates_tests/element_in_frame.html | 9 + .../element_in_nested_frame.html | 9 + .../page_with_element_out_of_view.html | 11 + .../page_with_empty_element.html | 10 + .../page_with_fixed_element.html | 12 + .../page_with_hidden_element.html | 10 + .../page_with_invisible_element.html | 10 + .../page_with_transparent_element.html | 10 + .../data/coordinates_tests/simple_page.html | 10 + .../ui-bg_diagonals-thick_18_b81900_40x40.png | Bin 0 -> 260 bytes .../ui-bg_diagonals-thick_20_666666_40x40.png | Bin 0 -> 251 bytes .../images/ui-bg_flat_10_000000_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_100_f6f6f6_1x400.png | Bin 0 -> 104 bytes .../images/ui-bg_glass_100_fdf5ce_1x400.png | Bin 0 -> 125 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../ui-bg_gloss-wave_35_f6a828_500x100.png | Bin 0 -> 3762 bytes .../ui-bg_highlight-soft_100_eeeeee_1x100.png | Bin 0 -> 90 bytes .../ui-bg_highlight-soft_75_ffe45c_1x100.png | Bin 0 -> 129 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_228ef1_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_ef8c08_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_ffd27a_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 4369 bytes .../ui-lightness/jquery-ui-1.8.10.custom.css | 573 ++ .../lib/test/data/cssTransform.html | 61 + .../lib/test/data/cssTransform2.html | 20 + .../test/data/document_write_in_onload.html | 13 + .../data/dragAndDropInsideScrolledDiv.html | 67 + .../lib/test/data/dragAndDropTest.html | 102 + .../lib/test/data/dragDropOverflow.html | 104 + .../lib/test/data/draggableLists.html | 67 + .../lib/test/data/droppableItems.html | 65 + .../lib/test/data/dynamic.html | 39 + .../test/data/dynamicallyModifiedPage.html | 42 + .../lib/test/data/errors.html | 15 + .../lib/test/data/fixedFooterNoScroll.html | 13 + .../data/fixedFooterNoScrollQuirksMode.html | 12 + .../lib/test/data/formPage.html | 174 + .../lib/test/data/formSelectionPage.html | 46 + .../test/data/form_handling_js_submit.html | 30 + .../lib/test/data/framePage3.html | 7 + .../lib/test/data/frameScrollChild.html | 26 + .../lib/test/data/frameScrollPage.html | 14 + .../lib/test/data/frameScrollParent.html | 11 + .../data/frame_switching_tests/bug4876.html | 9 + .../frame_switching_tests/bug4876_iframe.html | 9 + .../frame_switching_tests/deletingFrame.html | 29 + .../deletingFrame_iframe.html | 8 + .../deletingFrame_iframe2.html | 7 + .../lib/test/data/frameset.html | 14 + .../lib/test/data/framesetPage2.html | 7 + .../lib/test/data/framesetPage3.html | 4 + .../lib/test/data/globalscope.html | 15 + .../lib/test/data/hidden.html | 5 + .../lib/test/data/html5/blue.jpg | Bin 0 -> 92 bytes .../lib/test/data/html5/database.js | 84 + .../lib/test/data/html5/geolocation.js | 18 + .../lib/test/data/html5/green.jpg | Bin 0 -> 92 bytes .../lib/test/data/html5/red.jpg | Bin 0 -> 92 bytes .../lib/test/data/html5/status.html | 1 + .../lib/test/data/html5/test.appcache | 11 + .../lib/test/data/html5/yellow.jpg | Bin 0 -> 92 bytes .../lib/test/data/html5Page.html | 32 + .../selenium-webdriver/lib/test/data/icon.gif | Bin 0 -> 127 bytes .../lib/test/data/iframeAtBottom.html | 15 + .../lib/test/data/iframeWithAlert.html | 1 + .../lib/test/data/iframeWithIframe.html | 1 + .../lib/test/data/iframes.html | 11 + .../lib/test/data/injectableContent.html | 22 + .../lib/test/data/javascriptEnhancedForm.html | 30 + .../lib/test/data/javascriptPage.html | 275 + .../lib/test/data/jquery-1.3.2.js | 4376 ++++++++++++++ .../lib/test/data/js/jquery-1.4.4.min.js | 167 + .../data/js/jquery-ui-1.8.10.custom.min.js | 782 +++ .../js/skins/lightgray/content.inline.min.css | 1 + .../data/js/skins/lightgray/content.min.css | 1 + .../data/js/skins/lightgray/fonts/readme.md | 1 + .../lightgray/fonts/tinymce-small.dev.svg | 175 + .../skins/lightgray/fonts/tinymce-small.eot | Bin 0 -> 10316 bytes .../skins/lightgray/fonts/tinymce-small.svg | 62 + .../skins/lightgray/fonts/tinymce-small.ttf | Bin 0 -> 10128 bytes .../skins/lightgray/fonts/tinymce-small.woff | Bin 0 -> 7848 bytes .../js/skins/lightgray/fonts/tinymce.dev.svg | 153 + .../data/js/skins/lightgray/fonts/tinymce.eot | Bin 0 -> 10024 bytes .../data/js/skins/lightgray/fonts/tinymce.svg | 63 + .../data/js/skins/lightgray/fonts/tinymce.ttf | Bin 0 -> 9860 bytes .../js/skins/lightgray/fonts/tinymce.woff | Bin 0 -> 7664 bytes .../data/js/skins/lightgray/img/anchor.gif | Bin 0 -> 53 bytes .../data/js/skins/lightgray/img/loader.gif | Bin 0 -> 2608 bytes .../data/js/skins/lightgray/img/object.gif | Bin 0 -> 152 bytes .../data/js/skins/lightgray/img/trans.gif | Bin 0 -> 43 bytes .../data/js/skins/lightgray/skin.ie7.min.css | 1 + .../test/data/js/skins/lightgray/skin.min.css | 1 + .../test/data/js/themes/modern/theme.min.js | 1 + .../lib/test/data/js/tinymce.min.js | 10 + .../data/key_tests/remove_on_keypress.html | 36 + .../lib/test/data/keyboard_shortcut.html | 36 + .../lib/test/data/linked_image.html | 16 + .../boolean_attribute_selected.html | 13 + .../boolean_attribute_selected_html4.html | 13 + .../lib/test/data/longContentPage.html | 55 + .../lib/test/data/macbeth.html | 5255 +++++++++++++++++ .../selenium-webdriver/lib/test/data/map.png | Bin 0 -> 26209 bytes .../lib/test/data/map_visibility.html | 8 + .../lib/test/data/markerTransparent.png | Bin 0 -> 260 bytes .../lib/test/data/messages.html | 15 + .../lib/test/data/meta-redirect.html | 11 + .../lib/test/data/missedJsReference.html | 11 + .../lib/test/data/modal_dialogs/modal_1.html | 21 + .../lib/test/data/modal_dialogs/modal_2.html | 21 + .../lib/test/data/modal_dialogs/modal_3.html | 15 + .../test/data/modal_dialogs/modalindex.html | 21 + .../lib/test/data/mouseOver.html | 17 + .../lib/test/data/mousePositionTracker.html | 33 + .../lib/test/data/nestedElements.html | 155 + .../lib/test/data/overflow-body.html | 15 + .../lib/test/data/overflow/x_auto_y_auto.html | 30 + .../test/data/overflow/x_auto_y_hidden.html | 30 + .../test/data/overflow/x_auto_y_scroll.html | 30 + .../test/data/overflow/x_hidden_y_auto.html | 30 + .../test/data/overflow/x_hidden_y_hidden.html | 30 + .../test/data/overflow/x_hidden_y_scroll.html | 30 + .../test/data/overflow/x_scroll_y_auto.html | 30 + .../test/data/overflow/x_scroll_y_hidden.html | 30 + .../test/data/overflow/x_scroll_y_scroll.html | 30 + .../data/pageWithOnBeforeUnloadMessage.html | 20 + .../lib/test/data/pageWithOnLoad.html | 6 + .../lib/test/data/pageWithOnUnload.html | 6 + .../page_with_link_to_slow_loading_page.html | 6 + .../lib/test/data/plain.txt | 1 + .../lib/test/data/proxy/page1.html | 20 + .../lib/test/data/proxy/page2.html | 24 + .../lib/test/data/proxy/page3.html | 5 + .../lib/test/data/readOnlyPage.html | 22 + .../lib/test/data/rectangles.html | 40 + .../lib/test/data/resultPage.html | 25 + .../lib/test/data/rich_text.html | 161 + .../test/data/safari/frames_benchmark.html | 31 + .../lib/test/data/screen/screen.css | 19 + .../lib/test/data/screen/screen.html | 72 + .../lib/test/data/screen/screen.js | 7 + .../lib/test/data/screen/screen_frame1.html | 72 + .../lib/test/data/screen/screen_frame2.html | 72 + .../lib/test/data/screen/screen_frames.html | 11 + .../lib/test/data/screen/screen_iframes.html | 12 + .../lib/test/data/screen/screen_too_long.html | 68 + .../lib/test/data/screen/screen_x_long.html | 72 + .../test/data/screen/screen_x_too_long.html | 72 + .../lib/test/data/screen/screen_y_long.html | 72 + .../test/data/screen/screen_y_too_long.html | 72 + .../lib/test/data/scroll.html | 27 + .../lib/test/data/scroll2.html | 21 + .../lib/test/data/scroll3.html | 8 + .../lib/test/data/scroll4.html | 7 + .../lib/test/data/scroll5.html | 18 + .../frame_with_height_above_200.html | 26 + .../frame_with_height_above_2000.html | 26 + .../frame_with_nested_scrolling_frame.html | 11 + ...th_nested_scrolling_frame_out_of_view.html | 12 + .../frame_with_small_height.html | 10 + .../page_with_double_overflow_auto.html | 19 + .../page_with_frame_out_of_view.html | 12 + .../page_with_nested_scrolling_frames.html | 11 + ...h_nested_scrolling_frames_out_of_view.html | 12 + .../page_with_non_scrolling_frame.html | 11 + .../page_with_scrolling_frame.html | 11 + ...page_with_scrolling_frame_out_of_view.html | 12 + .../scrolling_tests/page_with_tall_frame.html | 11 + .../page_with_y_overflow_auto.html | 14 + .../data/scrolling_tests/target_page.html | 9 + .../lib/test/data/selectPage.html | 42 + .../lib/test/data/selectableItems.html | 65 + .../lib/test/data/sessionCookie.html | 21 + .../lib/test/data/sessionCookieDest.html | 34 + .../lib/test/data/simple.xml | 5 + .../lib/test/data/simpleTest.html | 97 + .../lib/test/data/slowLoadingAlert.html | 10 + .../test/data/slowLoadingResourcePage.html | 12 + .../lib/test/data/slow_loading_iframes.html | 14 + .../lib/test/data/styledPage.html | 28 + .../lib/test/data/svgPiechart.xhtml | 81 + .../lib/test/data/svgTest.svg | 4 + .../lib/test/data/tables.html | 36 + .../lib/test/data/tinymce.html | 10 + .../lib/test/data/transformable.xml | 11 + .../lib/test/data/transformable.xsl | 37 + .../lib/test/data/underscore.html | 9 + .../lib/test/data/unicode_ltr.html | 8 + .../lib/test/data/upload.html | 45 + .../lib/test/data/userDefinedProperty.html | 8 + .../lib/test/data/veryLargeCanvas.html | 81 + .../lib/test/data/visibility-css.html | 21 + .../lib/test/data/win32frameset.html | 8 + .../page_with_frame.html | 12 + .../window_switching_tests/simple_page.html | 9 + .../lib/test/data/xhtmlFormPage.xhtml | 17 + .../lib/test/data/xhtmlTest.html | 76 + .../selenium-webdriver/lib/test/fileserver.js | 469 ++ .../selenium-webdriver/lib/test/httpserver.js | 117 + .../selenium-webdriver/lib/test/index.js | 268 + .../selenium-webdriver/lib/test/resources.js | 42 + .../lib/test/seleniumserver.js | 81 + .../lib/webdriver/abstractbuilder.js | 122 + .../lib/webdriver/actionsequence.js | 356 ++ .../lib/webdriver/builder.js | 117 + .../lib/webdriver/button.js | 27 + .../lib/webdriver/capabilities.js | 318 + .../lib/webdriver/command.js | 240 + .../lib/webdriver/events.js | 176 + .../lib/webdriver/firefoxdomexecutor.js | 172 + .../lib/webdriver/http/corsclient.js | 130 + .../lib/webdriver/http/http.js | 462 ++ .../lib/webdriver/http/xhrclient.js | 64 + .../selenium-webdriver/lib/webdriver/key.js | 89 + .../lib/webdriver/locators.js | 253 + .../lib/webdriver/logging.js | 158 + .../lib/webdriver/process.js | 120 + .../lib/webdriver/promise.js | 2057 +++++++ .../lib/webdriver/session.js | 71 + .../lib/webdriver/stacktrace.js | 647 ++ .../lib/webdriver/testing/asserts.js | 485 ++ .../lib/webdriver/webdriver.js | 2132 +++++++ node_modules/selenium-webdriver/net/index.js | 80 + .../selenium-webdriver/net/portprober.js | 213 + node_modules/selenium-webdriver/package.json | 36 + node_modules/selenium-webdriver/phantomjs.js | 164 + node_modules/selenium-webdriver/proxy.js | 115 + .../selenium-webdriver/remote/index.js | 332 ++ .../test/chrome/options_test.js | 213 + .../selenium-webdriver/test/cookie_test.js | 198 + .../test/element_finding_test.js | 346 ++ .../selenium-webdriver/test/http/http_test.js | 88 + .../selenium-webdriver/test/http/util_test.js | 181 + .../test/net/portprober_test.js | 127 + .../test/page_loading_test.js | 152 + .../selenium-webdriver/test/proxy_test.js | 157 + .../test/stale_element_test.js | 63 + .../selenium-webdriver/test/tag_name_test.js | 29 + .../test/testing/index_test.js | 41 + .../selenium-webdriver/test/window_test.js | 107 + .../selenium-webdriver/testing/assert.js | 43 + .../selenium-webdriver/testing/index.js | 248 + package.json | 3 +- 577 files changed, 52138 insertions(+), 1 deletion(-) create mode 100644 node_modules/selenium-webdriver/CHANGES.md create mode 100644 node_modules/selenium-webdriver/COPYING create mode 100644 node_modules/selenium-webdriver/README.md create mode 100644 node_modules/selenium-webdriver/_base.js create mode 100644 node_modules/selenium-webdriver/builder.js create mode 100644 node_modules/selenium-webdriver/chrome.js create mode 100644 node_modules/selenium-webdriver/docs/class_bot_Error.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_Uri.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_Uri_QueryData.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_asserts_AssertionError.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_debug_Error.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_iter_GroupByIterator_.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_iter_Iterator.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_json_Serializer.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_AllOfMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_AnyOfMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_CloseToMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_ContainsStringMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_EndsWithMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_EqualToIgnoringWhitespaceMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_EqualToMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_EqualsMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_GreaterThanEqualToMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_GreaterThanMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_HasPropertyMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_InstanceOfMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsNotMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsNullMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsNullOrUndefinedMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsUndefinedMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_LessThanEqualToMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_LessThanMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_MatcherError.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_ObjectEqualsMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_RegexMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_StartsWithMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_labs_testing_StringContainsInOrderMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_net_DefaultXmlHttpFactory.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_net_WrapperXmlHttpFactory.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_net_XmlHttpFactory.html create mode 100644 node_modules/selenium-webdriver/docs/class_goog_structs_Map.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_AbstractBuilder.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_ActionSequence.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_Alert.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_Builder.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_Capabilities.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_Command.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_EventEmitter.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_FirefoxDomExecutor.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_Locator.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_Session.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_UnhandledAlertError.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_WebDriver.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Logs.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Navigation.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Options.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_TargetLocator.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Timeouts.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Window.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_WebElement.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_http_CorsClient.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_http_Executor.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_http_Request.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_http_Response.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_http_XhrClient.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_logging_Entry.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_promise_CanceledTaskError_.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_promise_ControlFlow.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_promise_Deferred.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_promise_Frame_.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_promise_Node_.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_promise_Promise.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_promise_Task_.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_stacktrace_Frame.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_stacktrace_Snapshot.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_testing_Assertion.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_testing_Assertion_DelegatingMatcher_.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_testing_ContainsMatcher.html create mode 100644 node_modules/selenium-webdriver/docs/class_webdriver_testing_NegatedAssertion.html create mode 100644 node_modules/selenium-webdriver/docs/dossier.css create mode 100644 node_modules/selenium-webdriver/docs/dossier.js create mode 100644 node_modules/selenium-webdriver/docs/enum_bot_ErrorCode.html create mode 100644 node_modules/selenium-webdriver/docs/enum_bot_Error_State.html create mode 100644 node_modules/selenium-webdriver/docs/enum_goog_dom_NodeType.html create mode 100644 node_modules/selenium-webdriver/docs/enum_goog_net_XmlHttp_OptionType.html create mode 100644 node_modules/selenium-webdriver/docs/enum_goog_net_XmlHttp_ReadyState.html create mode 100644 node_modules/selenium-webdriver/docs/enum_goog_string_Unicode.html create mode 100644 node_modules/selenium-webdriver/docs/enum_goog_uri_utils_CharCode_.html create mode 100644 node_modules/selenium-webdriver/docs/enum_goog_uri_utils_ComponentIndex.html create mode 100644 node_modules/selenium-webdriver/docs/enum_goog_uri_utils_StandardQueryParam.html create mode 100644 node_modules/selenium-webdriver/docs/enum_webdriver_Browser.html create mode 100644 node_modules/selenium-webdriver/docs/enum_webdriver_Button.html create mode 100644 node_modules/selenium-webdriver/docs/enum_webdriver_Capability.html create mode 100644 node_modules/selenium-webdriver/docs/enum_webdriver_CommandName.html create mode 100644 node_modules/selenium-webdriver/docs/enum_webdriver_FirefoxDomExecutor_Attribute_.html create mode 100644 node_modules/selenium-webdriver/docs/enum_webdriver_FirefoxDomExecutor_EventType_.html create mode 100644 node_modules/selenium-webdriver/docs/enum_webdriver_Key.html create mode 100644 node_modules/selenium-webdriver/docs/enum_webdriver_logging_Level.html create mode 100644 node_modules/selenium-webdriver/docs/enum_webdriver_logging_LevelName.html create mode 100644 node_modules/selenium-webdriver/docs/enum_webdriver_logging_Type.html create mode 100644 node_modules/selenium-webdriver/docs/enum_webdriver_promise_ControlFlow_EventType.html create mode 100644 node_modules/selenium-webdriver/docs/enum_webdriver_promise_Deferred_State_.html create mode 100644 node_modules/selenium-webdriver/docs/index.html create mode 100644 node_modules/selenium-webdriver/docs/interface_goog_labs_testing_Matcher.html create mode 100644 node_modules/selenium-webdriver/docs/interface_goog_net_XhrLike.html create mode 100644 node_modules/selenium-webdriver/docs/interface_webdriver_CommandExecutor.html create mode 100644 node_modules/selenium-webdriver/docs/interface_webdriver_http_Client.html create mode 100644 node_modules/selenium-webdriver/docs/license.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver__base.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_builder.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_builder_class_Builder.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_chrome.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_chrome_class_Options.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_chrome_class_ServiceBuilder.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_error.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_executors.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_http.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_http_class_HttpClient.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_http_util.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_io.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_net.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_net_portprober.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_phantomjs.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_proxy.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_remote.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_remote_class_DriverService.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_remote_class_SeleniumServer.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_testing.html create mode 100644 node_modules/selenium-webdriver/docs/module_selenium-webdriver_testing_assert.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_bot.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_bot_json.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_bot_response.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_bot_userAgent.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_array.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_asserts.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_debug.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_dom.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_functions.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_iter.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_json.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_labs.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_labs_testing.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent_browser.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent_engine.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent_util.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_math.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_net.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_net_XmlHttp.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_net_XmlHttpDefines.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_object.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_string.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_structs.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_uri.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_uri_utils.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_userAgent.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_goog_userAgent_product.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_webdriver.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_webdriver_By.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_webdriver_http.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_webdriver_logging.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_webdriver_process.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_webdriver_promise.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_webdriver_stacktrace.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_webdriver_testing.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_webdriver_testing_assert.html create mode 100644 node_modules/selenium-webdriver/docs/namespace_webdriver_testing_asserts.html create mode 100644 node_modules/selenium-webdriver/docs/source/_base.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/builder.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/chrome.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/error.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/executors.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/http/index.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/http/util.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/index.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/io/index.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/atoms/error.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/atoms/json.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/atoms/response.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/atoms/userAgent.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/array/array.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/asserts/asserts.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/base.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/debug/error.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/deps.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/dom/nodetype.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/functions/functions.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/iter/iter.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/json/json.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/assertthat.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/logicmatcher.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/matcher.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/numbermatcher.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/objectmatcher.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/stringmatcher.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/labs/useragent/browser.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/labs/useragent/engine.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/labs/useragent/util.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/math/math.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/net/xhrlike.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/net/xmlhttp.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/net/xmlhttpfactory.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/object/object.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/string/string.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/structs/map.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/structs/structs.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/uri/uri.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/uri/utils.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/useragent/product.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/useragent/product_isversion.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/goog/useragent/useragent.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/abstractbuilder.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/actionsequence.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/builder.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/button.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/capabilities.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/command.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/events.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/firefoxdomexecutor.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/http/corsclient.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/http/http.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/http/xhrclient.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/key.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/locators.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/logging.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/process.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/promise.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/session.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/stacktrace.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/testing/asserts.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/lib/webdriver/webdriver.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/net/index.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/net/portprober.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/phantomjs.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/proxy.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/remote/index.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/testing/assert.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/source/testing/index.js.src.html create mode 100644 node_modules/selenium-webdriver/docs/types.js create mode 100644 node_modules/selenium-webdriver/error.js create mode 100644 node_modules/selenium-webdriver/example/google_search.js create mode 100644 node_modules/selenium-webdriver/example/google_search_test.js create mode 100644 node_modules/selenium-webdriver/executors.js create mode 100644 node_modules/selenium-webdriver/http/index.js create mode 100644 node_modules/selenium-webdriver/http/util.js create mode 100644 node_modules/selenium-webdriver/index.js create mode 100644 node_modules/selenium-webdriver/io/index.js create mode 100644 node_modules/selenium-webdriver/lib/README create mode 100644 node_modules/selenium-webdriver/lib/atoms/error.js create mode 100644 node_modules/selenium-webdriver/lib/atoms/json.js create mode 100644 node_modules/selenium-webdriver/lib/atoms/response.js create mode 100644 node_modules/selenium-webdriver/lib/atoms/userAgent.js create mode 100644 node_modules/selenium-webdriver/lib/goog/LICENSE create mode 100644 node_modules/selenium-webdriver/lib/goog/array/array.js create mode 100644 node_modules/selenium-webdriver/lib/goog/asserts/asserts.js create mode 100644 node_modules/selenium-webdriver/lib/goog/base.js create mode 100644 node_modules/selenium-webdriver/lib/goog/debug/error.js create mode 100644 node_modules/selenium-webdriver/lib/goog/deps.js create mode 100644 node_modules/selenium-webdriver/lib/goog/dom/nodetype.js create mode 100644 node_modules/selenium-webdriver/lib/goog/functions/functions.js create mode 100644 node_modules/selenium-webdriver/lib/goog/iter/iter.js create mode 100644 node_modules/selenium-webdriver/lib/goog/json/json.js create mode 100644 node_modules/selenium-webdriver/lib/goog/labs/testing/assertthat.js create mode 100644 node_modules/selenium-webdriver/lib/goog/labs/testing/logicmatcher.js create mode 100644 node_modules/selenium-webdriver/lib/goog/labs/testing/matcher.js create mode 100644 node_modules/selenium-webdriver/lib/goog/labs/testing/numbermatcher.js create mode 100644 node_modules/selenium-webdriver/lib/goog/labs/testing/objectmatcher.js create mode 100644 node_modules/selenium-webdriver/lib/goog/labs/testing/stringmatcher.js create mode 100644 node_modules/selenium-webdriver/lib/goog/labs/useragent/browser.js create mode 100644 node_modules/selenium-webdriver/lib/goog/labs/useragent/engine.js create mode 100644 node_modules/selenium-webdriver/lib/goog/labs/useragent/util.js create mode 100644 node_modules/selenium-webdriver/lib/goog/math/math.js create mode 100644 node_modules/selenium-webdriver/lib/goog/net/wrapperxmlhttpfactory.js create mode 100644 node_modules/selenium-webdriver/lib/goog/net/xhrlike.js create mode 100644 node_modules/selenium-webdriver/lib/goog/net/xmlhttp.js create mode 100644 node_modules/selenium-webdriver/lib/goog/net/xmlhttpfactory.js create mode 100644 node_modules/selenium-webdriver/lib/goog/object/object.js create mode 100644 node_modules/selenium-webdriver/lib/goog/string/string.js create mode 100644 node_modules/selenium-webdriver/lib/goog/structs/map.js create mode 100644 node_modules/selenium-webdriver/lib/goog/structs/structs.js create mode 100644 node_modules/selenium-webdriver/lib/goog/uri/uri.js create mode 100644 node_modules/selenium-webdriver/lib/goog/uri/utils.js create mode 100644 node_modules/selenium-webdriver/lib/goog/useragent/product.js create mode 100644 node_modules/selenium-webdriver/lib/goog/useragent/product_isversion.js create mode 100644 node_modules/selenium-webdriver/lib/goog/useragent/useragent.js create mode 100644 node_modules/selenium-webdriver/lib/test/build.js create mode 100644 node_modules/selenium-webdriver/lib/test/data/ClickTest_testClicksASurroundingStrongTag.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/Page.aspx create mode 100644 node_modules/selenium-webdriver/lib/test/data/Page.aspx.cs create mode 100644 node_modules/selenium-webdriver/lib/test/data/Redirect.aspx create mode 100644 node_modules/selenium-webdriver/lib/test/data/Redirect.aspx.cs create mode 100644 node_modules/selenium-webdriver/lib/test/data/Settings.StyleCop create mode 100644 node_modules/selenium-webdriver/lib/test/data/Web.Config create mode 100644 node_modules/selenium-webdriver/lib/test/data/actualXhtmlPage.xhtml create mode 100644 node_modules/selenium-webdriver/lib/test/data/ajaxy_page.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/alerts.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/banner.gif create mode 100644 node_modules/selenium-webdriver/lib/test/data/beach.jpg create mode 100644 node_modules/selenium-webdriver/lib/test/data/blank.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/bodyTypingTest.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/booleanAttributes.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/child/childPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/child/grandchild/grandchildPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/clickEventPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_frames.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_jacker.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds_overflow.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_rtl.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_source.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/click_iframe.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/click_in_iframe.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/google_map.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/google_map.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/html5_submit_buttons.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_frame.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_target.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/link_that_wraps.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page1.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page2.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page3.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/span_that_wraps.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_tests/submitted_page.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_too_big.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/click_too_big_in_frame.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/clicks.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/closeable_window.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/cn-test.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/colorPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/cookies.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_frame.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_nested_frame.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_element_out_of_view.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_empty_element.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_fixed_element.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_hidden_element.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_invisible_element.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_transparent_element.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/coordinates_tests/simple_page.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_222222_256x240.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_228ef1_256x240.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ef8c08_256x240.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffd27a_256x240.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffffff_256x240.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/jquery-ui-1.8.10.custom.css create mode 100644 node_modules/selenium-webdriver/lib/test/data/cssTransform.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/cssTransform2.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/document_write_in_onload.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/dragAndDropInsideScrolledDiv.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/dragAndDropTest.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/dragDropOverflow.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/draggableLists.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/droppableItems.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/dynamic.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/dynamicallyModifiedPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/errors.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScroll.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScrollQuirksMode.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/formPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/formSelectionPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/form_handling_js_submit.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/framePage3.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/frameScrollChild.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/frameScrollPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/frameScrollParent.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876_iframe.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe2.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/frameset.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/framesetPage2.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/framesetPage3.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/globalscope.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/hidden.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/html5/blue.jpg create mode 100644 node_modules/selenium-webdriver/lib/test/data/html5/database.js create mode 100644 node_modules/selenium-webdriver/lib/test/data/html5/geolocation.js create mode 100644 node_modules/selenium-webdriver/lib/test/data/html5/green.jpg create mode 100644 node_modules/selenium-webdriver/lib/test/data/html5/red.jpg create mode 100644 node_modules/selenium-webdriver/lib/test/data/html5/status.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/html5/test.appcache create mode 100644 node_modules/selenium-webdriver/lib/test/data/html5/yellow.jpg create mode 100644 node_modules/selenium-webdriver/lib/test/data/html5Page.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/icon.gif create mode 100644 node_modules/selenium-webdriver/lib/test/data/iframeAtBottom.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/iframeWithAlert.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/iframeWithIframe.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/iframes.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/injectableContent.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/javascriptEnhancedForm.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/javascriptPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/jquery-1.3.2.js create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/jquery-1.4.4.min.js create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/jquery-ui-1.8.10.custom.min.js create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.inline.min.css create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.min.css create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/readme.md create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.dev.svg create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.eot create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.svg create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.ttf create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.woff create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.dev.svg create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.eot create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.svg create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.ttf create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.woff create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/anchor.gif create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/loader.gif create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/object.gif create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/trans.gif create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.ie7.min.css create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.min.css create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/themes/modern/theme.min.js create mode 100644 node_modules/selenium-webdriver/lib/test/data/js/tinymce.min.js create mode 100644 node_modules/selenium-webdriver/lib/test/data/key_tests/remove_on_keypress.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/keyboard_shortcut.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/linked_image.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected_html4.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/longContentPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/macbeth.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/map.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/map_visibility.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/markerTransparent.png create mode 100644 node_modules/selenium-webdriver/lib/test/data/messages.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/meta-redirect.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/missedJsReference.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_1.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_2.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_3.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modalindex.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/mouseOver.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/mousePositionTracker.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/nestedElements.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/overflow-body.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_auto.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_hidden.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_scroll.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_auto.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_hidden.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_scroll.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_auto.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_hidden.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_scroll.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/pageWithOnBeforeUnloadMessage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/pageWithOnLoad.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/pageWithOnUnload.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/page_with_link_to_slow_loading_page.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/plain.txt create mode 100644 node_modules/selenium-webdriver/lib/test/data/proxy/page1.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/proxy/page2.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/proxy/page3.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/readOnlyPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/rectangles.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/resultPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/rich_text.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/safari/frames_benchmark.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/screen/screen.css create mode 100644 node_modules/selenium-webdriver/lib/test/data/screen/screen.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/screen/screen.js create mode 100644 node_modules/selenium-webdriver/lib/test/data/screen/screen_frame1.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/screen/screen_frame2.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/screen/screen_frames.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/screen/screen_iframes.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/screen/screen_too_long.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/screen/screen_x_long.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/screen/screen_x_too_long.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/screen/screen_y_long.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/screen/screen_y_too_long.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scroll.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scroll2.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scroll3.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scroll4.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scroll5.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_200.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_2000.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_small_height.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_double_overflow_auto.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_frame_out_of_view.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_non_scrolling_frame.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame_out_of_view.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_tall_frame.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_y_overflow_auto.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/scrolling_tests/target_page.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/selectPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/selectableItems.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/sessionCookie.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/sessionCookieDest.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/simple.xml create mode 100644 node_modules/selenium-webdriver/lib/test/data/simpleTest.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/slowLoadingAlert.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/slowLoadingResourcePage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/slow_loading_iframes.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/styledPage.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/svgPiechart.xhtml create mode 100644 node_modules/selenium-webdriver/lib/test/data/svgTest.svg create mode 100644 node_modules/selenium-webdriver/lib/test/data/tables.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/tinymce.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/transformable.xml create mode 100644 node_modules/selenium-webdriver/lib/test/data/transformable.xsl create mode 100644 node_modules/selenium-webdriver/lib/test/data/underscore.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/unicode_ltr.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/upload.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/userDefinedProperty.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/veryLargeCanvas.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/visibility-css.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/win32frameset.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/window_switching_tests/page_with_frame.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/window_switching_tests/simple_page.html create mode 100644 node_modules/selenium-webdriver/lib/test/data/xhtmlFormPage.xhtml create mode 100644 node_modules/selenium-webdriver/lib/test/data/xhtmlTest.html create mode 100644 node_modules/selenium-webdriver/lib/test/fileserver.js create mode 100644 node_modules/selenium-webdriver/lib/test/httpserver.js create mode 100644 node_modules/selenium-webdriver/lib/test/index.js create mode 100644 node_modules/selenium-webdriver/lib/test/resources.js create mode 100644 node_modules/selenium-webdriver/lib/test/seleniumserver.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/abstractbuilder.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/actionsequence.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/builder.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/button.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/capabilities.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/command.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/events.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/firefoxdomexecutor.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/http/corsclient.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/http/http.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/http/xhrclient.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/key.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/locators.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/logging.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/process.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/promise.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/session.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/stacktrace.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/testing/asserts.js create mode 100644 node_modules/selenium-webdriver/lib/webdriver/webdriver.js create mode 100644 node_modules/selenium-webdriver/net/index.js create mode 100644 node_modules/selenium-webdriver/net/portprober.js create mode 100644 node_modules/selenium-webdriver/package.json create mode 100644 node_modules/selenium-webdriver/phantomjs.js create mode 100644 node_modules/selenium-webdriver/proxy.js create mode 100644 node_modules/selenium-webdriver/remote/index.js create mode 100644 node_modules/selenium-webdriver/test/chrome/options_test.js create mode 100644 node_modules/selenium-webdriver/test/cookie_test.js create mode 100644 node_modules/selenium-webdriver/test/element_finding_test.js create mode 100644 node_modules/selenium-webdriver/test/http/http_test.js create mode 100644 node_modules/selenium-webdriver/test/http/util_test.js create mode 100644 node_modules/selenium-webdriver/test/net/portprober_test.js create mode 100644 node_modules/selenium-webdriver/test/page_loading_test.js create mode 100644 node_modules/selenium-webdriver/test/proxy_test.js create mode 100644 node_modules/selenium-webdriver/test/stale_element_test.js create mode 100644 node_modules/selenium-webdriver/test/tag_name_test.js create mode 100644 node_modules/selenium-webdriver/test/testing/index_test.js create mode 100644 node_modules/selenium-webdriver/test/window_test.js create mode 100644 node_modules/selenium-webdriver/testing/assert.js create mode 100644 node_modules/selenium-webdriver/testing/index.js diff --git a/node_modules/selenium-webdriver/CHANGES.md b/node_modules/selenium-webdriver/CHANGES.md new file mode 100644 index 0000000..2d7c98d --- /dev/null +++ b/node_modules/selenium-webdriver/CHANGES.md @@ -0,0 +1,169 @@ +## v2.42.1 + +* FIXED: 7465: Fixed `net.getLoopbackAddress` on Windows +* FIXED: 7277: Support `done` callback in Mocha's BDD interface +* FIXED: 7156: `Promise#thenFinally` should not suppress original error + +## v2.42.0 + +* Removed deprecated functions `Promise#addCallback()`, + `Promise#addCallbacks()`, `Promise#addErrback()`, and `Promise#addBoth()`. +* Fail with a more descriptive error if the server returns a malformed redirect +* FIXED: 7300: Connect to ChromeDriver using the loopback address since + ChromeDriver 2.10.267517 binds to localhost by default. +* FIXED: 7339: Preserve wrapped test function's string representation for + Mocha's BDD interface. + +## v2.41.0 + +* FIXED: 7138: export logging API from webdriver module. +* FIXED: 7105: beforeEach/it/afterEach properly bind `this` for Mocha tests. + +## v2.40.0 + +* API documentation is now included in the docs directory. +* Added utility functions for working with an array of promises: + `promise.all`, `promise.map`, and `promise.filter` +* Introduced `Promise#thenCatch()` and `Promise#thenFinally()`. +* Deprecated `Promise#addCallback()`, `Promise#addCallbacks()`, + `Promise#addErrback()`, and `Promise#addBoth()`. +* Removed deprecated function `webdriver.WebDriver#getCapability`. +* FIXED: 6826: Added support for custom locators. + +## v2.39.0 + +* Version bump to stay in sync with the Selenium project. + +## v2.38.1 + +* FIXED: 6686: Changed `webdriver.promise.Deferred#cancel()` to silently no-op + if the deferred has already been resolved. + +## v2.38.0 + +* When a promise is rejected, always annotate the stacktrace with the parent + flow state so users can identify the source of an error. +* Updated tests to reflect features not working correctly in the SafariDriver + (cookie management and proxy support; see issues 5051, 5212, and 5503) +* FIXED: 6284: For mouse moves, correctly omit the x/y offsets if not + specified as a function argument (instead of passing (0,0)). +* FIXED: 6471: Updated documentation on `webdriver.WebElement#getAttribute` +* FIXED: 6612: On Unix, use the default IANA ephemeral port range if unable to + retrieve the current system's port range. +* FIXED: 6617: Avoid triggering the node debugger when initializing the + stacktrace module. +* FIXED: 6627: Safely rebuild chrome.Options from a partial JSON spec. + +## v2.37.0 + +* FIXED: 6346: The remote.SeleniumServer class now accepts JVM arguments using + the `jvmArgs` option. + +## v2.36.0 + +* _Release skipped to stay in sync with main Selenium project._ + +## v2.35.2 + +* FIXED: 6200: Pass arguments to the Selenium server instead of to the JVM. + +## v2.35.1 + +* FIXED: 6090: Changed example scripts to use chromedriver. + +## v2.35.0 + +* Version bump to stay in sync with the Selenium project. + +## v2.34.1 + +* FIXED: 6079: The parent process should not wait for spawn driver service + processes (chromedriver, phantomjs, etc.) + +## v2.34.0 + +* Added the `selenium-webdriver/testing/assert` module. This module + simplifies writing assertions against promised values (see + example in module documentation). +* Added the `webdriver.Capabilities` class. +* Added native support for the ChromeDriver. When using the `Builder`, + requesting chrome without specifying a remote server URL will default to + the native ChromeDriver implementation. The + [ChromeDriver server](https://code.google.com/p/chromedriver/downloads/list) + must be downloaded separately. + + // Will start ChromeDriver locally. + var driver = new webdriver.Builder(). + withCapabilities(webdriver.Capabilities.chrome()). + build(); + + // Will start ChromeDriver using the remote server. + var driver = new webdriver.Builder(). + withCapabilities(webdriver.Capabilities.chrome()). + usingServer('http://server:1234/wd/hub'). + build(); + +* Added support for configuring proxies through the builder. For examples, see + `selenium-webdriver/test/proxy_test`. +* Added native support for PhantomJS. +* Changed signature of `SeleniumServer` to `SeleniumServer(jar, options)`. +* Tests are now included in the npm published package. See `README.md` for + execution instructions +* Removed the deprecated `webdriver.Deferred#resolve` and + `webdriver.promise.resolved` functions. +* Removed the ability to connect to an existing session from the Builder. This + feature is intended for use with the browser-based client. + +## v2.33.0 + +* Added support for WebDriver's logging API +* FIXED: 5511: Added webdriver.manage().timeouts().pageLoadTimeout(ms) + +## v2.32.1 + +* FIXED: 5541: Added missing return statement for windows in + `portprober.findFreePort()` + +## v2.32.0 + +* Added the `selenium-webdriver/testing` package, which provides a basic + framework for writing tests using Mocha. See + `selenium-webdriver/example/google_search_test.js` for usage. +* For Promises/A+ compatibility, backing out the change in 2.30.0 that ensured + rejections were always Error objects. Rejection reasons are now left as is. +* Removed deprecated functions originally scheduled for removal in 2.31.0 + * promise.Application.getInstance() + * promise.ControlFlow#schedule() + * promise.ControlFlow#scheduleTimeout() + * promise.ControlFlow#scheduleWait() +* Renamed some functions for consistency with Promises/A+ terminology. The + original functions have been deprecated and will be removed in 2.34.0: + * promise.resolved() -> promise.fulfilled() + * promise.Deferred#resolve() -> promise.Deferred#fulfill() +* FIXED: remote.SeleniumServer#stop now shuts down within the active control + flow, allowing scripts to finish. Use #kill to shutdown immediately. +* FIXED: 5321: cookie deletion commands + +## v2.31.0 + +* Added an example script. +* Added a class for controlling the standalone Selenium server (server +available separately) +* Added a portprober for finding free ports +* FIXED: WebElements now belong to the same flow as their parent driver. + +## v2.30.0 + +* Ensures promise rejections are always Error values. +* Version bump to keep in sync with the Selenium project. + +## v2.29.1 + +* Fixed a bug that could lead to an infinite loop. +* Added a README.md + +## v2.29.0 + +* Initial release for npm: + + npm install selenium-webdriver diff --git a/node_modules/selenium-webdriver/COPYING b/node_modules/selenium-webdriver/COPYING new file mode 100644 index 0000000..80a4762 --- /dev/null +++ b/node_modules/selenium-webdriver/COPYING @@ -0,0 +1,204 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2007-2009 Google Inc. + Copyright 2007-2009 WebDriver committers + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/node_modules/selenium-webdriver/README.md b/node_modules/selenium-webdriver/README.md new file mode 100644 index 0000000..1f954bf --- /dev/null +++ b/node_modules/selenium-webdriver/README.md @@ -0,0 +1,77 @@ +# selenium-webdriver + +## Installation + +Install the latest published version using `npm`: + + npm install selenium-webdriver + +In addition to the npm package, you will to download the WebDriver +implementations you wish to utilize. As of 2.34.0, `selenium-webdriver` +natively supports the [ChromeDriver](http://chromedriver.storage.googleapis.com/index.html). +Simply download a copy and make sure it can be found on your `PATH`. The other +drivers (e.g. Firefox, Internet Explorer, and Safari), still require the +[standalone Selenium server](http://selenium-release.storage.googleapis.com/index.html). + +### Running the tests + +To run the tests, you will need to download a copy of the +[ChromeDriver](http://chromedriver.storage.googleapis.com/index.html) and make +sure it can be found on your `PATH`. + + npm test selenium-webdriver + +To run the tests against multiple browsers, download the +[Selenium server](http://selenium-release.storage.googleapis.com/index.html) and +specify its location through the `SELENIUM_SERVER_JAR` environment variable. +You can use the `SELENIUM_BROWSER` environment variable to define a +comma-separated list of browsers you wish to test against. For example: + + export SELENIUM_SERVER_JAR=path/to/selenium-server-standalone-2.33.0.jar + SELENIUM_BROWSER=chrome,firefox npm test selenium-webdriver + +## Usage + + + var webdriver = require('selenium-webdriver'); + + var driver = new webdriver.Builder(). + withCapabilities(webdriver.Capabilities.chrome()). + build(); + + driver.get('http://www.google.com'); + driver.findElement(webdriver.By.name('q')).sendKeys('webdriver'); + driver.findElement(webdriver.By.name('btnG')).click(); + driver.wait(function() { + return driver.getTitle().then(function(title) { + return title === 'webdriver - Google Search'; + }); + }, 1000); + + driver.quit(); + +## Documentation + +API documentation is included in the docs module. The API documentation for the +current release are also available online from the [Selenium project](http://selenium.googlecode.com/git/docs/api/javascript/index.html "API docs"). A full user guide is available on the +[Selenium project wiki](http://code.google.com/p/selenium/wiki/WebDriverJs "User guide"). + +## Issues + +Please report any issues using the [Selenium issue tracker](https://code.google.com/p/selenium/issues/list). + +## License + +Copyright 2009-2014 Software Freedom Conservancy + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/node_modules/selenium-webdriver/_base.js b/node_modules/selenium-webdriver/_base.js new file mode 100644 index 0000000..6048179 --- /dev/null +++ b/node_modules/selenium-webdriver/_base.js @@ -0,0 +1,165 @@ +// Copyright 2012 Selenium committers +// Copyright 2012 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview The base module responsible for bootstrapping the Closure + * library and providing a means of loading Closure-based modules. + * + *

Each script loaded by this module will be granted access to this module's + * {@code require} function; all required non-native modules must be specified + * relative to this module. + * + *

This module will load all scripts from the "lib" subdirectory, unless the + * SELENIUM_DEV_MODE environment variable has been set to 1, in which case all + * scripts will be loaded from the Selenium client containing this script. + */ + +'use strict'; + +var fs = require('fs'), + path = require('path'), + vm = require('vm'); + + +/** + * If this script was loaded from the Selenium project repo, it will operate in + * development mode, adjusting how it loads Closure-based dependencies. + * @type {boolean} + */ +var devMode = (function() { + var buildDescFile = path.join(__dirname, '..', 'build.desc'); + return fs.existsSync(buildDescFile); +})(); + + +/** @return {boolean} Whether this script was loaded in dev mode. */ +function isDevMode() { + return devMode; +} + + +/** + * @type {string} Path to Closure's base file, relative to this module. + * @const + */ +var CLOSURE_BASE_FILE_PATH = (function() { + var relativePath = isDevMode() ? + '../../../third_party/closure/goog/base.js' : + './lib/goog/base.js'; + return path.join(__dirname, relativePath); +})(); + + +/** + * @type {string} Path to Closure's base file, relative to this module. + * @const + */ +var DEPS_FILE_PATH = (function() { + var relativePath = isDevMode() ? + '../../../javascript/deps.js' : + './lib/goog/deps.js'; + return path.join(__dirname, relativePath); +})(); + + + +/** + * Synchronously loads a script into the protected Closure context. + * @param {string} src Path to the file to load. + */ +function loadScript(src) { + src = path.normalize(src); + var contents = fs.readFileSync(src, 'utf8'); + vm.runInContext(contents, closure, src); +} + + +/** + * The protected context to host the Closure library. + * @type {!Object} + * @const + */ +var closure = vm.createContext({ + console: console, + setTimeout: setTimeout, + setInterval: setInterval, + clearTimeout: clearTimeout, + clearInterval: clearInterval, + process: process, + require: require, + Buffer: Buffer, + Error: Error, + CLOSURE_BASE_PATH: path.dirname(CLOSURE_BASE_FILE_PATH) + '/', + CLOSURE_IMPORT_SCRIPT: function(src) { + loadScript(src); + return true; + }, + CLOSURE_NO_DEPS: !isDevMode(), + goog: {} +}); +closure.window = closure; + + +loadScript(CLOSURE_BASE_FILE_PATH); +loadScript(DEPS_FILE_PATH); + + +/** + * Loads a symbol by name from the protected Closure context. + * @param {string} symbol The symbol to load. + * @return {?} The loaded symbol, or {@code null} if not found. + * @throws {Error} If the symbol has not been defined. + */ +function closureRequire(symbol) { + closure.goog.require(symbol); + return closure.goog.getObjectByName(symbol); +} + + +// PUBLIC API + + +/** + * Loads a symbol by name from the protected Closure context and exports its + * public API to the provided object. This function relies on Closure code + * conventions to define the public API of an object as those properties whose + * name does not end with "_". + * @param {string} symbol The symbol to load. This must resolve to an object. + * @return {!Object} An object with the exported API. + * @throws {Error} If the symbol has not been defined or does not resolve to + * an object. + */ +exports.exportPublicApi = function(symbol) { + var src = closureRequire(symbol); + if (typeof src != 'object' || src === null) { + throw Error('"' + symbol + '" must resolve to an object'); + } + + var dest = {}; + Object.keys(src).forEach(function(key) { + if (key[key.length - 1] != '_') { + dest[key] = src[key]; + } + }); + + return dest; +}; + + +if (isDevMode()) { + exports.closure = closure; +} +exports.isDevMode = isDevMode; +exports.require = closureRequire; diff --git a/node_modules/selenium-webdriver/builder.js b/node_modules/selenium-webdriver/builder.js new file mode 100644 index 0000000..fc2f40b --- /dev/null +++ b/node_modules/selenium-webdriver/builder.js @@ -0,0 +1,113 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var base = require('./_base'), + executors = require('./executors'); + +var goog = base.require('goog'), + AbstractBuilder = base.require('webdriver.AbstractBuilder'), + Browser = base.require('webdriver.Browser'), + Capability = base.require('webdriver.Capability'), + WebDriver = base.require('webdriver.WebDriver'), + promise = base.require('webdriver.promise'); + + +/** + * @param {!webdriver.Capabilities} capabilities The desired capabilities. + * @return {webdriver.WebDriver} A new WebDriver instance or {@code null} + * if the requested browser is not natively supported in Node. + */ +function createNativeDriver(capabilities) { + switch (capabilities.get(Capability.BROWSER_NAME)) { + case Browser.CHROME: + // Requiring 'chrome' above would create a cycle: + // index -> builder -> chrome -> index + var chrome = require('./chrome'); + return chrome.createDriver(capabilities); + + case Browser.PHANTOM_JS: + // Requiring 'phantomjs' would create a cycle: + // index -> builder -> phantomjs -> index + var phantomjs = require('./phantomjs'); + return phantomjs.createDriver(capabilities); + + default: + return null; + } +} + + + +/** + * Creates new {@link webdriver.WebDriver WebDriver} instances. + * @constructor + * @extends {webdriver.AbstractBuilder} + */ +var Builder = function() { + goog.base(this); +}; +goog.inherits(Builder, AbstractBuilder); + + +/** + * Sets the proxy configuration to use for WebDriver clients created by this + * builder. Any calls to {@link #withCapabilities} after this function will + * overwrite these settings. + * @param {!proxy.ProxyConfig} config The configuration to use. + * @return {!Builder} A self reference. + */ +Builder.prototype.setProxy = function(config) { + this.getCapabilities().set(Capability.PROXY, config); + return this; +}; + + +/** + * Sets Chrome-specific options for drivers created by this builder. + * @param {!chrome.Options} options The ChromeDriver options to use. + * @return {!Builder} A self reference. + */ +Builder.prototype.setChromeOptions = function(options) { + var newCapabilities = options.toCapabilities(this.getCapabilities()); + return /** @type {!Builder} */(this.withCapabilities(newCapabilities)); +}; + + +/** + * @override + */ +Builder.prototype.build = function() { + var url = this.getServerUrl(); + + // If a remote server wasn't specified, check for browsers we support + // natively in node before falling back to using the java Selenium server. + if (!url) { + var driver = createNativeDriver(this.getCapabilities()); + if (driver) { + return driver; + } + + // Nope, fall-back to using the default java server. + url = AbstractBuilder.DEFAULT_SERVER_URL; + } + + var executor = executors.createExecutor(url); + return WebDriver.createSession(executor, this.getCapabilities()); +}; + + +// PUBLIC API + + +exports.Builder = Builder; diff --git a/node_modules/selenium-webdriver/chrome.js b/node_modules/selenium-webdriver/chrome.js new file mode 100644 index 0000000..7e32873 --- /dev/null +++ b/node_modules/selenium-webdriver/chrome.js @@ -0,0 +1,473 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var fs = require('fs'), + util = require('util'); + +var webdriver = require('./index'), + executors = require('./executors'), + io = require('./io'), + portprober = require('./net/portprober'), + remote = require('./remote'); + + +/** + * Name of the ChromeDriver executable. + * @type {string} + * @const + */ +var CHROMEDRIVER_EXE = + process.platform === 'win32' ? 'chromedriver.exe' : 'chromedriver'; + + +/** + * Creates {@link remote.DriverService} instances that manage a ChromeDriver + * server. + * @param {string=} opt_exe Path to the server executable to use. If omitted, + * the builder will attempt to locate the chromedriver on the current + * PATH. + * @throws {Error} If provided executable does not exist, or the chromedriver + * cannot be found on the PATH. + * @constructor + */ +var ServiceBuilder = function(opt_exe) { + /** @private {string} */ + this.exe_ = opt_exe || io.findInPath(CHROMEDRIVER_EXE, true); + if (!this.exe_) { + throw Error( + 'The ChromeDriver could not be found on the current PATH. Please ' + + 'download the latest version of the ChromeDriver from ' + + 'http://chromedriver.storage.googleapis.com/index.html and ensure ' + + 'it can be found on your PATH.'); + } + + if (!fs.existsSync(this.exe_)) { + throw Error('File does not exist: ' + this.exe_); + } + + /** @private {!Array.} */ + this.args_ = []; + this.stdio_ = 'ignore'; +}; + + +/** @private {number} */ +ServiceBuilder.prototype.port_ = 0; + + +/** @private {(string|!Array.)} */ +ServiceBuilder.prototype.stdio_ = 'ignore'; + + +/** @private {Object.} */ +ServiceBuilder.prototype.env_ = null; + + +/** + * Sets the port to start the ChromeDriver on. + * @param {number} port The port to use, or 0 for any free port. + * @return {!ServiceBuilder} A self reference. + * @throws {Error} If the port is invalid. + */ +ServiceBuilder.prototype.usingPort = function(port) { + if (port < 0) { + throw Error('port must be >= 0: ' + port); + } + this.port_ = port; + return this; +}; + + +/** + * Sets the path of the log file the driver should log to. If a log file is + * not specified, the driver will log to stderr. + * @param {string} path Path of the log file to use. + * @return {!ServiceBuilder} A self reference. + */ +ServiceBuilder.prototype.loggingTo = function(path) { + this.args_.push('--log-path=' + path); + return this; +}; + + +/** + * Enables verbose logging. + * @return {!ServiceBuilder} A self reference. + */ +ServiceBuilder.prototype.enableVerboseLogging = function() { + this.args_.push('--verbose'); + return this; +}; + + +/** + * Sets the number of threads the driver should use to manage HTTP requests. + * By default, the driver will use 4 threads. + * @param {number} n The number of threads to use. + * @return {!ServiceBuilder} A self reference. + */ +ServiceBuilder.prototype.setNumHttpThreads = function(n) { + this.args_.push('--http-threads=' + n); + return this; +}; + + +/** + * Sets the base path for WebDriver REST commands (e.g. "/wd/hub"). + * By default, the driver will accept commands relative to "/". + * @param {string} path The base path to use. + * @return {!ServiceBuilder} A self reference. + */ +ServiceBuilder.prototype.setUrlBasePath = function(path) { + this.args_.push('--url-base=' + path); + return this; +}; + + +/** + * Defines the stdio configuration for the driver service. See + * {@code child_process.spawn} for more information. + * @param {(string|!Array.)} config The + * configuration to use. + * @return {!ServiceBuilder} A self reference. + */ +ServiceBuilder.prototype.setStdio = function(config) { + this.stdio_ = config; + return this; +}; + + +/** + * Defines the environment to start the server under. This settings will be + * inherited by every browser session started by the server. + * @param {!Object.} env The environment to use. + * @return {!ServiceBuilder} A self reference. + */ +ServiceBuilder.prototype.withEnvironment = function(env) { + this.env_ = env; + return this; +}; + + +/** + * Creates a new DriverService using this instance's current configuration. + * @return {remote.DriverService} A new driver service using this instance's + * current configuration. + * @throws {Error} If the driver exectuable was not specified and a default + * could not be found on the current PATH. + */ +ServiceBuilder.prototype.build = function() { + var port = this.port_ || portprober.findFreePort(); + var args = this.args_.concat(); // Defensive copy. + + return new remote.DriverService(this.exe_, { + loopback: true, + port: port, + args: webdriver.promise.when(port, function(port) { + return args.concat('--port=' + port); + }), + env: this.env_, + stdio: this.stdio_ + }); +}; + + +/** @type {remote.DriverService} */ +var defaultService = null; + + +/** + * Sets the default service to use for new ChromeDriver instances. + * @param {!remote.DriverService} service The service to use. + * @throws {Error} If the default service is currently running. + */ +function setDefaultService(service) { + if (defaultService && defaultService.isRunning()) { + throw Error( + 'The previously configured ChromeDriver service is still running. ' + + 'You must shut it down before you may adjust its configuration.'); + } + defaultService = service; +} + + +/** + * Returns the default ChromeDriver service. If such a service has not been + * configured, one will be constructed using the default configuration for + * a ChromeDriver executable found on the system PATH. + * @return {!remote.DriverService} The default ChromeDriver service. + */ +function getDefaultService() { + if (!defaultService) { + defaultService = new ServiceBuilder().build(); + } + return defaultService; +} + + +/** + * @type {string} + * @const + */ +var OPTIONS_CAPABILITY_KEY = 'chromeOptions'; + + +/** + * Class for managing ChromeDriver specific options. + * @constructor + */ +var Options = function() { + /** @private {!Array.} */ + this.args_ = []; + + /** @private {!Array.<(string|!Buffer)>} */ + this.extensions_ = []; +}; + + +/** + * Extracts the ChromeDriver specific options from the given capabilities + * object. + * @param {!webdriver.Capabilities} capabilities The capabilities object. + * @return {!Options} The ChromeDriver options. + */ +Options.fromCapabilities = function(capabilities) { + var options = new Options(); + + var o = capabilities.get(OPTIONS_CAPABILITY_KEY); + if (o instanceof Options) { + options = o; + } else if (o) { + options. + addArguments(o.args || []). + addExtensions(o.extensions || []). + detachDriver(!!o.detach). + setChromeBinaryPath(o.binary). + setChromeLogFile(o.logFile). + setLocalState(o.localState). + setUserPreferences(o.prefs); + } + + if (capabilities.has(webdriver.Capability.PROXY)) { + options.setProxy(capabilities.get(webdriver.Capability.PROXY)); + } + + if (capabilities.has(webdriver.Capability.LOGGING_PREFS)) { + options.setLoggingPreferences( + capabilities.get(webdriver.Capability.LOGGING_PREFS)); + } + + return options; +}; + + +/** + * Add additional command line arguments to use when launching the Chrome + * browser. Each argument may be specified with or without the "--" prefix + * (e.g. "--foo" and "foo"). Arguments with an associated value should be + * delimited by an "=": "foo=bar". + * @param {...(string|!Array.)} var_args The arguments to add. + * @return {!Options} A self reference. + */ +Options.prototype.addArguments = function(var_args) { + this.args_ = this.args_.concat.apply(this.args_, arguments); + return this; +}; + + +/** + * Add additional extensions to install when launching Chrome. Each extension + * should be specified as the path to the packed CRX file, or a Buffer for an + * extension. + * @param {...(string|!Buffer|!Array.<(string|!Buffer)>)} var_args The + * extensions to add. + * @return {!Options} A self reference. + */ +Options.prototype.addExtensions = function(var_args) { + this.extensions_ = this.extensions_.concat.apply( + this.extensions_, arguments); + return this; +}; + + +/** + * Sets the path to the Chrome binary to use. On Mac OS X, this path should + * reference the actual Chrome executable, not just the application binary + * (e.g. "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"). + * + * The binary path be absolute or relative to the chromedriver server + * executable, but it must exist on the machine that will launch Chrome. + * + * @param {string} path The path to the Chrome binary to use. + * @return {!Options} A self reference. + */ +Options.prototype.setChromeBinaryPath = function(path) { + this.binary_ = path; + return this; +}; + + +/** + * Sets whether to leave the started Chrome browser running if the controlling + * ChromeDriver service is killed before {@link webdriver.WebDriver#quit()} is + * called. + * @param {boolean} detach Whether to leave the browser running if the + * chromedriver service is killed before the session. + * @return {!Options} A self reference. + */ +Options.prototype.detachDriver = function(detach) { + this.detach_ = detach; + return this; +}; + + +/** + * Sets the user preferences for Chrome's user profile. See the "Preferences" + * file in Chrome's user data directory for examples. + * @param {!Object} prefs Dictionary of user preferences to use. + * @return {!Options} A self reference. + */ +Options.prototype.setUserPreferences = function(prefs) { + this.prefs_ = prefs; + return this; +}; + + +/** + * Sets the logging preferences for the new session. + * @param {!webdriver.logging.Preferences} prefs The logging preferences. + * @return {!Options} A self reference. + */ +Options.prototype.setLoggingPreferences = function(prefs) { + this.logPrefs_ = prefs; + return this; +}; + + +/** + * Sets preferences for the "Local State" file in Chrome's user data + * directory. + * @param {!Object} state Dictionary of local state preferences. + * @return {!Options} A self reference. + */ +Options.prototype.setLocalState = function(state) { + this.localState_ = state; + return this; +}; + + +/** + * Sets the path to Chrome's log file. This path should exist on the machine + * that will launch Chrome. + * @param {string} path Path to the log file to use. + * @return {!Options} A self reference. + */ +Options.prototype.setChromeLogFile = function(path) { + this.logFile_ = path; + return this; +}; + + +/** + * Sets the proxy settings for the new session. + * @param {ProxyConfig} proxy The proxy configuration to use. + * @return {!Options} A self reference. + */ +Options.prototype.setProxy = function(proxy) { + this.proxy_ = proxy; + return this; +}; + + +/** + * Converts this options instance to a {@link webdriver.Capabilities} object. + * @param {webdriver.Capabilities=} opt_capabilities The capabilities to merge + * these options into, if any. + * @return {!webdriver.Capabilities} The capabilities. + */ +Options.prototype.toCapabilities = function(opt_capabilities) { + var capabilities = opt_capabilities || webdriver.Capabilities.chrome(); + capabilities. + set(webdriver.Capability.PROXY, this.proxy_). + set(webdriver.Capability.LOGGING_PREFS, this.logPrefs_). + set(OPTIONS_CAPABILITY_KEY, this); + return capabilities; +}; + + +/** + * Converts this instance to its JSON wire protocol representation. Note this + * function is an implementation not intended for general use. + * @return {{args: !Array., + * binary: (string|undefined), + * detach: boolean, + * extensions: !Array., + * localState: (Object|undefined), + * logFile: (string|undefined), + * prefs: (Object|undefined)}} The JSON wire protocol representation + * of this instance. + */ +Options.prototype.toJSON = function() { + return { + args: this.args_, + binary: this.binary_, + detach: !!this.detach_, + extensions: this.extensions_.map(function(extension) { + if (Buffer.isBuffer(extension)) { + return extension.toString('base64'); + } + return fs.readFileSync(extension, 'base64'); + }), + localState: this.localState_, + logFile: this.logFile_, + prefs: this.prefs_ + }; +}; + + +/** + * Creates a new ChromeDriver session. + * @param {(webdriver.Capabilities|Options)=} opt_options The session options. + * @param {remote.DriverService=} opt_service The session to use; will use + * the {@link getDefaultService default service} by default. + * @return {!webdriver.WebDriver} A new WebDriver instance. + */ +function createDriver(opt_options, opt_service) { + var service = opt_service || getDefaultService(); + var executor = executors.createExecutor(service.start()); + + var options = opt_options || new Options(); + if (opt_options instanceof webdriver.Capabilities) { + // Extract the Chrome-specific options so we do not send unnecessary + // data across the wire. + options = Options.fromCapabilities(options); + } + + return webdriver.WebDriver.createSession( + executor, options.toCapabilities()); +} + + + +// PUBLIC API + + +exports.ServiceBuilder = ServiceBuilder; +exports.Options = Options; +exports.createDriver = createDriver; +exports.getDefaultService = getDefaultService; +exports.setDefaultService = setDefaultService; diff --git a/node_modules/selenium-webdriver/docs/class_bot_Error.html b/node_modules/selenium-webdriver/docs/class_bot_Error.html new file mode 100644 index 0000000..2171f78 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_bot_Error.html @@ -0,0 +1,6 @@ +bot.Error

Class bot.Error

code »
Error
+  └ bot.Error

Error extension that includes error status codes from the WebDriver wire + protocol: + http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes

Constructor

bot.Error ( code, opt_message )
Parameters
code: !bot.ErrorCode
The error's status code.
opt_message: string=
Optional error message.

Enumerations

bot.Error.State
Status strings enumerated in the W3C WebDriver working draft.
Show:

Instance Methods

Defined in bot.Error

Returns
he string representation of this error.

Instance Properties

Defined in bot.Error

Flag used for duck-typing when this code is embedded in a Firefox extension. + This is required since an Error thrown in one component and then reported + to another will fail instanceof checks in the second component.

Static Properties

A map of error codes to state string.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_Uri.html b/node_modules/selenium-webdriver/docs/class_goog_Uri.html new file mode 100644 index 0000000..37ab040 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_Uri.html @@ -0,0 +1,63 @@ +goog.Uri

Class goog.Uri

code »

This class contains setters and getters for the parts of the URI. + The getXyz/setXyz methods return the decoded part + -- sogoog.Uri.parse('/foo%20bar').getPath() will return the + decoded path, /foo bar. + + The constructor accepts an optional unparsed, raw URI string. The parser + is relaxed, so special characters that aren't escaped but don't cause + ambiguities will not cause parse failures. + + All setters return this and so may be chained, a la + goog.Uri.parse('/foo').setFragment('part').toString().

Constructor

goog.Uri ( opt_uri, opt_ignoreCase )
Parameters
opt_uri: *=
Optional string URI to parse + (use goog.Uri.create() to create a URI from parts), or if + a goog.Uri is passed, a clone is created.
opt_ignoreCase: boolean=
If true, #getParameterValue will ignore + the case of the parameter name.

Classes

goog.Uri.QueryData
Class used to represent URI query parameters.
Show:

Instance Methods

Clones the URI instance.

Returns
New instance of the URI object.

Checks if this Uri has been marked as read only, and if so, throws an error. + This should be called whenever any modifying function is called.

Returns
The decoded URI query, not including the ?.
Returns
The decoded domain.
Returns
The encoded URI query, not including the ?.
Returns
The URI fragment, not including the #.
Returns
Whether to ignore case.

Returns the first value for a given cgi parameter or undefined if the given + parameter name does not appear in the query string.

Parameters
paramName: string
Unescaped parameter name.
Returns
The first value for a given cgi parameter or + undefined if the given parameter name does not appear in the query + string.

Returns the values for a given cgi parameter as a list of decoded + query parameter values.

Parameters
name: string
The parameter to get values for.
Returns
The values for a given cgi parameter as a list of + decoded query parameter values.
Returns
The decoded path.
Returns
The port number.
Returns
The encoded URI query, not including the ?. + + Warning: This method, unlike other getter methods, returns encoded + value, instead of decoded one.

Returns the query data.

Returns
QueryData object.
Returns
The encoded scheme/protocol for the URI.
Returns
The decoded user info.
Returns
Whether the domain has been set.
Returns
Whether the URI has a fragment set.
Returns
Whether the path has been set.
Returns
Whether the port has been set.
Returns
Whether the query string has been set.

Returns true if this has the same domain as that of uri2.

Parameters
uri2: goog.Uri
The URI object to compare to.
Returns
true if same domain; false otherwise.
Returns
Whether the scheme has been set.
Returns
Whether the user info has been set.
Returns
Whether the URI is read only.

Adds a random parameter to the Uri.

Returns
Reference to this Uri object.

Removes the named query parameter.

Parameters
key: string
The parameter to remove.
Returns
Reference to this URI object.
code »resolve ( relativeUri )!goog.Uri

Resolves the given relative URI (a goog.Uri object), using the URI + represented by this instance as the base URI. + + There are several kinds of relative URIs:
+ 1. foo - replaces the last part of the path, the whole query and fragment
+ 2. /foo - replaces the the path, the query and fragment
+ 3. //foo - replaces everything from the domain on. foo is a domain name
+ 4. ?foo - replace the query and fragment
+ 5. #foo - replace the fragment only + + Additionally, if relative URI has a non-empty path, all ".." and "." + segments will be resolved, as described in RFC 3986.

Parameters
relativeUri: goog.Uri
The relative URI to resolve.
Returns
The resolved URI.
code »setDomain ( newDomain, opt_decode )!goog.Uri

Sets the domain.

Parameters
newDomain: string
New domain value.
opt_decode: boolean=
Optional param for whether to decode new value.
Returns
Reference to this URI object.
code »setFragment ( newFragment, opt_decode )!goog.Uri

Sets the URI fragment.

Parameters
newFragment: string
New fragment value.
opt_decode: boolean=
Optional param for whether to decode new value.
Returns
Reference to this URI object.
code »setIgnoreCase ( ignoreCase )!goog.Uri

Sets whether to ignore case. + NOTE: If there are already key/value pairs in the QueryData, and + ignoreCase_ is set to false, the keys will all be lower-cased.

Parameters
ignoreCase: boolean
whether this goog.Uri should ignore case.
Returns
Reference to this Uri object.

Sets the value of the named query parameters, clearing previous values for + that key.

Parameters
key: string
The parameter to set.
value: *
The new value.
Returns
Reference to this URI object.
code »setParameterValues ( key, values )!goog.Uri

Sets the values of the named query parameters, clearing previous values for + that key. Not new values will currently be moved to the end of the query + string. + + So, goog.Uri.parse('foo?a=b&c=d&e=f').setParameterValues('c', ['new']) + yields foo?a=b&e=f&c=new.

Parameters
key: string
The parameter to set.
values: *
The new values. If values is a single + string then it will be treated as the sole value.
Returns
Reference to this URI object.
code »setPath ( newPath, opt_decode )!goog.Uri

Sets the path.

Parameters
newPath: string
New path value.
opt_decode: boolean=
Optional param for whether to decode new value.
Returns
Reference to this URI object.
code »setPort ( newPort )!goog.Uri

Sets the port number.

Parameters
newPort: *
Port number. Will be explicitly casted to a number.
Returns
Reference to this URI object.
code »setQuery ( newQuery, opt_decode )!goog.Uri

Sets the URI query.

Parameters
newQuery: string
New query value.
opt_decode: boolean=
Optional param for whether to decode new value.
Returns
Reference to this URI object.
code »setQueryData ( queryData, opt_decode )!goog.Uri

Sets the query data.

Parameters
queryData: (goog.Uri.QueryData|string|undefined)
QueryData object.
opt_decode: boolean=
Optional param for whether to decode new value. + Applies only if queryData is a string.
Returns
Reference to this URI object.
code »setReadOnly ( isReadOnly )!goog.Uri

Sets whether Uri is read only. If this goog.Uri is read-only, + enforceReadOnly_ will be called at the start of any function that may modify + this Uri.

Parameters
isReadOnly: boolean
whether this goog.Uri should be read only.
Returns
Reference to this Uri object.
code »setScheme ( newScheme, opt_decode )!goog.Uri

Sets the scheme/protocol.

Parameters
newScheme: string
New scheme value.
opt_decode: boolean=
Optional param for whether to decode new value.
Returns
Reference to this URI object.
code »setUserInfo ( newUserInfo, opt_decode )!goog.Uri

Sets the userInfo.

Parameters
newUserInfo: string
New userInfo value.
opt_decode: boolean=
Optional param for whether to decode new value.
Returns
Reference to this URI object.
Returns
The string form of the url.

Instance Properties

Domain part, e.g. "www.google.com".

The fragment without the #.

Whether or not to ignore case when comparing query params.

Whether or not this Uri should be treated as Read Only.

Path, e.g. "/tests/img.png".

Port, e.g. 8080.

Object representing query data.

Scheme such as "http".

User credentials in the form "username:password".

Static Functions

code »goog.Uri.create ( opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_query, opt_fragment, opt_ignoreCase )!goog.Uri

Creates a new goog.Uri object from unencoded parts.

Parameters
opt_scheme: ?string=
Scheme/protocol or full URI to parse.
opt_userInfo: ?string=
username:password.
opt_domain: ?string=
www.google.com.
opt_port: ?number=
9830.
opt_path: ?string=
/some/path/to/a/file.html.
opt_query: (string|goog.Uri.QueryData)=
a=1&b=2.
opt_fragment: ?string=
The fragment without the #.
opt_ignoreCase: boolean=
Whether to ignore parameter name case in + #getParameterValue.
Returns
The new URI object.

Decodes a value or returns the empty string if it isn't defined or empty.

Parameters
val: (string|undefined)
Value to decode.
Returns
Decoded value.

Converts a character in [\01-\177] to its unicode character equivalent.

Parameters
ch: string
One character string.
Returns
Encoded string.
code »goog.Uri.encodeSpecialChars_ ( unescapedPart, extra )?string

If unescapedPart is non null, then escapes any characters in it that aren't + valid characters in a url and also escapes any special characters that + appear in extra.

Parameters
unescapedPart: *
The string to encode.
extra: RegExp
A character set of characters in [\01-\177].
Returns
null iff unescapedPart == null.
code »goog.Uri.haveSameDomain ( uri1String, uri2String )boolean

Checks whether two URIs have the same domain.

Parameters
uri1String: string
First URI string.
uri2String: string
Second URI string.
Returns
true if the two URIs have the same domain; false otherwise.
code »goog.Uri.parse ( uri, opt_ignoreCase )!goog.Uri

Creates a uri from the string form. Basically an alias of new goog.Uri(). + If a Uri object is passed to parse then it will return a clone of the object.

Parameters
uri: *
Raw URI string or instance of Uri + object.
opt_ignoreCase: boolean=
Whether to ignore the case of parameter + names in #getParameterValue.
Returns
The new URI object.

Removes dot segments in given path component, as described in + RFC 3986, section 5.2.4.

Parameters
path: string
A non-empty path component.
Returns
Path component with removed dot segments.

Resolves a relative Uri against a base Uri, accepting both strings and + Uri objects.

Parameters
base: *
Base Uri.
rel: *
Relative Uri.
Returns
Resolved uri.

Static Properties

Parameter name added to stop caching.

If true, we preserve the type of query parameters set programmatically. + + This means that if you set a parameter to a boolean, and then call + getParameterValue, you will get a boolean back. + + If false, we will coerce parameters to strings, just as they would + appear in real URIs. + + TODO(nicksantos): Remove this once people have time to fix all tests.

Regular expression for characters that are disallowed in an absolute path.

Regular expression for characters that are disallowed in the fragment.

Regular expression for characters that are disallowed in the query.

Regular expression for characters that are disallowed in a relative path.

Regular expression for characters that are disallowed in the scheme or + userInfo part of the URI.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_Uri_QueryData.html b/node_modules/selenium-webdriver/docs/class_goog_Uri_QueryData.html new file mode 100644 index 0000000..4e5c64f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_Uri_QueryData.html @@ -0,0 +1,34 @@ +goog.Uri.QueryData

Class goog.Uri.QueryData

code »

Class used to represent URI query parameters. It is essentially a hash of + name-value pairs, though a name can be present more than once. + + Has the same interface as the collections in goog.structs.

Constructor

goog.Uri.QueryData ( opt_query, opt_uri, opt_ignoreCase )
Parameters
opt_query: ?string=
Optional encoded query string to parse into + the object.
opt_uri: goog.Uri=
Optional uri object that should have its + cache invalidated when this object updates. Deprecated -- this + is no longer required.
opt_ignoreCase: boolean=
If true, ignore the case of the parameter + name in #get.
Show:

Instance Methods

code »add ( key, value )!goog.Uri.QueryData

Adds a key value pair.

Parameters
key: string
Name.
value: *
Value.
Returns
Instance of this object.

Clears the parameters.

Clone the query data instance.

Returns
New instance of the QueryData object.

Whether there is a parameter with the given name

Parameters
key: string
The parameter name to check for.
Returns
Whether there is a parameter with the given name.

Whether there is a parameter with the given value.

Parameters
value: *
The value to check for.
Returns
Whether there is a parameter with the given value.

If the underlying key map is not yet initialized, it parses the + query string and fills the map with parsed data.

code »extend ( var_args )

Extends a query data object with another query data or map like object. This + operates 'in-place', it does not create a new QueryData object.

Parameters
var_args: ...(goog.Uri.QueryData|goog.structs.Map|Object)
The object + from which key value pairs will be copied.

Removes all keys that are not in the provided list. (Modifies this object.)

Parameters
keys: Array.<string>
The desired keys.
Returns
a reference to this object.
code »get ( key, opt_default )*

Returns the first value associated with the key. If the query data has no + such key this will return undefined or the optional default.

Parameters
key: string
The name of the parameter to get the value for.
opt_default: *=
The default value to return if the query data + has no such key.
Returns
The first string value associated with the key, or opt_default + if there's no value.
Returns
The number of parameters.

Helper function to get the key name from a JavaScript object. Converts + the object to a string, and to lower case if necessary.

Parameters
arg: *
The object to get a key name from.
Returns
valid key name which can be looked up in #keyMap_.

Returns all the keys of the parameters. If a key is used multiple times + it will be included multiple times in the returned array

Returns
All the keys of the parameters.
code »getValues ( opt_key )!Array

Returns all the values of the parameters with the given name. If the query + data has no such key this will return an empty array. If no key is given + all values wil be returned.

Parameters
opt_key: string=
The name of the parameter to get the values for.
Returns
All the values of the parameters with the given name.

Invalidate the cache.

Returns
Whether we have any parameters.

Removes all the params with the given key.

Parameters
key: string
Name.
Returns
Whether any parameter was removed.
code »set ( key, value )!goog.Uri.QueryData

Sets a key value pair and removes all other keys with the same value.

Parameters
key: string
Name.
value: *
Value.
Returns
Instance of this object.
code »setIgnoreCase ( ignoreCase )

Ignore case in parameter names. + NOTE: If there are already key/value pairs in the QueryData, and + ignoreCase_ is set to false, the keys will all be lower-cased.

Parameters
ignoreCase: boolean
whether this goog.Uri should ignore case.
code »setValues ( key, values )

Sets the values for a key. If the key already exists, this will + override all of the existing values that correspond to the key.

Parameters
key: string
The key to set values for.
values: Array
The values to set.
Returns
Decoded query string.
Returns
Encoded query string.

Instance Properties

The number of params, or null if it requires computing.

Encoded query string, or null if it requires computing from the key map.

If true, ignore the case of the parameter name in #get.

The map containing name/value or name/array-of-values pairs. + May be null if it requires parsing from the query string. + + We need to use a Map because we cannot guarantee that the key names will + not be problematic for IE.

Static Functions

code »goog.Uri.QueryData.createFromKeysValues ( keys, values, opt_uri, opt_ignoreCase )!goog.Uri.QueryData

Creates a new query data instance from parallel arrays of parameter names + and values. Allows for duplicate parameter names. Throws an error if the + lengths of the arrays differ.

Parameters
keys: Array.<string>
Parameter names.
values: Array
Parameter values.
opt_uri: goog.Uri=
URI object that should have its cache + invalidated when this object updates.
opt_ignoreCase: boolean=
If true, ignore the case of the parameter + name in #get.
Returns
The populated query data instance.
code »goog.Uri.QueryData.createFromMap ( map, opt_uri, opt_ignoreCase )!goog.Uri.QueryData

Creates a new query data instance from a map of names and values.

Parameters
map: (!goog.structs.Map|!Object)
Map of string parameter + names to parameter value. If parameter value is an array, it is + treated as if the key maps to each individual value in the + array.
opt_uri: goog.Uri=
URI object that should have its cache + invalidated when this object updates.
opt_ignoreCase: boolean=
If true, ignore the case of the parameter + name in #get.
Returns
The populated query data instance.
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_asserts_AssertionError.html b/node_modules/selenium-webdriver/docs/class_goog_asserts_AssertionError.html new file mode 100644 index 0000000..a435077 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_asserts_AssertionError.html @@ -0,0 +1,4 @@ +goog.asserts.AssertionError

Class goog.asserts.AssertionError

code »
Error
+  └ goog.debug.Error
+      └ goog.asserts.AssertionError

Error object for failed assertions.

Constructor

goog.asserts.AssertionError ( messagePattern, messageArgs )
Parameters
messagePattern: string
The pattern that was used to form message.
messageArgs: !Array
The items to substitute into the pattern.
Show:

Instance Properties

Defined in goog.asserts.AssertionError

The message pattern used to format the error message. Error handlers can + use this to uniquely identify the assertion.

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_debug_Error.html b/node_modules/selenium-webdriver/docs/class_goog_debug_Error.html new file mode 100644 index 0000000..15eb56f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_debug_Error.html @@ -0,0 +1,2 @@ +goog.debug.Error

Class goog.debug.Error

code »
Error
+  └ goog.debug.Error

Base class for custom error objects.

Constructor

goog.debug.Error ( opt_msg )
Parameters
opt_msg: *=
The message associated with the error.
Show:

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_iter_GroupByIterator_.html b/node_modules/selenium-webdriver/docs/class_goog_iter_GroupByIterator_.html new file mode 100644 index 0000000..6331c61 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_iter_GroupByIterator_.html @@ -0,0 +1,12 @@ +goog.iter.GroupByIterator_

Class goog.iter.GroupByIterator_.<KEY, VALUE>

code »
goog.iter.Iterator.<Array>
+  └ goog.iter.GroupByIterator_

Implements the goog.iter.groupBy iterator.

Constructor

goog.iter.GroupByIterator_ ( iterable, opt_keyFunc )
Parameters
iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
The + iterable to group.
opt_keyFunc: function(VALUE): KEY=
Optional function for + determining the key value for each group in the iterable. Default + is the identity function.
Show:

Instance Methods

Defined in goog.iter.GroupByIterator_

code »groupItems_ ( targetKey )!Array.<VALUE>

Performs the grouping of objects using the given key.

Parameters
targetKey: KEY
The target key object for the group.
Returns
An array of grouped objects.
code »keyFunc ( )KEY

A function for determining the key value for each element in the iterable. + If no function is provided, the identity function is used and returns the + element unchanged.

code »next ( )Array

Defined in goog.iter.Iterator.<Array>

code »__iterator__ ( opt_keys )!goog.iter.Iterator.<VALUE>

Returns the Iterator object itself. This is used to implement + the iterator protocol in JavaScript 1.7

Parameters
opt_keys: boolean=
Whether to return the keys or values. Default is + to only return the values. This is being used by the for-in loop (true) + and the for-each-in loop (false). Even though the param gives a hint + about what the iterator will return there is no guarantee that it will + return the keys when true is passed.
Returns
The object itself.

Instance Properties

Defined in goog.iter.GroupByIterator_

The current key visited during iteration.

The current value being added to the group.

The iterable to group, coerced to an iterator.

The target key for determining the start of a group.

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_iter_Iterator.html b/node_modules/selenium-webdriver/docs/class_goog_iter_Iterator.html new file mode 100644 index 0000000..9a08d8f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_iter_Iterator.html @@ -0,0 +1,11 @@ +goog.iter.Iterator

Class goog.iter.Iterator.<VALUE>

code »

Class/interface for iterators. An iterator needs to implement a next + method and it needs to throw a goog.iter.StopIteration when the + iteration passes beyond the end. Iterators have no hasNext method. + It is recommended to always use the helper functions to iterate over the + iterator or in case you are only targeting JavaScript 1.7 for in loops.

Constructor

goog.iter.Iterator ( )
Show:

Instance Methods

code »__iterator__ ( opt_keys )!goog.iter.Iterator.<VALUE>

Returns the Iterator object itself. This is used to implement + the iterator protocol in JavaScript 1.7

Parameters
opt_keys: boolean=
Whether to return the keys or values. Default is + to only return the values. This is being used by the for-in loop (true) + and the for-each-in loop (false). Even though the param gives a hint + about what the iterator will return there is no guarantee that it will + return the keys when true is passed.
Returns
The object itself.
code »next ( )VALUE

Returns the next value of the iteration. This will throw the object + goog.iter#StopIteration when the iteration passes the end.

Returns
Any object or value.
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_json_Serializer.html b/node_modules/selenium-webdriver/docs/class_goog_json_Serializer.html new file mode 100644 index 0000000..cb17974 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_json_Serializer.html @@ -0,0 +1,4 @@ +goog.json.Serializer

Class goog.json.Serializer

code »

Class that is used to serialize JSON objects to a string.

Constructor

goog.json.Serializer ( opt_replacer )
Parameters
opt_replacer: ?goog.json.Replacer=
Replacer.
Show:

Instance Methods

code »serialize ( object )string

Serializes an object or a value to a JSON string.

Parameters
object: *
The object to serialize.
Returns
A JSON string representation of the input.
Throws
if there are loops in the object graph.

Serializes an array to a JSON string

Parameters
arr: Array
The array to serialize.
sb: Array
Array used as a string builder.

Serializes a generic value to a JSON string

Parameters
object: *
The object to serialize.
sb: Array
Array used as a string builder.
Throws
if there are loops in the object graph.

Serializes a number to a JSON string

Parameters
n: number
The number to serialize.
sb: Array
Array used as a string builder.

Serializes an object to a JSON string

Parameters
obj: Object
The object to serialize.
sb: Array
Array used as a string builder.

Serializes a string to a JSON string

Parameters
s: string
The string to serialize.
sb: Array
Array used as a string builder.

Instance Properties

Static Properties

Character mappings used internally for goog.string.quote

Regular expression used to match characters that need to be replaced. + The S60 browser has a bug where unicode characters are not matched by + regular expressions. The condition below detects such behaviour and + adjusts the regular expression accordingly.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_AllOfMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_AllOfMatcher.html new file mode 100644 index 0000000..a8abeeb --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_AllOfMatcher.html @@ -0,0 +1,2 @@ +goog.labs.testing.AllOfMatcher

Class goog.labs.testing.AllOfMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The AllOf matcher.

Constructor

goog.labs.testing.AllOfMatcher ( matchers )
Parameters
matchers: !Array
Input matchers.
Show:

Instance Methods

code »describe ( actualValue )string

Describes why the matcher failed. The returned string is a concatenation of + all the failed matchers' error strings.

Parameters
actualValue
code »matches ( actualValue )boolean

Determines if all of the matchers match the input value.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_AnyOfMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_AnyOfMatcher.html new file mode 100644 index 0000000..69104a3 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_AnyOfMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.AnyOfMatcher

Class goog.labs.testing.AnyOfMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The AnyOf matcher.

Constructor

goog.labs.testing.AnyOfMatcher ( matchers )
Parameters
matchers: !Array
Input matchers.
Show:

Instance Methods

code »describe ( actualValue )string

Describes why the matcher failed.

Parameters
actualValue
code »matches ( actualValue )boolean

Determines if any of the matchers matches the input value.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_CloseToMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_CloseToMatcher.html new file mode 100644 index 0000000..6ba10dd --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_CloseToMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.CloseToMatcher

Class goog.labs.testing.CloseToMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The CloseTo matcher.

Constructor

goog.labs.testing.CloseToMatcher ( value, range )
Parameters
value: number
The value to compare.
range: number
The range to check within.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if input value is within a certain range of the expected value.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_ContainsStringMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_ContainsStringMatcher.html new file mode 100644 index 0000000..0cff10f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_ContainsStringMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.ContainsStringMatcher

Class goog.labs.testing.ContainsStringMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The ContainsString matcher.

Constructor

goog.labs.testing.ContainsStringMatcher ( value )
Parameters
value: string
The expected string.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if input string contains the expected string.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_EndsWithMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_EndsWithMatcher.html new file mode 100644 index 0000000..3a8150c --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_EndsWithMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.EndsWithMatcher

Class goog.labs.testing.EndsWithMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The EndsWith matcher.

Constructor

goog.labs.testing.EndsWithMatcher ( value )
Parameters
value: string
The expected string.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if input string ends with the expected string.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_EqualToIgnoringWhitespaceMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_EqualToIgnoringWhitespaceMatcher.html new file mode 100644 index 0000000..de9baf2 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_EqualToIgnoringWhitespaceMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.EqualToIgnoringWhitespaceMatcher

Class goog.labs.testing.EqualToIgnoringWhitespaceMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The EqualToIgnoringWhitespace matcher.

Constructor

goog.labs.testing.EqualToIgnoringWhitespaceMatcher ( value )
Parameters
value: string
The expected string.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if input string contains the expected string.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_EqualToMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_EqualToMatcher.html new file mode 100644 index 0000000..cab4268 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_EqualToMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.EqualToMatcher

Class goog.labs.testing.EqualToMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The EqualTo matcher.

Constructor

goog.labs.testing.EqualToMatcher ( value )
Parameters
value: number
The value to compare.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if the input value is equal to the expected value.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_EqualsMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_EqualsMatcher.html new file mode 100644 index 0000000..bec6a9e --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_EqualsMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.EqualsMatcher

Class goog.labs.testing.EqualsMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The Equals matcher.

Constructor

goog.labs.testing.EqualsMatcher ( value )
Parameters
value: string
The expected string.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if input string is equal to the expected string.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_GreaterThanEqualToMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_GreaterThanEqualToMatcher.html new file mode 100644 index 0000000..dc0eef5 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_GreaterThanEqualToMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.GreaterThanEqualToMatcher

Class goog.labs.testing.GreaterThanEqualToMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The GreaterThanEqualTo matcher.

Constructor

goog.labs.testing.GreaterThanEqualToMatcher ( value )
Parameters
value: number
The value to compare.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if the input value is greater than equal to the expected value.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_GreaterThanMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_GreaterThanMatcher.html new file mode 100644 index 0000000..d6833fc --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_GreaterThanMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.GreaterThanMatcher

Class goog.labs.testing.GreaterThanMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The GreaterThan matcher.

Constructor

goog.labs.testing.GreaterThanMatcher ( value )
Parameters
value: number
The value to compare.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if input value is greater than the expected value.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_HasPropertyMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_HasPropertyMatcher.html new file mode 100644 index 0000000..20cbe1b --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_HasPropertyMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.HasPropertyMatcher

Class goog.labs.testing.HasPropertyMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The HasProperty matcher.

Constructor

goog.labs.testing.HasPropertyMatcher ( property )
Parameters
property: string
Name of the property to test.
Show:

Instance Methods

code »describe ( actualObject )string
Parameters
actualObject
code »matches ( actualObject )boolean

Determines if an object has a property.

Parameters
actualObject

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_InstanceOfMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_InstanceOfMatcher.html new file mode 100644 index 0000000..28672ce --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_InstanceOfMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.InstanceOfMatcher

Class goog.labs.testing.InstanceOfMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The InstanceOf matcher.

Constructor

goog.labs.testing.InstanceOfMatcher ( object )
Parameters
object: !Object
The expected class object.
Show:

Instance Methods

code »describe ( actualObject )string
Parameters
actualObject
code »matches ( actualObject )boolean

Determines if an object is an instance of another object.

Parameters
actualObject

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsNotMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsNotMatcher.html new file mode 100644 index 0000000..3900ba6 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsNotMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.IsNotMatcher

Class goog.labs.testing.IsNotMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The IsNot matcher.

Constructor

goog.labs.testing.IsNotMatcher ( matcher )
Parameters
matcher: !goog.labs.testing.Matcher
The matcher to negate.
Show:

Instance Methods

code »describe ( actualValue )string

Describes why the matcher failed.

Parameters
actualValue
code »matches ( actualValue )boolean

Determines if the input value doesn't satisfy a matcher.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsNullMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsNullMatcher.html new file mode 100644 index 0000000..2f49dbb --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsNullMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.IsNullMatcher

Class goog.labs.testing.IsNullMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The IsNull matcher.

Constructor

goog.labs.testing.IsNullMatcher ( )
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if input value is null.

Parameters
actualValue
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsNullOrUndefinedMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsNullOrUndefinedMatcher.html new file mode 100644 index 0000000..6dfc016 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsNullOrUndefinedMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.IsNullOrUndefinedMatcher

Class goog.labs.testing.IsNullOrUndefinedMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The IsNullOrUndefined matcher.

Constructor

goog.labs.testing.IsNullOrUndefinedMatcher ( )
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if input value is null or undefined.

Parameters
actualValue
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsUndefinedMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsUndefinedMatcher.html new file mode 100644 index 0000000..195756d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_IsUndefinedMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.IsUndefinedMatcher

Class goog.labs.testing.IsUndefinedMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The IsUndefined matcher.

Constructor

goog.labs.testing.IsUndefinedMatcher ( )
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if input value is undefined.

Parameters
actualValue
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_LessThanEqualToMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_LessThanEqualToMatcher.html new file mode 100644 index 0000000..c2b056d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_LessThanEqualToMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.LessThanEqualToMatcher

Class goog.labs.testing.LessThanEqualToMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The LessThanEqualTo matcher.

Constructor

goog.labs.testing.LessThanEqualToMatcher ( value )
Parameters
value: number
The value to compare.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if the input value is less than or equal to the expected value.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_LessThanMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_LessThanMatcher.html new file mode 100644 index 0000000..d6ef5aa --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_LessThanMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.LessThanMatcher

Class goog.labs.testing.LessThanMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The lessThan matcher.

Constructor

goog.labs.testing.LessThanMatcher ( value )
Parameters
value: number
The value to compare.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if the input value is less than the expected value.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_MatcherError.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_MatcherError.html new file mode 100644 index 0000000..d59d8cd --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_MatcherError.html @@ -0,0 +1,3 @@ +goog.labs.testing.MatcherError

Class goog.labs.testing.MatcherError

code »
Error
+  └ goog.debug.Error
+      └ goog.labs.testing.MatcherError

Error thrown when a Matcher fails to match the input value.

Constructor

goog.labs.testing.MatcherError ( opt_message )
Parameters
opt_message: string=
The error message.
Show:

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_ObjectEqualsMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_ObjectEqualsMatcher.html new file mode 100644 index 0000000..c186646 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_ObjectEqualsMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.ObjectEqualsMatcher

Class goog.labs.testing.ObjectEqualsMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The Equals matcher.

Constructor

goog.labs.testing.ObjectEqualsMatcher ( expectedObject )
Parameters
expectedObject: !Object
The expected object.
Show:

Instance Methods

code »describe ( actualObject )string
Parameters
actualObject
code »matches ( actualObject )boolean

Determines if two objects are the same.

Parameters
actualObject

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_RegexMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_RegexMatcher.html new file mode 100644 index 0000000..a2c868f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_RegexMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.RegexMatcher

Class goog.labs.testing.RegexMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The MatchesRegex matcher.

Constructor

goog.labs.testing.RegexMatcher ( regex )
Parameters
regex: !RegExp
The expected regex.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if input string is equal to the expected string.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_StartsWithMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_StartsWithMatcher.html new file mode 100644 index 0000000..d365ba0 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_StartsWithMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.StartsWithMatcher

Class goog.labs.testing.StartsWithMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The StartsWith matcher.

Constructor

goog.labs.testing.StartsWithMatcher ( value )
Parameters
value: string
The expected string.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if input string starts with the expected string.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_labs_testing_StringContainsInOrderMatcher.html b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_StringContainsInOrderMatcher.html new file mode 100644 index 0000000..8b39438 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_labs_testing_StringContainsInOrderMatcher.html @@ -0,0 +1 @@ +goog.labs.testing.StringContainsInOrderMatcher

Class goog.labs.testing.StringContainsInOrderMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

The StringContainsInOrdermatcher.

Constructor

goog.labs.testing.StringContainsInOrderMatcher ( values )
Parameters
values: Array.<string>
The expected string values.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean

Determines if input string contains, in order, the expected array of strings.

Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_net_DefaultXmlHttpFactory.html b/node_modules/selenium-webdriver/docs/class_goog_net_DefaultXmlHttpFactory.html new file mode 100644 index 0000000..926ca60 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_net_DefaultXmlHttpFactory.html @@ -0,0 +1,4 @@ +goog.net.DefaultXmlHttpFactory

Class goog.net.DefaultXmlHttpFactory

code »
goog.net.XmlHttpFactory
+  └ goog.net.DefaultXmlHttpFactory

Default factory to use when creating xhr objects. You probably shouldn't be + instantiating this directly, but rather using it via goog.net.XmlHttp.

Constructor

goog.net.DefaultXmlHttpFactory ( )
Show:

Instance Methods

Defined in goog.net.DefaultXmlHttpFactory

code »createInstance ( )(XMLHttpRequest|goog.net.XhrLike)

Initialize the private state used by other functions.

Returns
The ActiveX PROG ID string to use to create xhr's in IE.
code »internalGetOptions ( )(Object|null)

Defined in goog.net.XmlHttpFactory

Returns
Options describing how xhr objects obtained from this + factory should be used.

Instance Properties

Defined in goog.net.DefaultXmlHttpFactory

The ActiveX PROG ID string to use to create xhr's in IE. Lazily initialized.

Defined in goog.net.XmlHttpFactory

Cache of options - we only actually call internalGetOptions once.

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_net_WrapperXmlHttpFactory.html b/node_modules/selenium-webdriver/docs/class_goog_net_WrapperXmlHttpFactory.html new file mode 100644 index 0000000..aee1ef2 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_net_WrapperXmlHttpFactory.html @@ -0,0 +1,7 @@ +goog.net.WrapperXmlHttpFactory

Class goog.net.WrapperXmlHttpFactory

code »
goog.net.XmlHttpFactory
+  └ goog.net.WrapperXmlHttpFactory

An xhr factory subclass which can be constructed using two factory methods. + This exists partly to allow the preservation of goog.net.XmlHttp.setFactory() + with an unchanged signature.

Constructor

goog.net.WrapperXmlHttpFactory ( xhrFactory, optionsFactory )
Parameters
xhrFactory: function(): !goog.net.XhrLike.OrNative
A function which returns a new XHR object.
optionsFactory: function(): !Object
A function which returns the + options associated with xhr objects from this factory.
Show:

Instance Methods

Defined in goog.net.WrapperXmlHttpFactory

code »createInstance ( )(XMLHttpRequest|goog.net.XhrLike)
code »getOptions ( )(Object|null)
code »optionsFactory_ ( )Object

Options factory method.

code »xhrFactory_ ( )(XMLHttpRequest|goog.net.XhrLike)

XHR factory method.

Defined in goog.net.XmlHttpFactory

Override this method in subclasses to preserve the caching offered by + getOptions().

Returns
Options describing how xhr objects obtained from this + factory should be used.

Instance Properties

Defined in goog.net.XmlHttpFactory

Cache of options - we only actually call internalGetOptions once.

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_net_XmlHttpFactory.html b/node_modules/selenium-webdriver/docs/class_goog_net_XmlHttpFactory.html new file mode 100644 index 0000000..fb9ff8d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_net_XmlHttpFactory.html @@ -0,0 +1,4 @@ +goog.net.XmlHttpFactory

Class goog.net.XmlHttpFactory

code »

Abstract base class for an XmlHttpRequest factory.

Constructor

goog.net.XmlHttpFactory ( )
Show:

Instance Methods

Returns
A new XhrLike instance.
Returns
Options describing how xhr objects obtained from this + factory should be used.

Override this method in subclasses to preserve the caching offered by + getOptions().

Returns
Options describing how xhr objects obtained from this + factory should be used.

Instance Properties

Cache of options - we only actually call internalGetOptions once.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_goog_structs_Map.html b/node_modules/selenium-webdriver/docs/class_goog_structs_Map.html new file mode 100644 index 0000000..161f995 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_goog_structs_Map.html @@ -0,0 +1,28 @@ +goog.structs.Map

Class goog.structs.Map.<K, V>

code »

Class for Hash Map datastructure.

Constructor

goog.structs.Map ( opt_map, var_args )
Parameters
opt_map: *=
Map or Object to initialize the map with.
var_args: ...*
If 2 or more arguments are present then they + will be used as key-value pairs.
Show:

Instance Methods

Returns an iterator that iterates over the values or the keys in the map. + This throws an exception if the map was mutated since the iterator was + created.

Parameters
opt_keys: boolean=
True to iterate over the keys. False to iterate + over the values. The default value is false.
Returns
An iterator over the values or keys in the map.

Adds multiple key-value pairs from another goog.structs.Map or Object.

Parameters
map: Object
Object containing the data to add.

Cleans up the temp keys array by removing entries that are no longer in the + map.

Removes all key-value pairs from the map.

Clones a map and returns a new map.

Returns
A new map with the same key-value pairs.

Whether the map contains the given key.

Parameters
key: *
The key to check for.
Returns
Whether the map contains the key.

Whether the map contains the given value. This is O(n).

Parameters
val: V
The value to check for.
Returns
Whether the map contains the value.
code »equals ( otherMap, opt_equalityFn )boolean

Whether this map is equal to the argument map.

Parameters
otherMap: goog.structs.Map
The map against which to test equality.
opt_equalityFn: function(V, V): boolean=
Optional equality function + to test equality of values. If not specified, this will test whether + the values contained in each map are identical objects.
Returns
Whether the maps are equal.
code »<T> forEach ( f, opt_obj )

Calls the given function on each entry in the map.

Parameters
f
opt_obj: T=
The value of "this" inside f.
code »<DEFAULT> get ( key, opt_val )(V|DEFAULT)

Returns the value for the given key. If the key is not found and the default + value is not given this will return undefined.

Parameters
key: *
The key to get the value for.
opt_val: DEFAULT=
The value to return if no item is found for the + given key, defaults to undefined.
Returns
The value for the given key.
Returns
The number of key-value pairs in the map.

Returns an iterator that iterates over the keys in the map. Removal of keys + while iterating might have undesired side effects.

Returns
An iterator over the keys in the map.

Returns the keys of the map.

Returns
Array of string values.

Returns an iterator that iterates over the values in the map. Removal of + keys while iterating might have undesired side effects.

Returns
An iterator over the values in the map.
code »getValues ( )!Array.<V>

Returns the values of the map.

Returns
The values in the map.
Returns
Whether the map is empty.

Removes a key-value pair based on the key. This is O(logN) amortized due to + updating the keys array whenever the count becomes half the size of the keys + in the keys array.

Parameters
key: *
The key to remove.
Returns
Whether object was removed.
code »set ( key, value )*

Adds a key-value pair to the map.

Parameters
key: *
The key.
value: V
The value to add.
Returns
Some subclasses return a value.
Returns
Object representation of the map.

Returns a new map in which all the keys and values are interchanged + (keys become values and values become keys). If multiple keys map to the + same value, the chosen transposed value is implementation-dependent. + + It acts very similarly to {goog.object.transpose(Object)}.

Returns
The transposed map.

Instance Properties

The number of key value pairs in the map.

An array of keys. This is necessary for two reasons: + 1. Iterating the keys using for (var key in this.map_) allocates an + object for every key in IE which is really bad for IE6 GC perf. + 2. Without a side data structure, we would need to escape all the keys + as that would be the only way we could tell during iteration if the + key was an internal key or a property of the object. + + This array can contain deleted keys so it's necessary to check the map + as well to see if the key is still in the map (this doesn't require a + memory allocation in IE).

Underlying JS object used to implement the map.

Version used to detect changes while iterating.

Static Functions

Default equality test for values.

Parameters
a: *
The first value.
b: *
The second value.
Returns
Whether a and b reference the same object.

Safe way to test for hasOwnProperty. It even allows testing for + 'hasOwnProperty'.

Parameters
obj: Object
The object to test for presence of the given key.
key: *
The key to check for.
Returns
Whether the object has the key.
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_AbstractBuilder.html b/node_modules/selenium-webdriver/docs/class_webdriver_AbstractBuilder.html new file mode 100644 index 0000000..a8dc544 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_AbstractBuilder.html @@ -0,0 +1,21 @@ +webdriver.AbstractBuilder

Class webdriver.AbstractBuilder

code »

Creates new webdriver.WebDriver clients. Upon instantiation, each + Builder will configure itself based on the following environment variables: +

+
webdriver.AbstractBuilder.SERVER_URL_ENV
+
Defines the remote WebDriver server that should be used for command + command execution; may be overridden using + webdriver.AbstractBuilder.prototype.usingServer.
+

Constructor

webdriver.AbstractBuilder ( )
Show:

Instance Methods

Builds a new webdriver.WebDriver instance using this builder's + current configuration.

Returns
A new WebDriver client.
Returns
The current desired capabilities for this + builder.
Returns
The URL of the WebDriver server this instance is configured + to use.

Configures which WebDriver server should be used for new sessions. Overrides + the value loaded from the webdriver.AbstractBuilder.SERVER_URL_ENV + upon creation of this instance.

Parameters
url: string
URL of the server to use.
Returns
This Builder instance for chain calling.

Sets the desired capabilities when requesting a new session. This will + overwrite any previously set desired capabilities.

Parameters
capabilities: !(Object|webdriver.Capabilities)
The desired + capabilities for a new session.
Returns
This Builder instance for chain calling.

Instance Properties

The desired capabilities to use when creating a new session.

URL of the remote server to use for new clients; initialized from the + value of the webdriver.AbstractBuilder.SERVER_URL_ENV environment + variable, but may be overridden using + webdriver.AbstractBuilder#usingServer.

Static Properties

The default URL of the WebDriver server to use if + webdriver.AbstractBuilder.SERVER_URL_ENV is not set.

Environment variable that defines the URL of the WebDriver server that + should be used for all new WebDriver clients. This setting may be overridden + using #usingServer(url).

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_ActionSequence.html b/node_modules/selenium-webdriver/docs/class_webdriver_ActionSequence.html new file mode 100644 index 0000000..86ec373 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_ActionSequence.html @@ -0,0 +1,87 @@ +webdriver.ActionSequence

Class webdriver.ActionSequence

code »

Class for defining sequences of complex user interactions. Each sequence + will not be executed until #perform is called. + +

Example:


+   new webdriver.ActionSequence(driver).
+       keyDown(webdriver.Key.SHIFT).
+       click(element1).
+       click(element2).
+       dragAndDrop(element3, element4).
+       keyUp(webdriver.Key.SHIFT).
+       perform();
+ 

Constructor

webdriver.ActionSequence ( driver )
Parameters
driver: !webdriver.WebDriver
The driver instance to use.
Show:

Instance Methods

code »click ( opt_elementOrButton, opt_button )!webdriver.ActionSequence

Clicks a mouse button. + +

If an element is provided, the mouse will first be moved to the center + of that element. This is equivalent to: +

sequence.mouseMove(element).click()
Parameters
opt_elementOrButton: (webdriver.WebElement|webdriver.Button)=
Either + the element to interact with or the button to click with. + Defaults to webdriver.Button.LEFT if neither an element nor + button is specified.
opt_button: webdriver.Button=
The button to use. Defaults to + webdriver.Button.LEFT. Ignored if a button is provided as the + first argument.
Returns
A self reference.
code »doubleClick ( opt_elementOrButton, opt_button )!webdriver.ActionSequence

Double-clicks a mouse button. + +

If an element is provided, the mouse will first be moved to the center of + that element. This is equivalent to: +

sequence.mouseMove(element).doubleClick()
+ +

Warning: this method currently only supports the left mouse button. See + http://code.google.com/p/selenium/issues/detail?id=4047

Parameters
opt_elementOrButton: (webdriver.WebElement|webdriver.Button)=
Either + the element to interact with or the button to click with. + Defaults to webdriver.Button.LEFT if neither an element nor + button is specified.
opt_button: webdriver.Button=
The button to use. Defaults to + webdriver.Button.LEFT. Ignored if a button is provided as the + first argument.
Returns
A self reference.
code »dragAndDrop ( element, location )!webdriver.ActionSequence

Convenience function for performing a "drag and drop" manuever. The target + element may be moved to the location of another element, or by an offset (in + pixels).

Parameters
element: !webdriver.WebElement
The element to drag.
location: (!webdriver.WebElement|{x: number, y: number})
The + location to drag to, either as another WebElement or an offset in pixels.
Returns
A self reference.

Performs a modifier key press. The modifier key is not released + until #keyUp or #sendKeys is called. The key press will be + targetted at the currently focused element.

Parameters
key: !webdriver.Key
The modifier key to push. Must be one of + {ALT, CONTROL, SHIFT, COMMAND, META}.
Returns
A self reference.
Throws
Error
If the key is not a valid modifier key.

Performs a modifier key release. The release is targetted at the currently + focused element.

Parameters
key: !webdriver.Key
The modifier key to release. Must be one of + {ALT, CONTROL, SHIFT, COMMAND, META}.
Returns
A self reference.
Throws
Error
If the key is not a valid modifier key.
code »mouseDown ( opt_elementOrButton, opt_button )!webdriver.ActionSequence

Presses a mouse button. The mouse button will not be released until + #mouseUp is called, regardless of whether that call is made in this + sequence or another. The behavior for out-of-order events (e.g. mouseDown, + click) is undefined. + +

If an element is provided, the mouse will first be moved to the center + of that element. This is equivalent to: +

sequence.mouseMove(element).mouseDown()
+ +

Warning: this method currently only supports the left mouse button. See + http://code.google.com/p/selenium/issues/detail?id=4047

Parameters
opt_elementOrButton: (webdriver.WebElement|webdriver.Button)=
Either + the element to interact with or the button to click with. + Defaults to webdriver.Button.LEFT if neither an element nor + button is specified.
opt_button: webdriver.Button=
The button to use. Defaults to + webdriver.Button.LEFT. Ignored if a button is provided as the + first argument.
Returns
A self reference.
code »mouseMove ( location, opt_offset )!webdriver.ActionSequence

Moves the mouse. The location to move to may be specified in terms of the + mouse's current location, an offset relative to the top-left corner of an + element, or an element (in which case the middle of the element is used).

Parameters
location: (!webdriver.WebElement|{x: number, y: number})
The + location to drag to, as either another WebElement or an offset in pixels.
opt_offset: {x: number, y: number}=
If the target location + is defined as a webdriver.WebElement, this parameter defines an + offset within that element. The offset should be specified in pixels + relative to the top-left corner of the element's bounding box. If + omitted, the element's center will be used as the target offset.
Returns
A self reference.
code »mouseUp ( opt_elementOrButton, opt_button )!webdriver.ActionSequence

Releases a mouse button. Behavior is undefined for calling this function + without a previous call to #mouseDown. + +

If an element is provided, the mouse will first be moved to the center + of that element. This is equivalent to: +

sequence.mouseMove(element).mouseUp()
+ +

Warning: this method currently only supports the left mouse button. See + http://code.google.com/p/selenium/issues/detail?id=4047

Parameters
opt_elementOrButton: (webdriver.WebElement|webdriver.Button)=
Either + the element to interact with or the button to click with. + Defaults to webdriver.Button.LEFT if neither an element nor + button is specified.
opt_button: webdriver.Button=
The button to use. Defaults to + webdriver.Button.LEFT. Ignored if a button is provided as the + first argument.
Returns
A self reference.

Executes this action sequence.

Returns
A promise that will be resolved once + this sequence has completed.

Schedules a keyboard action.

Parameters
description: string
A simple descriptive label for the scheduled + action.
keys: !Array
The keys to send.
Returns
A self reference.
code »scheduleMouseAction_ ( description, commandName, opt_elementOrButton, opt_button )!webdriver.ActionSequence

Schedules a mouse action.

Parameters
description: string
A simple descriptive label for the scheduled + action.
commandName: !webdriver.CommandName
The name of the command.
opt_elementOrButton: (webdriver.WebElement|webdriver.Button)=
Either + the element to interact with or the button to click with. + Defaults to webdriver.Button.LEFT if neither an element nor + button is specified.
opt_button: webdriver.Button=
The button to use. Defaults to + webdriver.Button.LEFT. Ignored if the previous argument is + provided as a button.
Returns
A self reference.
code »schedule_ ( description, command )

Schedules an action to be executed each time #perform is called on + this instance.

Parameters
description: string
A description of the command.
command: !webdriver.Command
The command.

Simulates typing multiple keys. Each modifier key encountered in the + sequence will not be released until it is encountered again. All key events + will be targetted at the currently focused element.

Parameters
var_args: ...(string|!webdriver.Key|!Array)
The keys to type.
Returns
A self reference.
Throws
Error
If the key is not a valid modifier key.

Instance Properties

Static Functions

Checks that a key is a modifier key.

Parameters
key: !webdriver.Key
The key to check.
Throws
Error
If the key is not a modifier key.
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_Alert.html b/node_modules/selenium-webdriver/docs/class_webdriver_Alert.html new file mode 100644 index 0000000..82fd883 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_Alert.html @@ -0,0 +1,85 @@ +webdriver.Alert

Class webdriver.Alert

code »
webdriver.promise.Promise.<(T|null)>
+  └ webdriver.promise.Deferred
+      └ webdriver.Alert

Represents a modal dialog such as alert, confirm, or + prompt. Provides functions to retrieve the message displayed with + the alert, accept or dismiss the alert, and set the response text (in the + case of prompt).

Constructor

webdriver.Alert ( driver, text )
Parameters
driver: !webdriver.WebDriver
The driver controlling the browser this + alert is attached to.
text: !(string|webdriver.promise.Promise.<string>)
Either the + message text displayed with this alert, or a promise that will be + resolved to said text.
Show:

Instance Methods

Defined in webdriver.Alert

Accepts this alert.

Returns
A promise that will be resolved + when this command has completed.

Dismisses this alert.

Returns
A promise that will be resolved + when this command has completed.

Retrieves the message text displayed with this alert. For instance, if the + alert were opened with alert("hello"), then this would return "hello".

Returns
A promise that will be + resolved to the text displayed with this alert.

Sets the response text on this alert. This command will return an error if + the underlying alert does not support response text (e.g. window.alert and + window.confirm).

Parameters
text: string
The text to set.
Returns
A promise that will be resolved + when this command has completed.

Defined in webdriver.promise.Deferred

code »errback ( opt_error )

Rejects this promise. If the error is itself a promise, this instance will + be chained to it and be rejected with the error's resolved value.

Parameters
opt_error: *=
The rejection reason, typically either a + Error or a string.
code »fulfill ( opt_value )

Resolves this promise with the given value. If the value is itself a + promise and not a reference to this deferred, this instance will wait for + it before resolving.

Parameters
opt_value: T=
The fulfilled value.
code »reject ( opt_error )

Rejects this promise. If the error is itself a promise, this instance will + be chained to it and be rejected with the error's resolved value.

Parameters
opt_error: *=
The rejection reason, typically either a + Error or a string.

Removes all of the listeners previously registered on this deferred.

Throws
Error
If this deferred has already been resolved.

Defined in webdriver.promise.Promise.<(T|null)>

code »cancel ( reason )

Cancels the computation of this promise's value, rejecting the promise in the + process.

Parameters
reason: *
The reason this promise is being cancelled. If not an + Error, one will be created using the value's string + representation.
Returns
Whether this promise's value is still being computed.
code »<R> then ( opt_callback, opt_errback )!webdriver.promise.Promise.<R>

Registers listeners for when this instance is resolved. This function most + overridden by subtypes.

Parameters
opt_callback: ?(function(T): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is successfully resolved. The function + should expect a single argument: the promise's resolved value.
opt_errback: ?(function(*): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is rejected. The function should expect + a single argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener for when this promise is rejected. This is synonymous + with the catch clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } catch (ex) {
+     console.error(ex);
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenCatch(function(ex) {
+     console.error(ex);
+   });
+ 
Parameters
errback: function(*): (R|webdriver.promise.Promise.<R>)
The function + to call if this promise is rejected. The function should expect a single + argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener to invoke when this promise is resolved, regardless + of whether the promise's value was successfully computed. This function + is synonymous with the finally clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } finally {
+     cleanUp();
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenFinally(cleanUp);
+ 
+ + Note: similar to the finally clause, if the registered + callback returns a rejected promise or throws an error, it will silently + replace the rejection error (if any) from this promise: +

+   try {
+     throw Error('one');
+   } finally {
+     throw Error('two');  // Hides Error: one
+   }
+
+   webdriver.promise.rejected(Error('one'))
+       .thenFinally(function() {
+         throw Error('two');  // Hides Error: one
+       });
+ 
Parameters
callback: function(): (R|webdriver.promise.Promise.<R>)
The function + to call when this promise is resolved.
Returns
A promise that will be fulfilled + with the callback result.

Instance Properties

Defined in webdriver.Alert

Defined in webdriver.promise.Deferred

Represents the eventual value of a completed operation. Each promise may be + in one of three states: pending, resolved, or rejected. Each promise starts + in the pending state and may make a single transition to either a + fulfilled or failed state. + +

This class is based on the Promise/A proposal from CommonJS. Additional + functions are provided for API compatibility with Dojo Deferred objects.

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_Builder.html b/node_modules/selenium-webdriver/docs/class_webdriver_Builder.html new file mode 100644 index 0000000..f650658 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_Builder.html @@ -0,0 +1,22 @@ +webdriver.Builder

Class webdriver.Builder

code »
webdriver.AbstractBuilder
+  └ webdriver.Builder

Constructor

webdriver.Builder ( )
Show:

Instance Methods

Defined in webdriver.Builder

code »build ( )webdriver.WebDriver
Returns
The ID of the session, if any, this builder is configured + to reuse.

Configures the builder to create a client that will use an existing WebDriver + session.

Parameters
id: string
The existing session ID to use.
Returns
This Builder instance for chain calling.

Defined in webdriver.AbstractBuilder

Returns
The current desired capabilities for this + builder.
Returns
The URL of the WebDriver server this instance is configured + to use.

Configures which WebDriver server should be used for new sessions. Overrides + the value loaded from the webdriver.AbstractBuilder.SERVER_URL_ENV + upon creation of this instance.

Parameters
url: string
URL of the server to use.
Returns
This Builder instance for chain calling.

Sets the desired capabilities when requesting a new session. This will + overwrite any previously set desired capabilities.

Parameters
capabilities: !(Object|webdriver.Capabilities)
The desired + capabilities for a new session.
Returns
This Builder instance for chain calling.

Instance Properties

Defined in webdriver.Builder

ID of an existing WebDriver session that new clients should use. + Initialized from the value of the + webdriver.AbstractBuilder.SESSION_ID_ENV environment variable, but + may be overridden using + webdriver.AbstractBuilder#usingSession.

Defined in webdriver.AbstractBuilder

The desired capabilities to use when creating a new session.

URL of the remote server to use for new clients; initialized from the + value of the webdriver.AbstractBuilder.SERVER_URL_ENV environment + variable, but may be overridden using + webdriver.AbstractBuilder#usingServer.

Static Properties

Environment variable that defines the session ID of an existing WebDriver + session to use when creating clients. If set, all new Builder instances will + default to creating clients that use this session. To create a new session, + use #useExistingSession(boolean). The use of this environment + variable requires that webdriver.AbstractBuilder.SERVER_URL_ENV also + be set.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_Capabilities.html b/node_modules/selenium-webdriver/docs/class_webdriver_Capabilities.html new file mode 100644 index 0000000..12d3834 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_Capabilities.html @@ -0,0 +1,9 @@ +webdriver.Capabilities

Class webdriver.Capabilities

code »

Constructor

webdriver.Capabilities ( opt_other )
Parameters
opt_other: (webdriver.Capabilities|Object)=
Another set of + capabilities to merge into this instance.
Show:

Instance Methods

code »get ( key )*
Parameters
key: string
The capability to return.
Returns
The capability with the given key, or null if it has + not been set.
code »has ( key )boolean
Parameters
key: string
The capability to check.
Returns
Whether the specified capability is set.

Merges another set of capabilities into this instance. Any duplicates in + the provided set will override those already set on this instance.

Parameters
other: !(webdriver.Capabilities|Object)
The capabilities to + merge into this instance.
Returns
A self reference.
Parameters
key: string
The capability to set.
value: *
The capability value. Capability values must be JSON + serializable. Pass null to unset the capability.
Returns
A self reference.
Returns
The JSON representation of this instance.

Instance Properties

Static Functions

Returns
A basic set of capabilities for Android.
Returns
A basic set of capabilities for Chrome.
Returns
A basic set of capabilities for Firefox.
Returns
A basic set of capabilities for HTMLUnit.
Returns
A basic set of capabilities for HTMLUnit + with enabled Javascript.
Returns
A basic set of capabilities for + Internet Explorer.
Returns
A basic set of capabilities for iPad.
Returns
A basic set of capabilities for iPhone.
Returns
A basic set of capabilities for Opera.
Returns
A basic set of capabilities for + PhantomJS.
Returns
A basic set of capabilities for Safari.
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_Command.html b/node_modules/selenium-webdriver/docs/class_webdriver_Command.html new file mode 100644 index 0000000..77ec1da --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_Command.html @@ -0,0 +1 @@ +webdriver.Command

Class webdriver.Command

code »

Describes a command to be executed by the WebDriverJS framework.

Constructor

webdriver.Command ( name )
Parameters
name: !webdriver.CommandName
The name of this command.
Show:

Instance Methods

Returns
This command's name.
code »getParameter ( key )*

Returns a named command parameter.

Parameters
key: string
The parameter key to look up.
Returns
The parameter value, or undefined if it has not been set.
Returns
The parameters to send with this command.

Sets a parameter to send with this command.

Parameters
name: string
The parameter name.
value: *
The parameter value.
Returns
A self reference.

Sets the parameters for this command.

Parameters
parameters: !Object
The command parameters.
Returns
A self reference.

Instance Properties

The parameters to this command.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_EventEmitter.html b/node_modules/selenium-webdriver/docs/class_webdriver_EventEmitter.html new file mode 100644 index 0000000..0289852 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_EventEmitter.html @@ -0,0 +1,7 @@ +webdriver.EventEmitter

Class webdriver.EventEmitter

code »

Object that can emit events for others to listen for. This is used instead + of Closure's event system because it is much more light weight. The API is + based on Node's EventEmitters.

Constructor

webdriver.EventEmitter ( )
Show:

Instance Methods

code »addListener ( type, listenerFn, opt_scope )!webdriver.EventEmitter

Registers a listener.

Parameters
type: string
The type of event to listen for.
listenerFn: !Function
The function to invoke when the event is fired.
opt_scope: Object=
The object in whose scope to invoke the listener.
Returns
A self reference.
code »addListener_ ( type, listenerFn, opt_scope, opt_oneshot )!webdriver.EventEmitter

Registers a listener.

Parameters
type: string
The type of event to listen for.
listenerFn: !Function
The function to invoke when the event is fired.
opt_scope: Object=
The object in whose scope to invoke the listener.
opt_oneshot: boolean=
Whether the listener should be removed after + the first event is fired.
Returns
A self reference.
code »emit ( type, var_args )

Fires an event and calls all listeners.

Parameters
type: string
The type of event to emit.
var_args: ...*
Any arguments to pass to each listener.
code »listeners ( type )!Array

Returns a mutable list of listeners for a specific type of event.

Parameters
type: string
The type of event to retrieve the listeners for.
Returns
The registered listeners for + the given event type.
code »on ( type, listenerFn, opt_scope )!webdriver.EventEmitter

An alias for #addListener().

Parameters
type: string
The type of event to listen for.
listenerFn: !Function
The function to invoke when the event is fired.
opt_scope: Object=
The object in whose scope to invoke the listener.
Returns
A self reference.
code »once ( type, listenerFn, opt_scope )!webdriver.EventEmitter

Registers a one-time listener which will be called only the first time an + event is emitted, after which it will be removed.

Parameters
type: string
The type of event to listen for.
listenerFn: !Function
The function to invoke when the event is fired.
opt_scope: Object=
The object in whose scope to invoke the listener.
Returns
A self reference.

Removes all listeners for a specific type of event. If no event is + specified, all listeners across all types will be removed.

Parameters
opt_type: string=
The type of event to remove listeners from.
Returns
A self reference.

Removes a previously registered event listener.

Parameters
type: string
The type of event to unregister.
listenerFn: !Function
The handler function to remove.
Returns
A self reference.

Instance Properties

Map of events to registered listeners.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_FirefoxDomExecutor.html b/node_modules/selenium-webdriver/docs/class_webdriver_FirefoxDomExecutor.html new file mode 100644 index 0000000..2e72f35 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_FirefoxDomExecutor.html @@ -0,0 +1,2 @@ +webdriver.FirefoxDomExecutor

Class webdriver.FirefoxDomExecutor

code »
All implemented interfaces:
webdriver.CommandExecutor

Constructor

webdriver.FirefoxDomExecutor ( )

Enumerations

webdriver.FirefoxDomExecutor.Attribute_
Attributes used to communicate with the FirefoxDriver extension.
webdriver.FirefoxDomExecutor.EventType_
Events used to communicate with the FirefoxDriver extension.
Show:

Instance Methods

code »execute ( command, callback )
Parameters
command
callback

Instance Properties

code »pendingCommand_ : ?{name: string, callback: !Function}

The pending command, if any.

Static Functions

Returns
Whether the current environment supports the + FirefoxDomExecutor.
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_Locator.html b/node_modules/selenium-webdriver/docs/class_webdriver_Locator.html new file mode 100644 index 0000000..c6876e3 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_Locator.html @@ -0,0 +1,2 @@ +webdriver.Locator

Class webdriver.Locator

code »

An element locator.

Constructor

webdriver.Locator ( using, value )
Parameters
using: string
The type of strategy to use for this locator.
value: string
The search target of this locator.
Show:

Instance Methods

code »toString ( )string

Instance Properties

The search strategy to use when searching for an element.

The search target for this locator.

Static Functions

Verifies that a value is a valid locator to use for searching for + elements on the page.

Parameters
value: *
The value to check is a valid locator.
Returns
A valid locator object or function.
Throws
TypeError
If the given value is an invalid locator.

Creates a factory function for a webdriver.Locator.

Parameters
type: string
The type of locator for the factory.
Returns
The new factory function.
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_Session.html b/node_modules/selenium-webdriver/docs/class_webdriver_Session.html new file mode 100644 index 0000000..5aa83a4 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_Session.html @@ -0,0 +1,3 @@ +webdriver.Session

Class webdriver.Session

code »

Contains information about a WebDriver session.

Constructor

webdriver.Session ( id, capabilities )
Parameters
id: string
The session ID.
capabilities: !(Object|webdriver.Capabilities)
The session + capabilities.
Show:

Instance Methods

Returns
This session's capabilities.
code »getCapability ( key )*

Retrieves the value of a specific capability.

Parameters
key: string
The capability to retrieve.
Returns
The capability value.
Returns
This session's ID.

Returns the JSON representation of this object, which is just the string + session ID.

Returns
The JSON representation of this Session.

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_UnhandledAlertError.html b/node_modules/selenium-webdriver/docs/class_webdriver_UnhandledAlertError.html new file mode 100644 index 0000000..6162b91 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_UnhandledAlertError.html @@ -0,0 +1,6 @@ +webdriver.UnhandledAlertError

Class webdriver.UnhandledAlertError

code »
Error
+  └ bot.Error
+      └ webdriver.UnhandledAlertError

An error returned to indicate that there is an unhandled modal dialog on the + current page.

Constructor

webdriver.UnhandledAlertError ( message, alert )
Parameters
message: string
The error message.
alert: !webdriver.Alert
The alert handle.
Show:

Instance Methods

Defined in webdriver.UnhandledAlertError

Returns
The open alert.

Defined in bot.Error

Returns
he string representation of this error.

Instance Properties

Defined in webdriver.UnhandledAlertError

Defined in bot.Error

Flag used for duck-typing when this code is embedded in a Firefox extension. + This is required since an Error thrown in one component and then reported + to another will fail instanceof checks in the second component.

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver.html b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver.html new file mode 100644 index 0000000..d49e341 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver.html @@ -0,0 +1,259 @@ +webdriver.WebDriver

Class webdriver.WebDriver

code »

Creates a new WebDriver client, which provides control over a browser. + + Every WebDriver command returns a webdriver.promise.Promise that + represents the result of that command. Callbacks may be registered on this + object to manipulate the command result or catch an expected error. Any + commands scheduled with a callback are considered sub-commands and will + execute before the next command in the current frame. For example: +


+   var message = [];
+   driver.call(message.push, message, 'a').then(function() {
+     driver.call(message.push, message, 'b');
+   });
+   driver.call(message.push, message, 'c');
+   driver.call(function() {
+     alert('message is abc? ' + (message.join('') == 'abc'));
+   });
+ 

Constructor

webdriver.WebDriver ( session, executor, opt_flow )
Parameters
session: !(webdriver.Session|webdriver.promise.Promise)
Either a + known session or a promise that will be resolved to a session.
executor: !webdriver.CommandExecutor
The executor to use when + sending commands to the browser.
opt_flow: webdriver.promise.ControlFlow=
The flow to + schedule commands through. Defaults to the active flow object.

Classes

webdriver.WebDriver.Logs
Interface for managing WebDriver log records.
webdriver.WebDriver.Navigation
Interface for navigating back and forth in the browser history.
webdriver.WebDriver.Options
Provides methods for managing browser and driver state.
webdriver.WebDriver.TargetLocator
An interface for changing the focus of the driver to another frame or window.
webdriver.WebDriver.Timeouts
An interface for managing timeout behavior for WebDriver instances.
webdriver.WebDriver.Window
An interface for managing the current window.
Show:

Instance Methods

Creates a new action sequence using this driver. The sequence will not be + scheduled for execution until webdriver.ActionSequence#perform is + called. Example: +


+   driver.actions().
+       mouseDown(element1).
+       mouseMove(element2).
+       mouseUp().
+       perform();
+ 
Returns
A new action sequence for this instance.
code »<T> call ( fn, opt_scope, var_args )!webdriver.promise.Promise.<T>

Schedules a command to execute a custom function.

Parameters
fn: function(...): (T|webdriver.promise.Promise.<T>)
The function to + execute.
opt_scope: Object=
The object in whose scope to execute the function.
var_args: ...*
Any arguments to pass to the function.
Returns
A promise that will be resolved' + with the function's result.

Schedules a command to close the current window.

Returns
A promise that will be resolved + when this command has completed.
Returns
The control flow used by this + instance.
code »<T> executeAsyncScript ( script, var_args )!webdriver.promise.Promise.<T>

Schedules a command to execute asynchronous JavaScript in the context of the + currently selected frame or window. The script fragment will be executed as + the body of an anonymous function. If the script is provided as a function + object, that function will be converted to a string for injection into the + target window. + + Any arguments provided in addition to the script will be included as script + arguments and may be referenced using the arguments object. + Arguments may be a boolean, number, string, or webdriver.WebElement. + Arrays and objects may also be used as script arguments as long as each item + adheres to the types previously mentioned. + + Unlike executing synchronous JavaScript with + webdriver.WebDriver.prototype.executeScript, scripts executed with + this function must explicitly signal they are finished by invoking the + provided callback. This callback will always be injected into the + executed function as the last argument, and thus may be referenced with + arguments[arguments.length - 1]. The following steps will be taken + for resolving this functions return value against the first argument to the + script's callback function: +

    +
  • For a HTML element, the value will resolve to a + webdriver.WebElement
  • +
  • Null and undefined return values will resolve to null
  • +
  • Booleans, numbers, and strings will resolve as is
  • +
  • Functions will resolve to their string representation
  • +
  • For arrays and objects, each member item will be converted according to + the rules above
  • +
+ + Example #1: Performing a sleep that is synchronized with the currently + selected window: +
+ var start = new Date().getTime();
+ driver.executeAsyncScript(
+     'window.setTimeout(arguments[arguments.length - 1], 500);').
+     then(function() {
+       console.log('Elapsed time: ' + (new Date().getTime() - start) + ' ms');
+     });
+ 
+ + Example #2: Synchronizing a test with an AJAX application: +
+ var button = driver.findElement(By.id('compose-button'));
+ button.click();
+ driver.executeAsyncScript(
+     'var callback = arguments[arguments.length - 1];' +
+     'mailClient.getComposeWindowWidget().onload(callback);');
+ driver.switchTo().frame('composeWidget');
+ driver.findElement(By.id('to')).sendKEys('dog@example.com');
+ 
+ + Example #3: Injecting a XMLHttpRequest and waiting for the result. In this + example, the inject script is specified with a function literal. When using + this format, the function is converted to a string for injection, so it + should not reference any symbols not defined in the scope of the page under + test. +
+ driver.executeAsyncScript(function() {
+   var callback = arguments[arguments.length - 1];
+   var xhr = new XMLHttpRequest();
+   xhr.open("GET", "/resource/data.json", true);
+   xhr.onreadystatechange = function() {
+     if (xhr.readyState == 4) {
+       callback(xhr.resposneText);
+     }
+   }
+   xhr.send('');
+ }).then(function(str) {
+   console.log(JSON.parse(str)['food']);
+ });
+ 
Parameters
script: !(string|Function)
The script to execute.
var_args: ...*
The arguments to pass to the script.
Returns
A promise that will resolve to the + scripts return value.
code »<T> executeScript ( script, var_args )!webdriver.promise.Promise.<T>

Schedules a command to execute JavaScript in the context of the currently + selected frame or window. The script fragment will be executed as the body + of an anonymous function. If the script is provided as a function object, + that function will be converted to a string for injection into the target + window. + + Any arguments provided in addition to the script will be included as script + arguments and may be referenced using the arguments object. + Arguments may be a boolean, number, string, or webdriver.WebElement. + Arrays and objects may also be used as script arguments as long as each item + adheres to the types previously mentioned. + + The script may refer to any variables accessible from the current window. + Furthermore, the script will execute in the window's context, thus + document may be used to refer to the current document. Any local + variables will not be available once the script has finished executing, + though global variables will persist. + + If the script has a return value (i.e. if the script contains a return + statement), then the following steps will be taken for resolving this + functions return value: +

    +
  • For a HTML element, the value will resolve to a + webdriver.WebElement
  • +
  • Null and undefined return values will resolve to null
  • +
  • Booleans, numbers, and strings will resolve as is
  • +
  • Functions will resolve to their string representation
  • +
  • For arrays and objects, each member item will be converted according to + the rules above
  • +
Parameters
script: !(string|Function)
The script to execute.
var_args: ...*
The arguments to pass to the script.
Returns
A promise that will resolve to the + scripts return value.

Locates a DOM element so that commands may be issued against it using the + webdriver.WebElement class. This is accomplished by storing a + reference to the element in an object on the element's ownerDocument. + #executeScript will then be used to create a WebElement from this + reference. This requires this driver to currently be focused on the + ownerDocument's window+frame.

Parameters
element: !Element
The element to locate.
Returns
A promise that + will be fulfilled with the located element, or null if the element + could not be found.

Schedule a command to find an element on the page. If the element cannot be + found, a bot.ErrorCode.NO_SUCH_ELEMENT result will be returned + by the driver. Unlike other commands, this error cannot be suppressed. In + other words, scheduling a command to find an element doubles as an assert + that the element is present on the page. To test whether an element is + present on the page, use #isElementPresent instead. + +

The search criteria for an element may be defined using one of the + factories in the webdriver.By namespace, or as a short-hand + webdriver.By.Hash object. For example, the following two statements + are equivalent: +

+ var e1 = driver.findElement(By.id('foo'));
+ var e2 = driver.findElement({id:'foo'});
+ 
+ +

You may also provide a custom locator function, which takes as input + this WebDriver instance and returns a webdriver.WebElement, or a + promise that will resolve to a WebElement. For example, to find the first + visible link on a page, you could write: +

+ var link = driver.findElement(firstVisibleLink);
+
+ function firstVisibleLink(driver) {
+   var links = driver.findElements(By.tagName('a'));
+   return webdriver.promise.filter(links, function(link) {
+     return links.isDisplayed();
+   }).then(function(visibleLinks) {
+     return visibleLinks[0];
+   });
+ }
+ 
+ +

When running in the browser, a WebDriver cannot manipulate DOM elements + directly; it may do so only through a webdriver.WebElement reference. + This function may be used to generate a WebElement from a DOM element. A + reference to the DOM element will be stored in a known location and this + driver will attempt to retrieve it through #executeScript. If the + element cannot be found (eg, it belongs to a different document than the + one this instance is currently focused on), a + bot.ErrorCode.NO_SUCH_ELEMENT error will be returned.

Parameters
locator: !(webdriver.Locator|webdriver.By.Hash|Element|Function)
The + locator to use.
Returns
A WebElement that can be used to issue + commands against the located element. If the element is not found, the + element will be invalidated and all scheduled commands aborted.
Parameters
locatorFn: !Function
The locator function to use.
context: !(webdriver.WebDriver|webdriver.WebElement)
The search + context.
Returns
A + promise that will resolve to a list of WebElements.

Schedule a command to search for multiple elements on the page.

Parameters
locator: !(webdriver.Locator|webdriver.By.Hash|Function)
The locator + strategy to use when searching for the element.
Returns
A + promise that will resolve to an array of WebElements.
Parameters
locatorFn: !Function
The locator function to use.
context: !(webdriver.WebDriver|webdriver.WebElement)
The search + context.
Returns
A + promise that will resolve to an array of WebElements.

Schedules a command to navigate to the given URL.

Parameters
url: string
The fully qualified URL to open.
Returns
A promise that will be resolved + when the document has finished loading.

Schedules a command to retrieve the current list of available window handles.

Returns
A promise that will + be resolved with an array of window handles.
Returns
A promise + that will resolve with the this instance's capabilities.

Schedules a command to retrieve the URL of the current page.

Returns
A promise that will be + resolved with the current URL.

Schedules a command to retrieve the current page's source. The page source + returned is a representation of the underlying DOM: do not expect it to be + formatted or escaped in the same way as the response sent from the web + server.

Returns
A promise that will be + resolved with the current page source.
Returns
A promise for this + client's session.

Schedules a command to retrieve the current page's title.

Returns
A promise that will be + resolved with the current page's title.

Schedules a command to retrieve they current window handle.

Returns
A promise that will be + resolved with the current window handle.

Schedules a command to test if an element is present on the page. + +

If given a DOM element, this function will check if it belongs to the + document the driver is currently focused on. Otherwise, the function will + test if at least one element can be found with the given search criteria.

Parameters
locatorOrElement: !(webdriver.Locator|webdriver.By.Hash|Element|Function)
The locator to use, or the actual + DOM element to be located by the server.
Returns
A promise that will resolve + with whether the element is present on the page.
Returns
The options interface for this + instance.
Returns
The navigation interface for this + instance.

Schedules a command to quit the current session. After calling quit, this + instance will be invalidated and may no longer be used to issue commands + against the browser.

Returns
A promise that will be resolved + when the command has completed.
code »<T> schedule ( command, description )!webdriver.promise.Promise.<T>

Schedules a webdriver.Command to be executed by this driver's + webdriver.CommandExecutor.

Parameters
command: !webdriver.Command
The command to schedule.
description: string
A description of the command for debugging.
Returns
A promise that will be resolved + with the command result.

Schedules a command to make the driver sleep for the given amount of time.

Parameters
ms: number
The amount of time, in milliseconds, to sleep.
Returns
A promise that will be resolved + when the sleep has finished.
Returns
The target locator interface for + this instance.

Schedule a command to take a screenshot. The driver makes a best effort to + return a screenshot of the following, in order of preference: +

    +
  1. Entire page +
  2. Current window +
  3. Visible portion of the current frame +
  4. The screenshot of the entire display containing the browser +
Returns
A promise that will be + resolved to the screenshot as a base-64 encoded PNG.
code »wait ( fn, timeout, opt_message )!webdriver.promise.Promise

Schedules a command to wait for a condition to hold, as defined by some + user supplied function. If any errors occur while evaluating the wait, they + will be allowed to propagate. + +

In the event a condition returns a webdriver.promise.Promise, the + polling loop will wait for it to be resolved and use the resolved value for + evaluating whether the condition has been satisfied. The resolution time for + a promise is factored into whether a wait has timed out.

Parameters
fn: function(): boolean
The function to evaluate as a wait condition.
timeout: number
How long to wait for the condition to be true.
opt_message: string=
An optional message to use if the wait times + out.
Returns
A promise that will be resolved when the + wait condition has been satisfied.

Instance Properties

Static Functions

code »webdriver.WebDriver.acquireSession_ ( executor, command, description )!webdriver.WebDriver

Sends a command to the server that is expected to return the details for a + webdriver.Session. This may either be an existing session, or a + newly created one.

Parameters
executor: !webdriver.CommandExecutor
Command executor to use when + querying for session details.
command: !webdriver.Command
The command to send to fetch the session + details.
description: string
A descriptive debug label for this action.
Returns
A new WebDriver client for the session.

Creates a new WebDriver client for an existing session.

Parameters
executor: !webdriver.CommandExecutor
Command executor to use when + querying for session details.
sessionId: string
ID of the session to attach to.
Returns
A new client for the specified session.
code »webdriver.WebDriver.createSession ( executor, desiredCapabilities )!webdriver.WebDriver

Creates a new WebDriver session.

Parameters
executor: !webdriver.CommandExecutor
The executor to create the new + session with.
desiredCapabilities: !webdriver.Capabilities
The desired + capabilities for the new session.
Returns
The driver for the newly created session.

Translates a command to its wire-protocol representation before passing it + to the given executor for execution.

Parameters
executor: !webdriver.CommandExecutor
The executor to use.
command: !webdriver.Command
The command to execute.
Returns
A promise that will resolve with the + command response.

Converts a value from its JSON representation according to the WebDriver wire + protocol. Any JSON object containing a + webdriver.WebElement.ELEMENT_KEY key will be decoded to a + webdriver.WebElement object. All other values will be passed through + as is.

Parameters
driver: !webdriver.WebDriver
The driver instance to use as the + parent of any unwrapped webdriver.WebElement values.
value: *
The value to convert.
Returns
The converted value.

Converts an object to its JSON representation in the WebDriver wire protocol. + When converting values of type object, the following steps will be taken: +

    +
  1. if the object provides a "toWireValue" function, the return value will + be returned in its fully resolved state (e.g. this function may return + promise values)
  2. +
  3. if the object provides a "toJSON" function, the return value of this + function will be returned
  4. +
  5. otherwise, the value of each key will be recursively converted according + to the rules above.
  6. +
Parameters
obj: *
The object to convert.
Returns
A promise that will resolve to the + input value's JSON representation.
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Logs.html b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Logs.html new file mode 100644 index 0000000..a4976c6 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Logs.html @@ -0,0 +1,10 @@ +webdriver.WebDriver.Logs

Class webdriver.WebDriver.Logs

code »

Interface for managing WebDriver log records.

Constructor

webdriver.WebDriver.Logs ( driver )
Parameters
driver: !webdriver.WebDriver
The parent driver.
Show:

Instance Methods

Fetches available log entries for the given type. + +

Note that log buffers are reset after each call, meaning that + available log entries correspond to those entries not yet returned for a + given log type. In practice, this means that this call will return the + available log entries since the last call, or from the start of the + session.

Parameters
type: !webdriver.logging.Type
The desired log type.
Returns
A + promise that will resolve to a list of log entries for the specified + type.

Retrieves the log types available to this driver.

Returns
A + promise that will resolve to a list of available log types.

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Navigation.html b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Navigation.html new file mode 100644 index 0000000..d2ac0db --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Navigation.html @@ -0,0 +1,5 @@ +webdriver.WebDriver.Navigation

Class webdriver.WebDriver.Navigation

code »

Interface for navigating back and forth in the browser history.

Constructor

webdriver.WebDriver.Navigation ( driver )
Parameters
driver: !webdriver.WebDriver
The parent driver.
Show:

Instance Methods

Schedules a command to move backwards in the browser history.

Returns
A promise that will be resolved + when the navigation event has completed.

Schedules a command to move forwards in the browser history.

Returns
A promise that will be resolved + when the navigation event has completed.

Schedules a command to refresh the current page.

Returns
A promise that will be resolved + when the navigation event has completed.

Schedules a command to navigate to a new URL.

Parameters
url: string
The URL to navigate to.
Returns
A promise that will be resolved + when the URL has been loaded.

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Options.html b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Options.html new file mode 100644 index 0000000..3e4e2f1 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Options.html @@ -0,0 +1,17 @@ +webdriver.WebDriver.Options

Class webdriver.WebDriver.Options

code »

Provides methods for managing browser and driver state.

Constructor

webdriver.WebDriver.Options ( driver )
Parameters
driver: !webdriver.WebDriver
The parent driver.
Show:

Type Definitions

A JSON description of a browser cookie.

Instance Methods

code »addCookie ( name, value, opt_path, opt_domain, opt_isSecure, opt_expiry )!webdriver.promise.Promise.<void>

Schedules a command to add a cookie.

Parameters
name: string
The cookie name.
value: string
The cookie value.
opt_path: string=
The cookie path.
opt_domain: string=
The cookie domain.
opt_isSecure: boolean=
Whether the cookie is secure.
opt_expiry: (number|!Date)=
When the cookie expires. If specified as + a number, should be in milliseconds since midnight, January 1, 1970 UTC.
Returns
A promise that will be resolved + when the cookie has been added to the page.

Schedules a command to delete all cookies visible to the current page.

Returns
A promise that will be resolved + when all cookies have been deleted.

Schedules a command to delete the cookie with the given name. This command is + a no-op if there is no cookie with the given name visible to the current + page.

Parameters
name: string
The name of the cookie to delete.
Returns
A promise that will be resolved + when the cookie has been deleted.

Schedules a command to retrieve the cookie with the given name. Returns null + if there is no such cookie. The cookie will be returned as a JSON object as + described by the WebDriver wire protocol.

Parameters
name: string
The name of the cookie to retrieve.
Returns
A + promise that will be resolved with the named cookie, or null + if there is no such cookie.

Schedules a command to retrieve all cookies visible to the current page. + Each cookie will be returned as a JSON object as described by the WebDriver + wire protocol.

Returns
A promise that will be + resolved with the cookies visible to the current page.
Returns
The interface for managing driver + logs.
Returns
The interface for managing driver + timeouts.
Returns
The interface for managing the + current window.

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_TargetLocator.html b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_TargetLocator.html new file mode 100644 index 0000000..b63420e --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_TargetLocator.html @@ -0,0 +1,27 @@ +webdriver.WebDriver.TargetLocator

Class webdriver.WebDriver.TargetLocator

code »

An interface for changing the focus of the driver to another frame or window.

Constructor

webdriver.WebDriver.TargetLocator ( driver )
Parameters
driver: !webdriver.WebDriver
The parent driver.
Show:

Instance Methods

Schedules a command retrieve the document.activeElement element on + the current document, or document.body if activeElement is not + available.

Returns
The active element.

Schedules a command to change focus to the active alert dialog. This command + will return a bot.ErrorCode.NO_MODAL_DIALOG_OPEN error if a modal + dialog is not currently open.

Returns
The open alert.

Schedules a command to switch focus of all future commands to the first frame + on the page.

Returns
A promise that will be resolved + when the driver has changed focus to the default content.
code »frame ( nameOrIndex )!webdriver.promise.Promise.<void>

Schedules a command to switch the focus of all future commands to another + frame on the page. +

+ If the frame is specified by a number, the command will switch to the frame + by its (zero-based) index into the window.frames collection. +

+ If the frame is specified by a string, the command will select the frame by + its name or ID. To select sub-frames, simply separate the frame names/IDs by + dots. As an example, "main.child" will select the frame with the name "main" + and then its child "child". +

+ If the specified frame can not be found, the deferred result will errback + with a bot.ErrorCode.NO_SUCH_FRAME error.

Parameters
nameOrIndex: (string|number)
The frame locator.
Returns
A promise that will be resolved + when the driver has changed focus to the specified frame.
code »window ( nameOrHandle )!webdriver.promise.Promise.<void>

Schedules a command to switch the focus of all future commands to another + window. Windows may be specified by their window.name attribute or + by its handle (as returned by webdriver.WebDriver#getWindowHandles). +

+ If the specificed window can not be found, the deferred result will errback + with a bot.ErrorCode.NO_SUCH_WINDOW error.

Parameters
nameOrHandle: string
The name or window handle of the window to + switch focus to.
Returns
A promise that will be resolved + when the driver has changed focus to the specified window.

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Timeouts.html b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Timeouts.html new file mode 100644 index 0000000..918a6bc --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Timeouts.html @@ -0,0 +1,21 @@ +webdriver.WebDriver.Timeouts

Class webdriver.WebDriver.Timeouts

code »

An interface for managing timeout behavior for WebDriver instances.

Constructor

webdriver.WebDriver.Timeouts ( driver )
Parameters
driver: !webdriver.WebDriver
The parent driver.
Show:

Instance Methods

Specifies the amount of time the driver should wait when searching for an + element if it is not immediately present. +

+ When searching for a single element, the driver should poll the page + until the element has been found, or this timeout expires before failing + with a bot.ErrorCode.NO_SUCH_ELEMENT error. When searching + for multiple elements, the driver should poll the page until at least one + element has been found or this timeout has expired. +

+ Setting the wait timeout to 0 (its default value), disables implicit + waiting. +

+ Increasing the implicit wait timeout should be used judiciously as it + will have an adverse effect on test run time, especially when used with + slower location strategies like XPath.

Parameters
ms: number
The amount of time to wait, in milliseconds.
Returns
A promise that will be resolved + when the implicit wait timeout has been set.

Sets the amount of time to wait for a page load to complete before returning + an error. If the timeout is negative, page loads may be indefinite.

Parameters
ms: number
The amount of time to wait, in milliseconds.
Returns
A promise that will be resolved + when the timeout has been set.

Sets the amount of time to wait, in milliseconds, for an asynchronous script + to finish execution before returning an error. If the timeout is less than or + equal to 0, the script will be allowed to run indefinitely.

Parameters
ms: number
The amount of time to wait, in milliseconds.
Returns
A promise that will be resolved + when the script timeout has been set.

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Window.html b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Window.html new file mode 100644 index 0000000..16c1183 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_WebDriver_Window.html @@ -0,0 +1,11 @@ +webdriver.WebDriver.Window

Class webdriver.WebDriver.Window

code »

An interface for managing the current window.

Constructor

webdriver.WebDriver.Window ( driver )
Parameters
driver: !webdriver.WebDriver
The parent driver.
Show:

Instance Methods

Retrieves the window's current position, relative to the top left corner of + the screen.

Returns
A promise that + will be resolved with the window's position in the form of a + {x:number, y:number} object literal.

Retrieves the window's current size.

Returns
A + promise that will be resolved with the window's size in the form of a + {width:number, height:number} object literal.

Maximizes the current window.

Returns
A promise that will be resolved + when the command has completed.

Repositions the current window.

Parameters
x: number
The desired horizontal position, relative to the left side + of the screen.
y: number
The desired vertical position, relative to the top of the + of the screen.
Returns
A promise that will be resolved + when the command has completed.
code »setSize ( width, height )!webdriver.promise.Promise.<void>

Resizes the current window.

Parameters
width: number
The desired window width.
height: number
The desired window height.
Returns
A promise that will be resolved + when the command has completed.

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_WebElement.html b/node_modules/selenium-webdriver/docs/class_webdriver_WebElement.html new file mode 100644 index 0000000..a52b8e5 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_WebElement.html @@ -0,0 +1,231 @@ +webdriver.WebElement

Class webdriver.WebElement

code »
webdriver.promise.Promise.<(T|null)>
+  └ webdriver.promise.Deferred
+      └ webdriver.WebElement

Represents a DOM element. WebElements can be found by searching from the + document root using a webdriver.WebDriver instance, or by searching + under another webdriver.WebElement: +


+   driver.get('http://www.google.com');
+   var searchForm = driver.findElement(By.tagName('form'));
+   var searchBox = searchForm.findElement(By.name('q'));
+   searchBox.sendKeys('webdriver');
+ 
+ + The WebElement is implemented as a promise for compatibility with the promise + API. It will always resolve itself when its internal state has been fully + resolved and commands may be issued against the element. This can be used to + catch errors when an element cannot be located on the page: +

+   driver.findElement(By.id('not-there')).then(function(element) {
+     alert('Found an element that was not expected to be there!');
+   }, function(error) {
+     alert('The element was not found, as expected');
+   });
+ 

Constructor

webdriver.WebElement ( driver, id )
Parameters
driver: !webdriver.WebDriver
The parent WebDriver instance for this + element.
id: !(string|webdriver.promise.Promise)
Either the opaque ID for the + underlying DOM element assigned by the server, or a promise that will + resolve to that ID or another WebElement.
Show:

Type Definitions

Wire protocol definition of a WebElement ID.

Instance Methods

Defined in webdriver.WebElement

Schedules a command to clear the value of this element. This command + has no effect if the underlying DOM element is neither a text INPUT element + nor a TEXTAREA element.

Returns
A promise that will be resolved + when the element has been cleared.

Schedules a command to click on this element.

Returns
A promise that will be resolved + when the click command has completed.

Schedule a command to find a descendant of this element. If the element + cannot be found, a bot.ErrorCode.NO_SUCH_ELEMENT result will + be returned by the driver. Unlike other commands, this error cannot be + suppressed. In other words, scheduling a command to find an element doubles + as an assert that the element is present on the page. To test whether an + element is present on the page, use #isElementPresent instead. + +

The search criteria for an element may be defined using one of the + factories in the webdriver.By namespace, or as a short-hand + webdriver.By.Hash object. For example, the following two statements + are equivalent: +

+ var e1 = element.findElement(By.id('foo'));
+ var e2 = element.findElement({id:'foo'});
+ 
+ +

You may also provide a custom locator function, which takes as input + this WebDriver instance and returns a webdriver.WebElement, or a + promise that will resolve to a WebElement. For example, to find the first + visible link on a page, you could write: +

+ var link = element.findElement(firstVisibleLink);
+
+ function firstVisibleLink(element) {
+   var links = element.findElements(By.tagName('a'));
+   return webdriver.promise.filter(links, function(link) {
+     return links.isDisplayed();
+   }).then(function(visibleLinks) {
+     return visibleLinks[0];
+   });
+ }
+ 
Parameters
locator: !(webdriver.Locator|webdriver.By.Hash|Function)
The + locator strategy to use when searching for the element.
Returns
A WebElement that can be used to issue + commands against the located element. If the element is not found, the + element will be invalidated and all scheduled commands aborted.

Schedules a command to find all of the descendants of this element that + match the given search criteria.

Parameters
locator: !(webdriver.Locator|webdriver.By.Hash|Function)
The + locator strategy to use when searching for the elements.
Returns
A + promise that will resolve to an array of WebElements.

Schedules a command to query for the value of the given attribute of the + element. Will return the current value, even if it has been modified after + the page has been loaded. More exactly, this method will return the value of + the given attribute, unless that attribute is not present, in which case the + value of the property with the same name is returned. If neither value is + set, null is returned (for example, the "value" property of a textarea + element). The "style" attribute is converted as best can be to a + text representation with a trailing semi-colon. The following are deemed to + be "boolean" attributes and will return either "true" or null: + +

async, autofocus, autoplay, checked, compact, complete, controls, declare, + defaultchecked, defaultselected, defer, disabled, draggable, ended, + formnovalidate, hidden, indeterminate, iscontenteditable, ismap, itemscope, + loop, multiple, muted, nohref, noresize, noshade, novalidate, nowrap, open, + paused, pubdate, readonly, required, reversed, scoped, seamless, seeking, + selected, spellcheck, truespeed, willvalidate + +

Finally, the following commonly mis-capitalized attribute/property names + are evaluated as expected: +

    +
  • "class" +
  • "readonly" +
Parameters
attributeName: string
The name of the attribute to query.
Returns
A promise that will be + resolved with the attribute's value. The returned value will always be + either a string or null.

Schedules a command to query for the computed style of the element + represented by this instance. If the element inherits the named style from + its parent, the parent will be queried for its value. Where possible, color + values will be converted to their hex representation (e.g. #00ff00 instead of + rgb(0, 255, 0)). +

+ Warning: the value returned will be as the browser interprets it, so + it may be tricky to form a proper assertion.

Parameters
cssStyleProperty: string
The name of the CSS style property to look + up.
Returns
A promise that will be + resolved with the requested CSS value.
Returns
The parent driver for this instance.

Schedules a command to retrieve the inner HTML of this element.

Returns
A promise that will be + resolved with the element's inner HTML.

Schedules a command to compute the location of this element in page space.

Returns
A promise that + will be resolved to the element's location as a + {x:number, y:number} object.

Schedules a command to retrieve the outer HTML of this element.

Returns
A promise that will be + resolved with the element's outer HTML.

Schedules a command to compute the size of this element's bounding box, in + pixels.

Returns
A + promise that will be resolved with the element's size as a + {width:number, height:number} object.

Schedules a command to query for the tag/node name of this element.

Returns
A promise that will be + resolved with the element's tag name.

Get the visible (i.e. not hidden by CSS) innerText of this element, including + sub-elements, without any leading or trailing whitespace.

Returns
A promise that will be + resolved with the element's visible text.

Schedules a command to test whether this element is currently displayed.

Returns
A promise that will be + resolved with whether this element is currently visible on the page.

Schedules a command to test if there is at least one descendant of this + element that matches the given search criteria.

Parameters
locator: !(webdriver.Locator|webdriver.By.Hash|Function)
The + locator strategy to use when searching for the element.
Returns
A promise that will be + resolved with whether an element could be located on the page.

Schedules a command to query whether the DOM element represented by this + instance is enabled, as dicted by the disabled attribute.

Returns
A promise that will be + resolved with whether this element is currently enabled.

Schedules a command to query whether this element is selected.

Returns
A promise that will be + resolved with whether this element is currently selected.
code »<T> schedule_ ( command, description )!webdriver.promise.Promise.<T>

Schedules a command that targets this element with the parent WebDriver + instance. Will ensure this element's ID is included in the command parameters + under the "id" key.

Parameters
command: !webdriver.Command
The command to schedule.
description: string
A description of the command for debugging.
Returns
A promise that will be resolved + with the command result.

Schedules a command to type a sequence on the DOM element represented by this + instance. +

+ Modifier keys (SHIFT, CONTROL, ALT, META) are stateful; once a modifier is + processed in the keysequence, that key state is toggled until one of the + following occurs: +

    +
  • The modifier key is encountered again in the sequence. At this point the + state of the key is toggled (along with the appropriate keyup/down events). +
  • +
  • The webdriver.Key.NULL key is encountered in the sequence. When + this key is encountered, all modifier keys current in the down state are + released (with accompanying keyup events). The NULL key can be used to + simulate common keyboard shortcuts: +
    +     element.sendKeys("text was",
    +                      webdriver.Key.CONTROL, "a", webdriver.Key.NULL,
    +                      "now text is");
    +     // Alternatively:
    +     element.sendKeys("text was",
    +                      webdriver.Key.chord(webdriver.Key.CONTROL, "a"),
    +                      "now text is");
    + 
  • +
  • The end of the keysequence is encountered. When there are no more keys + to type, all depressed modifier keys are released (with accompanying keyup + events). +
  • +
+ Note: On browsers where native keyboard events are not yet + supported (e.g. Firefox on OS X), key events will be synthesized. Special + punctionation keys will be synthesized according to a standard QWERTY en-us + keyboard layout.
Parameters
var_args: ...string
The sequence of keys to + type. All arguments will be joined into a single sequence (var_args is + permitted for convenience).
Returns
A promise that will be resolved + when all keys have been typed.

Schedules a command to submit the form containing this element (or this + element if it is a FORM element). This command is a no-op if the element is + not contained in a form.

Returns
A promise that will be resolved + when the form has been submitted.
Returns
A promise + that resolves to this element's JSON representation as defined by the + WebDriver wire protocol.

Defined in webdriver.promise.Deferred

code »errback ( opt_error )

Rejects this promise. If the error is itself a promise, this instance will + be chained to it and be rejected with the error's resolved value.

Parameters
opt_error: *=
The rejection reason, typically either a + Error or a string.
code »fulfill ( opt_value )

Resolves this promise with the given value. If the value is itself a + promise and not a reference to this deferred, this instance will wait for + it before resolving.

Parameters
opt_value: T=
The fulfilled value.
code »reject ( opt_error )

Rejects this promise. If the error is itself a promise, this instance will + be chained to it and be rejected with the error's resolved value.

Parameters
opt_error: *=
The rejection reason, typically either a + Error or a string.

Removes all of the listeners previously registered on this deferred.

Throws
Error
If this deferred has already been resolved.

Defined in webdriver.promise.Promise.<(T|null)>

code »cancel ( reason )

Cancels the computation of this promise's value, rejecting the promise in the + process.

Parameters
reason: *
The reason this promise is being cancelled. If not an + Error, one will be created using the value's string + representation.
Returns
Whether this promise's value is still being computed.
code »<R> then ( opt_callback, opt_errback )!webdriver.promise.Promise.<R>

Registers listeners for when this instance is resolved. This function most + overridden by subtypes.

Parameters
opt_callback: ?(function(T): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is successfully resolved. The function + should expect a single argument: the promise's resolved value.
opt_errback: ?(function(*): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is rejected. The function should expect + a single argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener for when this promise is rejected. This is synonymous + with the catch clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } catch (ex) {
+     console.error(ex);
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenCatch(function(ex) {
+     console.error(ex);
+   });
+ 
Parameters
errback: function(*): (R|webdriver.promise.Promise.<R>)
The function + to call if this promise is rejected. The function should expect a single + argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener to invoke when this promise is resolved, regardless + of whether the promise's value was successfully computed. This function + is synonymous with the finally clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } finally {
+     cleanUp();
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenFinally(cleanUp);
+ 
+ + Note: similar to the finally clause, if the registered + callback returns a rejected promise or throws an error, it will silently + replace the rejection error (if any) from this promise: +

+   try {
+     throw Error('one');
+   } finally {
+     throw Error('two');  // Hides Error: one
+   }
+
+   webdriver.promise.rejected(Error('one'))
+       .thenFinally(function() {
+         throw Error('two');  // Hides Error: one
+       });
+ 
Parameters
callback: function(): (R|webdriver.promise.Promise.<R>)
The function + to call when this promise is resolved.
Returns
A promise that will be fulfilled + with the callback result.

Instance Properties

Defined in webdriver.WebElement

The parent WebDriver instance for this element.

A promise that resolves to the JSON representation of this WebElement's + ID, as defined by the WebDriver wire protocol.

Defined in webdriver.promise.Deferred

Represents the eventual value of a completed operation. Each promise may be + in one of three states: pending, resolved, or rejected. Each promise starts + in the pending state and may make a single transition to either a + fulfilled or failed state. + +

This class is based on the Promise/A proposal from CommonJS. Additional + functions are provided for API compatibility with Dojo Deferred objects.

Static Functions

Compares to WebElements for equality.

Parameters
a: !webdriver.WebElement
A WebElement.
b: !webdriver.WebElement
A WebElement.
Returns
A promise that will be + resolved to whether the two WebElements are equal.

Static Properties

The property key used in the wire protocol to indicate that a JSON object + contains the ID of a WebElement.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_http_CorsClient.html b/node_modules/selenium-webdriver/docs/class_webdriver_http_CorsClient.html new file mode 100644 index 0000000..7a7b1f1 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_http_CorsClient.html @@ -0,0 +1,33 @@ +webdriver.http.CorsClient

Class webdriver.http.CorsClient

code »
All implemented interfaces:
webdriver.http.Client

Communicates with a WebDriver server, which may be on a different domain, + using the cross-origin resource sharing + (CORS) extension to WebDriver's JSON wire protocol. + +

Each command from the standard JSON protocol will be encoded in a + JSON object with the following form: + {method:string, path:string, data:!Object} + +

The encoded command is then sent as a POST request to the server's /xdrpc + endpoint. The server will decode the command, re-route it to the appropriate + handler, and then return the command's response as a standard JSON response + object. The JSON responses will always be returned with a 200 + response from the server; clients must rely on the response's "status" field + to determine whether the command succeeded. + +

This client cannot be used with the standard wire protocol due to + limitations in the various browser implementations of the CORS specification: +

    +
  • IE's XDomainRequest object is only + capable of generating the types of requests that may be generated through + a standard HTML form - it can not send + DELETE requests, as is required in the wire protocol. +
  • WebKit's implementation of CORS does not follow the spec and forbids + redirects: https://bugs.webkit.org/show_bug.cgi?id=57600 + This limitation appears to be intentional and is documented in WebKit's + Layout tests: + //LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects.html +
  • If the server does not return a 2xx response, IE and Opera's + implementations will fire the XDomainRequest/XMLHttpRequest object's + onerror handler, but without the corresponding response text returned by + the server. This renders IE and Opera incapable of handling command + failures in the standard JSON protocol. +

Constructor

webdriver.http.CorsClient ( url )
Parameters
url: string
URL for the WebDriver server to send commands to.
Show:

Instance Methods

code »send ( request, callback )
Parameters
request
callback

Instance Properties

Static Functions

Tests whether the current environment supports cross-origin resource sharing.

Returns
Whether cross-origin resource sharing is supported.

Static Properties

Resource URL to send commands to on the server.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_http_Executor.html b/node_modules/selenium-webdriver/docs/class_webdriver_http_Executor.html new file mode 100644 index 0000000..1e656a3 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_http_Executor.html @@ -0,0 +1,8 @@ +webdriver.http.Executor

Class webdriver.http.Executor

code »
All implemented interfaces:
webdriver.CommandExecutor

A command executor that communicates with a server using the WebDriver + command protocol.

Constructor

webdriver.http.Executor ( client )
Parameters
client: !webdriver.http.Client
The client to use when sending + requests to the server.
Show:

Instance Methods

code »execute ( command, callback )
Parameters
command
callback

Instance Properties

Client used to communicate with the server.

Static Functions

Builds a fully qualified path using the given set of command parameters. Each + path segment prefixed with ':' will be replaced by the value of the + corresponding parameter. All parameters spliced into the path will be + removed from the parameter map.

Parameters
path: string
The original resource path.
parameters: !Object
The parameters object to splice into + the path.
Returns
The modified path.

Callback used to parse webdriver.http.Response objects from a + webdriver.http.Client.

Parameters
httpResponse: !webdriver.http.Response
The HTTP response to parse.
Returns
The parsed response.

Static Properties

Maps command names to resource locator.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_http_Request.html b/node_modules/selenium-webdriver/docs/class_webdriver_http_Request.html new file mode 100644 index 0000000..2c4efb5 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_http_Request.html @@ -0,0 +1,4 @@ +webdriver.http.Request

Class webdriver.http.Request

code »

Describes a partial HTTP request. This class is a "partial" request and only + defines the path on the server to send a request to. It is each + webdriver.http.Client's responsibility to build the full URL for the + final request.

Constructor

webdriver.http.Request ( method, path, opt_data )
Parameters
method: string
The HTTP method to use for the request.
path: string
Path on the server to send the request to.
opt_data: Object=
This request's JSON data.
Show:

Instance Methods

code »toString ( )string

Instance Properties

This request's body.

The headers to send with the request.

The HTTP method to use for the request.

The path on the server to send the request to.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_http_Response.html b/node_modules/selenium-webdriver/docs/class_webdriver_http_Response.html new file mode 100644 index 0000000..c39d270 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_http_Response.html @@ -0,0 +1,3 @@ +webdriver.http.Response

Class webdriver.http.Response

code »

Represents a HTTP response.

Constructor

webdriver.http.Response ( status, headers, body )
Parameters
status: number
The response code.
headers: !Object.<string>
The response headers. All header + names will be converted to lowercase strings for consistent lookups.
body: string
The response body.
Show:

Instance Methods

code »toString ( )string

Instance Properties

The response body.

The response body.

The HTTP response code.

Static Functions

Builds a webdriver.http.Response from a XMLHttpRequest or + XDomainRequest response object.

Parameters
xhr: !(XDomainRequest|XMLHttpRequest)
The request to parse.
Returns
The parsed response.
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_http_XhrClient.html b/node_modules/selenium-webdriver/docs/class_webdriver_http_XhrClient.html new file mode 100644 index 0000000..d53dfaa --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_http_XhrClient.html @@ -0,0 +1 @@ +webdriver.http.XhrClient

Class webdriver.http.XhrClient

code »
All implemented interfaces:
webdriver.http.Client

A HTTP client that sends requests using XMLHttpRequests.

Constructor

webdriver.http.XhrClient ( url )
Parameters
url: string
URL for the WebDriver server to send commands to.
Show:

Instance Methods

code »send ( request, callback )
Parameters
request
callback

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_logging_Entry.html b/node_modules/selenium-webdriver/docs/class_webdriver_logging_Entry.html new file mode 100644 index 0000000..c6f0822 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_logging_Entry.html @@ -0,0 +1,4 @@ +webdriver.logging.Entry

Class webdriver.logging.Entry

code »

A single log entry.

Constructor

webdriver.logging.Entry ( level, message, opt_timestamp, opt_type )
Parameters
level: (!webdriver.logging.Level|string)
The entry level.
message: string
The log message.
opt_timestamp: number=
The time this entry was generated, in + milliseconds since 0:00:00, January 1, 1970 UTC. If omitted, the + current time will be used.
opt_type: string=
The log type, if known.
Show:

Instance Methods

code »toJSON ( ){level: string, message: string, timestamp: number, type: string}
Returns
The JSON representation of this entry.

Instance Properties

Static Functions

Converts a goog.debug.LogRecord into a + webdriver.logging.Entry.

Parameters
logRecord: !goog.debug.LogRecord
The record to convert.
opt_type: string=
The log type.
Returns
The converted entry.
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_promise_CanceledTaskError_.html b/node_modules/selenium-webdriver/docs/class_webdriver_promise_CanceledTaskError_.html new file mode 100644 index 0000000..7924866 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_promise_CanceledTaskError_.html @@ -0,0 +1,4 @@ +webdriver.promise.CanceledTaskError_

Class webdriver.promise.CanceledTaskError_

code »
Error
+  └ goog.debug.Error
+      └ webdriver.promise.CanceledTaskError_

Special error used to signal when a task is canceled because a previous + task in the same frame failed.

Constructor

webdriver.promise.CanceledTaskError_ ( err )
Parameters
err: *
The error that caused the task cancellation.
Show:

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_promise_ControlFlow.html b/node_modules/selenium-webdriver/docs/class_webdriver_promise_ControlFlow.html new file mode 100644 index 0000000..1378718 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_promise_ControlFlow.html @@ -0,0 +1,117 @@ +webdriver.promise.ControlFlow

Class webdriver.promise.ControlFlow

code »
webdriver.EventEmitter
+  └ webdriver.promise.ControlFlow

Handles the execution of scheduled tasks, each of which may be an + asynchronous operation. The control flow will ensure tasks are executed in + the ordered scheduled, starting each task only once those before it have + completed. + +

Each task scheduled within this flow may return a + webdriver.promise.Promise to indicate it is an asynchronous + operation. The ControlFlow will wait for such promises to be resolved before + marking the task as completed. + +

Tasks and each callback registered on a webdriver.promise.Deferred + will be run in their own ControlFlow frame. Any tasks scheduled within a + frame will have priority over previously scheduled tasks. Furthermore, if + any of the tasks in the frame fails, the remainder of the tasks in that frame + will be discarded and the failure will be propagated to the user through the + callback/task's promised result. + +

Each time a ControlFlow empties its task queue, it will fire an + webdriver.promise.ControlFlow.EventType.IDLE event. Conversely, + whenever the flow terminates due to an unhandled error, it will remove all + remaining tasks in its queue and fire an + webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION event. If + there are no listeners registered with the flow, the error will be + rethrown to the global error handler.

Constructor

webdriver.promise.ControlFlow ( opt_timer )
Parameters
opt_timer: webdriver.promise.ControlFlow.Timer=
The timer object + to use. Should only be set for testing.

Enumerations

Show:

Type Definitions

code »webdriver.promise.ControlFlow.Timer : {clearInterval: function(number), clearTimeout: function(number), setInterval: function(!Function, number): number, setTimeout: function(!Function, number): number}
No description.

Instance Methods

Defined in webdriver.promise.ControlFlow

Aborts the current frame. The frame, and all of the tasks scheduled within it + will be discarded. If this instance does not have an active frame, it will + immediately terminate all execution.

Parameters
error: *
The reason the frame is being aborted; typically either + an Error or string.

Aborts this flow, abandoning all remaining tasks. If there are + listeners registered, an UNCAUGHT_EXCEPTION will be emitted with the + offending error, otherwise, the error will be rethrown to the + global error handler.

Parameters
error: *
Object describing the error that caused the flow to + abort; usually either an Error or string value.
code »annotateError ( e )!(Error|goog.testing.JsUnitException)

Appends a summary of this instance's recent task history to the given + error's stack trace. This function will also ensure the error's stack trace + is in canonical form.

Parameters
e: !(Error|goog.testing.JsUnitException)
The error to annotate.
Returns
The annotated error.

Schedules a task that will wait for another promise to resolve. The resolved + promise's value will be returned as the task result.

Parameters
promise: !webdriver.promise.Promise
The promise to wait on.
Returns
A promise that will resolve when the + task has completed.

Cancels the event loop, if necessary.

Cancels the shutdown sequence if it is currently scheduled.

Clears this instance's task history.

Commences the shutdown sequence for this instance. After one turn of the + event loop, this object will emit the + webdriver.promise.ControlFlow.EventType.IDLE event to signal + listeners that it has completed. During this wait, if another task is + scheduled, the shutdown will be aborted.

code »<T> execute ( fn, opt_description )!webdriver.promise.Promise.<T>

Schedules a task for execution. If there is nothing currently in the + queue, the task will be executed in the next turn of the event loop.

Parameters
fn: function(): (T|webdriver.promise.Promise.<T>)
The function to + call to start the task. If the function returns a + webdriver.promise.Promise, this instance will wait for it to be + resolved before starting the next task.
opt_description: string=
A description of the task.
Returns
A promise that will be resolved + with the result of the action.

Returns a summary of the recent task activity for this instance. This + includes the most recently completed task, as well as any parent tasks. In + the returned summary, the task at index N is considered a sub-task of the + task at index N+1.

Returns
A summary of this instance's recent task + activity.
Returns
The next task to execute, or + null if a frame was resolved.
Returns
The scheduled tasks still pending with this instance.

Resets this instance, clearing its queue and removing all event listeners.

Parameters
frame: !webdriver.promise.Frame_
The frame to resolve.

Executes the next task for the current frame. If the current frame has no + more tasks, the frame's result will be resolved, returning control to the + frame's creator. This will terminate the flow if the completed frame was at + the top of the stack.

code »runInNewFrame_ ( fn, callback, errback, opt_activate )

Executes a function in a new frame. If the function does not schedule any new + tasks, the frame will be discarded and the function's result returned + immediately. Otherwise, a promise will be returned. This promise will be + resolved with the function's result once all of the tasks scheduled within + the function have been completed. If the function's frame is aborted, the + returned promise will be rejected.

Parameters
fn: !Function
The function to execute.
callback: function(*)
The function to call with a successful result.
errback: function(*)
The function to call if there is an error.
opt_activate: boolean=
Whether the active frame should be updated to + the newly created frame so tasks are treated as sub-tasks.

Schedules the interval for this instance's event loop, if necessary.

code »timeout ( ms, opt_description )!webdriver.promise.Promise

Inserts a setTimeout into the command queue. This is equivalent to + a thread sleep in a synchronous programming language.

Parameters
ms: number
The timeout delay, in milliseconds.
opt_description: string=
A description to accompany the timeout.
Returns
A promise that will be resolved with + the result of the action.

Removes a completed task from this instance's history record. If any + tasks remain from aborted frames, those will be removed as well.

code »wait ( condition, timeout, opt_message )!webdriver.promise.Promise

Schedules a task that shall wait for a condition to hold. Each condition + function may return any value, but it will always be evaluated as a boolean. + +

Condition functions may schedule sub-tasks with this instance, however, + their execution time will be factored into whether a wait has timed out. + +

In the event a condition returns a Promise, the polling loop will wait for + it to be resolved before evaluating whether the condition has been satisfied. + The resolution time for a promise is factored into whether a wait has timed + out. + +

If the condition function throws, or returns a rejected promise, the + wait task will fail.

Parameters
condition: !Function
The condition function to poll.
timeout: number
How long to wait, in milliseconds, for the condition + to hold before timing out.
opt_message: string=
An optional error message to include if the + wait times out; defaults to the empty string.
Returns
A promise that will be resolved when the + condition has been satisified. The promise shall be rejected if the wait + times out waiting for the condition.

Defined in webdriver.EventEmitter

code »addListener ( type, listenerFn, opt_scope )!webdriver.EventEmitter

Registers a listener.

Parameters
type: string
The type of event to listen for.
listenerFn: !Function
The function to invoke when the event is fired.
opt_scope: Object=
The object in whose scope to invoke the listener.
Returns
A self reference.
code »addListener_ ( type, listenerFn, opt_scope, opt_oneshot )!webdriver.EventEmitter

Registers a listener.

Parameters
type: string
The type of event to listen for.
listenerFn: !Function
The function to invoke when the event is fired.
opt_scope: Object=
The object in whose scope to invoke the listener.
opt_oneshot: boolean=
Whether the listener should be removed after + the first event is fired.
Returns
A self reference.
code »emit ( type, var_args )

Fires an event and calls all listeners.

Parameters
type: string
The type of event to emit.
var_args: ...*
Any arguments to pass to each listener.
code »listeners ( type )!Array

Returns a mutable list of listeners for a specific type of event.

Parameters
type: string
The type of event to retrieve the listeners for.
Returns
The registered listeners for + the given event type.
code »on ( type, listenerFn, opt_scope )!webdriver.EventEmitter

An alias for #addListener().

Parameters
type: string
The type of event to listen for.
listenerFn: !Function
The function to invoke when the event is fired.
opt_scope: Object=
The object in whose scope to invoke the listener.
Returns
A self reference.
code »once ( type, listenerFn, opt_scope )!webdriver.EventEmitter

Registers a one-time listener which will be called only the first time an + event is emitted, after which it will be removed.

Parameters
type: string
The type of event to listen for.
listenerFn: !Function
The function to invoke when the event is fired.
opt_scope: Object=
The object in whose scope to invoke the listener.
Returns
A self reference.

Removes all listeners for a specific type of event. If no event is + specified, all listeners across all types will be removed.

Parameters
opt_type: string=
The type of event to remove listeners from.
Returns
A self reference.

Removes a previously registered event listener.

Parameters
type: string
The type of event to unregister.
listenerFn: !Function
The handler function to remove.
Returns
A self reference.

Instance Properties

Defined in webdriver.promise.ControlFlow

Tracks the active execution frame for this instance. Lazily initialized + when the first task is scheduled.

Interval ID for this instance's event loop.

A list of recent tasks. Each time a new task is started, or a frame is + completed, the previously recorded task is removed from this list. If + there are multiple tasks, task N+1 is considered a sub-task of task + N.

The number of aborted frames since the last time a task was executed or a + frame completed successfully.

The number of "pending" promise rejections. + +

Each time a promise is rejected and is not handled by a listener, it will + schedule a 0-based timeout to check if it is still unrejected in the next + turn of the JS-event loop. This allows listeners to attach to, and handle, + the rejected promise at any point in same turn of the event loop that the + promise was rejected. + +

When this flow's own event loop triggers, it will not run if there + are any outstanding promise rejections. This allows unhandled promises to + be reported before a new task is started, ensuring the error is reported to + the current task queue.

A reference to the frame in which new tasks should be scheduled. If + null, tasks will be scheduled within the active frame. When forcing + a function to run in the context of a new frame, this pointer is used to + ensure tasks are scheduled within the newly created frame, even though it + won't be active yet.

Timeout ID set when the flow is about to shutdown without any errors + being detected. Upon shutting down, the flow will emit an + webdriver.promise.ControlFlow.EventType.IDLE event. Idle events + always follow a brief timeout in order to catch latent errors from the last + completed task. If this task had a callback registered, but no errback, and + the task fails, the unhandled failure would not be reported by the promise + system until the next turn of the event loop: + + // Schedule 1 task that fails. + var result = webriver.promise.controlFlow().schedule('example', + function() { return webdriver.promise.rejected('failed'); }); + // Set a callback on the result. This delays reporting the unhandled + // failure for 1 turn of the event loop. + result.then(goog.nullFunction);

The timer used by this instance.

Defined in webdriver.EventEmitter

Map of events to registered listeners.

Static Properties

How often, in milliseconds, the event loop should run.

The default timer object, which uses the global timer functions.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_promise_Deferred.html b/node_modules/selenium-webdriver/docs/class_webdriver_promise_Deferred.html new file mode 100644 index 0000000..2f4e863 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_promise_Deferred.html @@ -0,0 +1,86 @@ +webdriver.promise.Deferred

Class webdriver.promise.Deferred.<T>

code »
webdriver.promise.Promise.<(T|null)>
+  └ webdriver.promise.Deferred

Represents a value that will be resolved at some point in the future. This + class represents the protected "producer" half of a Promise - each Deferred + has a promise property that may be returned to consumers for + registering callbacks, reserving the ability to resolve the deferred to the + producer. + +

If this Deferred is rejected and there are no listeners registered before + the next turn of the event loop, the rejection will be passed to the + webdriver.promise.ControlFlow as an unhandled failure. + +

If this Deferred is cancelled, the cancellation reason will be forward to + the Deferred's canceller function (if provided). The canceller may return a + truth-y value to override the reason provided for rejection.

Constructor

webdriver.promise.Deferred ( opt_canceller, opt_flow )
Parameters
opt_canceller: Function=
Function to call when cancelling the + computation of this instance's value.
opt_flow: webdriver.promise.ControlFlow=
The control flow + this instance was created under. This should only be provided during + unit tests.

Enumerations

Show:

Type Definitions

code »webdriver.promise.Deferred.Listener_ : {callback: (Function|undefined), errback: (Function|undefined), fulfill: function(*), reject: function(*)}
Type definition for a listener registered on a Deferred object.

Instance Methods

Defined in webdriver.promise.Deferred

code »errback ( opt_error )

Rejects this promise. If the error is itself a promise, this instance will + be chained to it and be rejected with the error's resolved value.

Parameters
opt_error: *=
The rejection reason, typically either a + Error or a string.
code »fulfill ( opt_value )

Resolves this promise with the given value. If the value is itself a + promise and not a reference to this deferred, this instance will wait for + it before resolving.

Parameters
opt_value: T=
The fulfilled value.
code »reject ( opt_error )

Rejects this promise. If the error is itself a promise, this instance will + be chained to it and be rejected with the error's resolved value.

Parameters
opt_error: *=
The rejection reason, typically either a + Error or a string.

Removes all of the listeners previously registered on this deferred.

Throws
Error
If this deferred has already been resolved.

Defined in webdriver.promise.Promise.<(T|null)>

code »cancel ( reason )

Cancels the computation of this promise's value, rejecting the promise in the + process.

Parameters
reason: *
The reason this promise is being cancelled. If not an + Error, one will be created using the value's string + representation.
Returns
Whether this promise's value is still being computed.
code »<R> then ( opt_callback, opt_errback )!webdriver.promise.Promise.<R>

Registers listeners for when this instance is resolved. This function most + overridden by subtypes.

Parameters
opt_callback: ?(function(T): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is successfully resolved. The function + should expect a single argument: the promise's resolved value.
opt_errback: ?(function(*): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is rejected. The function should expect + a single argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener for when this promise is rejected. This is synonymous + with the catch clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } catch (ex) {
+     console.error(ex);
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenCatch(function(ex) {
+     console.error(ex);
+   });
+ 
Parameters
errback: function(*): (R|webdriver.promise.Promise.<R>)
The function + to call if this promise is rejected. The function should expect a single + argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener to invoke when this promise is resolved, regardless + of whether the promise's value was successfully computed. This function + is synonymous with the finally clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } finally {
+     cleanUp();
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenFinally(cleanUp);
+ 
+ + Note: similar to the finally clause, if the registered + callback returns a rejected promise or throws an error, it will silently + replace the rejection error (if any) from this promise: +

+   try {
+     throw Error('one');
+   } finally {
+     throw Error('two');  // Hides Error: one
+   }
+
+   webdriver.promise.rejected(Error('one'))
+       .thenFinally(function() {
+         throw Error('two');  // Hides Error: one
+       });
+ 
Parameters
callback: function(): (R|webdriver.promise.Promise.<R>)
The function + to call when this promise is resolved.
Returns
A promise that will be fulfilled + with the callback result.

Instance Properties

Defined in webdriver.promise.Deferred

Represents the eventual value of a completed operation. Each promise may be + in one of three states: pending, resolved, or rejected. Each promise starts + in the pending state and may make a single transition to either a + fulfilled or failed state. + +

This class is based on the Promise/A proposal from CommonJS. Additional + functions are provided for API compatibility with Dojo Deferred objects.

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_promise_Frame_.html b/node_modules/selenium-webdriver/docs/class_webdriver_promise_Frame_.html new file mode 100644 index 0000000..66dabed --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_promise_Frame_.html @@ -0,0 +1,118 @@ +webdriver.promise.Frame_

Class webdriver.promise.Frame_

code »
webdriver.promise.Promise.<(T|null)>
+  └ webdriver.promise.Deferred
+      └ webdriver.promise.Node_
+          └ webdriver.promise.Frame_

An execution frame within a webdriver.promise.ControlFlow. Each + frame represents the execution context for either a + webdriver.promise.Task_ or a callback on a + webdriver.promise.Deferred. + +

Each frame may contain sub-frames. If child N is a sub-frame, then the + items queued within it are given priority over child N+1.

Constructor

webdriver.promise.Frame_ ( flow )
Parameters
flow: !webdriver.promise.ControlFlow
The flow this instance belongs + to.
Show:

Instance Methods

Defined in webdriver.promise.Frame_

Adds a new node to this frame.

Parameters
node: !(webdriver.promise.Frame_|webdriver.promise.Task_)
The node to insert.

Marks all of the tasks that are descendants of this frame in the execution + tree as cancelled. This is necessary for callbacks scheduled asynchronous. + For example: + + var someResult; + webdriver.promise.createFlow(function(flow) { + someResult = flow.execute(function() {}); + throw Error(); + }).addErrback(function(err) { + console.log('flow failed: ' + err); + someResult.then(function() { + console.log('task succeeded!'); + }, function(err) { + console.log('task failed! ' + err); + }); + }); + // flow failed: Error: boom + // task failed! CanceledTaskError: Task discarded due to a previous + // task failure: Error: boom

Parameters
error: !webdriver.promise.CanceledTaskError_
The cancellation + error.
Returns
This frame's + fist child.
Returns
The task currently executing + within this frame, if any.

Locks this frame.

Removes a child from this frame.

Parameters
child: !(webdriver.promise.Frame_|webdriver.promise.Task_)
The child to remove.
Parameters
task: webdriver.promise.Task_
The task currently + executing within this frame, if any.
code »toString ( )string

Defined in webdriver.promise.Node_

Returns
This node's parent.
Returns
The root of this node's tree.
code »setParent ( parent )
Parameters
parent: webdriver.promise.Node_
This node's new parent.

Defined in webdriver.promise.Deferred

code »errback ( opt_error )

Rejects this promise. If the error is itself a promise, this instance will + be chained to it and be rejected with the error's resolved value.

Parameters
opt_error: *=
The rejection reason, typically either a + Error or a string.
code »fulfill ( opt_value )

Resolves this promise with the given value. If the value is itself a + promise and not a reference to this deferred, this instance will wait for + it before resolving.

Parameters
opt_value: T=
The fulfilled value.

Removes all of the listeners previously registered on this deferred.

Throws
Error
If this deferred has already been resolved.

Defined in webdriver.promise.Promise.<(T|null)>

code »cancel ( reason )

Cancels the computation of this promise's value, rejecting the promise in the + process.

Parameters
reason: *
The reason this promise is being cancelled. If not an + Error, one will be created using the value's string + representation.
Returns
Whether this promise's value is still being computed.
code »<R> then ( opt_callback, opt_errback )!webdriver.promise.Promise.<R>

Registers listeners for when this instance is resolved. This function most + overridden by subtypes.

Parameters
opt_callback: ?(function(T): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is successfully resolved. The function + should expect a single argument: the promise's resolved value.
opt_errback: ?(function(*): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is rejected. The function should expect + a single argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener for when this promise is rejected. This is synonymous + with the catch clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } catch (ex) {
+     console.error(ex);
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenCatch(function(ex) {
+     console.error(ex);
+   });
+ 
Parameters
errback: function(*): (R|webdriver.promise.Promise.<R>)
The function + to call if this promise is rejected. The function should expect a single + argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener to invoke when this promise is resolved, regardless + of whether the promise's value was successfully computed. This function + is synonymous with the finally clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } finally {
+     cleanUp();
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenFinally(cleanUp);
+ 
+ + Note: similar to the finally clause, if the registered + callback returns a rejected promise or throws an error, it will silently + replace the rejection error (if any) from this promise: +

+   try {
+     throw Error('one');
+   } finally {
+     throw Error('two');  // Hides Error: one
+   }
+
+   webdriver.promise.rejected(Error('one'))
+       .thenFinally(function() {
+         throw Error('two');  // Hides Error: one
+       });
+ 
Parameters
callback: function(): (R|webdriver.promise.Promise.<R>)
The function + to call when this promise is resolved.
Returns
A promise that will be fulfilled + with the callback result.

Instance Properties

Defined in webdriver.promise.Frame_

Whether this frame is active. A frame is considered active once one of its + descendants has been removed for execution. + + Adding a sub-frame as a child to an active frame is an indication that + a callback to a webdriver.promise.Deferred is being invoked and any + tasks scheduled within it should have priority over previously scheduled + tasks: +

+   var flow = webdriver.promise.controlFlow();
+   flow.execute('start here', goog.nullFunction).then(function() {
+     flow.execute('this should execute 2nd', goog.nullFunction);
+   });
+   flow.execute('this should execute last', goog.nullFunction);
+ 

Whether this frame is currently locked. A locked frame represents a callback + or task function which has run to completion and scheduled all of its tasks. + +

Once a frame becomes active, any new frames which are + added represent callbacks on a webdriver.promise.Deferred, whose + tasks must be given priority over previously scheduled tasks.

A reference to the last node inserted in this frame.

The task currently being executed within this frame.

Defined in webdriver.promise.Node_

Defined in webdriver.promise.Deferred

Represents the eventual value of a completed operation. Each promise may be + in one of three states: pending, resolved, or rejected. Each promise starts + in the pending state and may make a single transition to either a + fulfilled or failed state. + +

This class is based on the Promise/A proposal from CommonJS. Additional + functions are provided for API compatibility with Dojo Deferred objects.

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_promise_Node_.html b/node_modules/selenium-webdriver/docs/class_webdriver_promise_Node_.html new file mode 100644 index 0000000..f6b36cf --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_promise_Node_.html @@ -0,0 +1,73 @@ +webdriver.promise.Node_

Class webdriver.promise.Node_

code »
webdriver.promise.Promise.<(T|null)>
+  └ webdriver.promise.Deferred
+      └ webdriver.promise.Node_

A single node in an webdriver.promise.ControlFlow's task tree.

Constructor

webdriver.promise.Node_ ( flow )
Parameters
flow: !webdriver.promise.ControlFlow
The flow this instance belongs + to.
Show:

Instance Methods

Defined in webdriver.promise.Node_

Returns
This node's parent.
Returns
The root of this node's tree.
code »setParent ( parent )
Parameters
parent: webdriver.promise.Node_
This node's new parent.

Defined in webdriver.promise.Deferred

code »errback ( opt_error )

Rejects this promise. If the error is itself a promise, this instance will + be chained to it and be rejected with the error's resolved value.

Parameters
opt_error: *=
The rejection reason, typically either a + Error or a string.
code »fulfill ( opt_value )

Resolves this promise with the given value. If the value is itself a + promise and not a reference to this deferred, this instance will wait for + it before resolving.

Parameters
opt_value: T=
The fulfilled value.
code »reject ( opt_error )

Rejects this promise. If the error is itself a promise, this instance will + be chained to it and be rejected with the error's resolved value.

Parameters
opt_error: *=
The rejection reason, typically either a + Error or a string.

Removes all of the listeners previously registered on this deferred.

Throws
Error
If this deferred has already been resolved.

Defined in webdriver.promise.Promise.<(T|null)>

code »cancel ( reason )

Cancels the computation of this promise's value, rejecting the promise in the + process.

Parameters
reason: *
The reason this promise is being cancelled. If not an + Error, one will be created using the value's string + representation.
Returns
Whether this promise's value is still being computed.
code »<R> then ( opt_callback, opt_errback )!webdriver.promise.Promise.<R>

Registers listeners for when this instance is resolved. This function most + overridden by subtypes.

Parameters
opt_callback: ?(function(T): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is successfully resolved. The function + should expect a single argument: the promise's resolved value.
opt_errback: ?(function(*): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is rejected. The function should expect + a single argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener for when this promise is rejected. This is synonymous + with the catch clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } catch (ex) {
+     console.error(ex);
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenCatch(function(ex) {
+     console.error(ex);
+   });
+ 
Parameters
errback: function(*): (R|webdriver.promise.Promise.<R>)
The function + to call if this promise is rejected. The function should expect a single + argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener to invoke when this promise is resolved, regardless + of whether the promise's value was successfully computed. This function + is synonymous with the finally clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } finally {
+     cleanUp();
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenFinally(cleanUp);
+ 
+ + Note: similar to the finally clause, if the registered + callback returns a rejected promise or throws an error, it will silently + replace the rejection error (if any) from this promise: +

+   try {
+     throw Error('one');
+   } finally {
+     throw Error('two');  // Hides Error: one
+   }
+
+   webdriver.promise.rejected(Error('one'))
+       .thenFinally(function() {
+         throw Error('two');  // Hides Error: one
+       });
+ 
Parameters
callback: function(): (R|webdriver.promise.Promise.<R>)
The function + to call when this promise is resolved.
Returns
A promise that will be fulfilled + with the callback result.

Instance Properties

Defined in webdriver.promise.Node_

Defined in webdriver.promise.Deferred

Represents the eventual value of a completed operation. Each promise may be + in one of three states: pending, resolved, or rejected. Each promise starts + in the pending state and may make a single transition to either a + fulfilled or failed state. + +

This class is based on the Promise/A proposal from CommonJS. Additional + functions are provided for API compatibility with Dojo Deferred objects.

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_promise_Promise.html b/node_modules/selenium-webdriver/docs/class_webdriver_promise_Promise.html new file mode 100644 index 0000000..ed14e51 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_promise_Promise.html @@ -0,0 +1,64 @@ +webdriver.promise.Promise

Class webdriver.promise.Promise.<T>

code »

Represents the eventual value of a completed operation. Each promise may be + in one of three states: pending, resolved, or rejected. Each promise starts + in the pending state and may make a single transition to either a + fulfilled or failed state. + +

This class is based on the Promise/A proposal from CommonJS. Additional + functions are provided for API compatibility with Dojo Deferred objects.

Constructor

webdriver.promise.Promise ( )
Show:

Instance Methods

code »cancel ( reason )

Cancels the computation of this promise's value, rejecting the promise in the + process.

Parameters
reason: *
The reason this promise is being cancelled. If not an + Error, one will be created using the value's string + representation.
Returns
Whether this promise's value is still being computed.
code »<R> then ( opt_callback, opt_errback )!webdriver.promise.Promise.<R>

Registers listeners for when this instance is resolved. This function most + overridden by subtypes.

Parameters
opt_callback: ?(function(T): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is successfully resolved. The function + should expect a single argument: the promise's resolved value.
opt_errback: ?(function(*): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is rejected. The function should expect + a single argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener for when this promise is rejected. This is synonymous + with the catch clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } catch (ex) {
+     console.error(ex);
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenCatch(function(ex) {
+     console.error(ex);
+   });
+ 
Parameters
errback: function(*): (R|webdriver.promise.Promise.<R>)
The function + to call if this promise is rejected. The function should expect a single + argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener to invoke when this promise is resolved, regardless + of whether the promise's value was successfully computed. This function + is synonymous with the finally clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } finally {
+     cleanUp();
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenFinally(cleanUp);
+ 
+ + Note: similar to the finally clause, if the registered + callback returns a rejected promise or throws an error, it will silently + replace the rejection error (if any) from this promise: +

+   try {
+     throw Error('one');
+   } finally {
+     throw Error('two');  // Hides Error: one
+   }
+
+   webdriver.promise.rejected(Error('one'))
+       .thenFinally(function() {
+         throw Error('two');  // Hides Error: one
+       });
+ 
Parameters
callback: function(): (R|webdriver.promise.Promise.<R>)
The function + to call when this promise is resolved.
Returns
A promise that will be fulfilled + with the callback result.
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_promise_Task_.html b/node_modules/selenium-webdriver/docs/class_webdriver_promise_Task_.html new file mode 100644 index 0000000..2329e18 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_promise_Task_.html @@ -0,0 +1,77 @@ +webdriver.promise.Task_

Class webdriver.promise.Task_

code »
webdriver.promise.Promise.<(T|null)>
+  └ webdriver.promise.Deferred
+      └ webdriver.promise.Node_
+          └ webdriver.promise.Task_

A task to be executed by a webdriver.promise.ControlFlow.

Constructor

webdriver.promise.Task_ ( flow, fn, description, snapshot )
Parameters
flow: !webdriver.promise.ControlFlow
The flow this instances belongs + to.
fn: !Function
The function to call when the task executes. If it + returns a webdriver.promise.Promise, the flow will wait + for it to be resolved before starting the next task.
description: string
A description of the task for debugging.
snapshot: !webdriver.stacktrace.Snapshot
A snapshot of the stack + when this task was scheduled.
Show:

Instance Methods

Defined in webdriver.promise.Task_

Executes this task.

Returns
This task's description.
code »toString ( )string

Defined in webdriver.promise.Node_

Returns
This node's parent.
Returns
The root of this node's tree.
code »setParent ( parent )
Parameters
parent: webdriver.promise.Node_
This node's new parent.

Defined in webdriver.promise.Deferred

code »errback ( opt_error )

Rejects this promise. If the error is itself a promise, this instance will + be chained to it and be rejected with the error's resolved value.

Parameters
opt_error: *=
The rejection reason, typically either a + Error or a string.
code »fulfill ( opt_value )

Resolves this promise with the given value. If the value is itself a + promise and not a reference to this deferred, this instance will wait for + it before resolving.

Parameters
opt_value: T=
The fulfilled value.
code »reject ( opt_error )

Rejects this promise. If the error is itself a promise, this instance will + be chained to it and be rejected with the error's resolved value.

Parameters
opt_error: *=
The rejection reason, typically either a + Error or a string.

Removes all of the listeners previously registered on this deferred.

Throws
Error
If this deferred has already been resolved.

Defined in webdriver.promise.Promise.<(T|null)>

code »cancel ( reason )

Cancels the computation of this promise's value, rejecting the promise in the + process.

Parameters
reason: *
The reason this promise is being cancelled. If not an + Error, one will be created using the value's string + representation.
Returns
Whether this promise's value is still being computed.
code »<R> then ( opt_callback, opt_errback )!webdriver.promise.Promise.<R>

Registers listeners for when this instance is resolved. This function most + overridden by subtypes.

Parameters
opt_callback: ?(function(T): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is successfully resolved. The function + should expect a single argument: the promise's resolved value.
opt_errback: ?(function(*): (R|webdriver.promise.Promise.<R>))=
The + function to call if this promise is rejected. The function should expect + a single argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener for when this promise is rejected. This is synonymous + with the catch clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } catch (ex) {
+     console.error(ex);
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenCatch(function(ex) {
+     console.error(ex);
+   });
+ 
Parameters
errback: function(*): (R|webdriver.promise.Promise.<R>)
The function + to call if this promise is rejected. The function should expect a single + argument: the rejection reason.
Returns
A new promise which will be + resolved with the result of the invoked callback.

Registers a listener to invoke when this promise is resolved, regardless + of whether the promise's value was successfully computed. This function + is synonymous with the finally clause in a synchronous API: +


+   // Synchronous API:
+   try {
+     doSynchronousWork();
+   } finally {
+     cleanUp();
+   }
+
+   // Asynchronous promise API:
+   doAsynchronousWork().thenFinally(cleanUp);
+ 
+ + Note: similar to the finally clause, if the registered + callback returns a rejected promise or throws an error, it will silently + replace the rejection error (if any) from this promise: +

+   try {
+     throw Error('one');
+   } finally {
+     throw Error('two');  // Hides Error: one
+   }
+
+   webdriver.promise.rejected(Error('one'))
+       .thenFinally(function() {
+         throw Error('two');  // Hides Error: one
+       });
+ 
Parameters
callback: function(): (R|webdriver.promise.Promise.<R>)
The function + to call when this promise is resolved.
Returns
A promise that will be fulfilled + with the callback result.

Instance Properties

Defined in webdriver.promise.Task_

Defined in webdriver.promise.Node_

Defined in webdriver.promise.Deferred

Represents the eventual value of a completed operation. Each promise may be + in one of three states: pending, resolved, or rejected. Each promise starts + in the pending state and may make a single transition to either a + fulfilled or failed state. + +

This class is based on the Promise/A proposal from CommonJS. Additional + functions are provided for API compatibility with Dojo Deferred objects.

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_stacktrace_Frame.html b/node_modules/selenium-webdriver/docs/class_webdriver_stacktrace_Frame.html new file mode 100644 index 0000000..68edecc --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_stacktrace_Frame.html @@ -0,0 +1,8 @@ +webdriver.stacktrace.Frame

Class webdriver.stacktrace.Frame

code »

Class representing one stack frame.

Constructor

webdriver.stacktrace.Frame ( context, name, alias, path )
Parameters
context: (string|undefined)
Context object, empty in case of global + functions or if the browser doesn't provide this information.
name: (string|undefined)
Function name, empty in case of anonymous + functions.
alias: (string|undefined)
Alias of the function if available. For + example the function name will be 'c' and the alias will be 'b' if the + function is defined as a.b = function c() {};.
path: (string|undefined)
File path or URL including line number and + optionally column number separated by colons.
Show:

Instance Methods

Returns
The column number if known and -1 if it is unknown.
Returns
The line number if known or -1 if it is unknown.
Returns
The function name or empty string if the function is + anonymous and the object field which it's assigned to is unknown.
Returns
The url or empty string if it is unknown.
Returns
Whether the stack frame contains an anonymous function.

Converts this frame to its string representation using V8's stack trace + format: http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi

Returns
The string representation of this frame.

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_stacktrace_Snapshot.html b/node_modules/selenium-webdriver/docs/class_webdriver_stacktrace_Snapshot.html new file mode 100644 index 0000000..0484ea1 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_stacktrace_Snapshot.html @@ -0,0 +1,5 @@ +webdriver.stacktrace.Snapshot

Class webdriver.stacktrace.Snapshot

code »

Stores a snapshot of the stack trace at the time this instance was created. + The stack trace will always be adjusted to exclude this function call.

Constructor

webdriver.stacktrace.Snapshot ( opt_slice )
Parameters
opt_slice: number=
The number of frames to remove from the top of + the generated stack trace.
Show:

Instance Methods

Returns
The parsed stack trace.

Instance Properties

The parsed stack trace. This list is lazily generated the first time it is + accessed.

The error's stacktrace. This must be accessed immediately to ensure Opera + computes the context correctly.

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_testing_Assertion.html b/node_modules/selenium-webdriver/docs/class_webdriver_testing_Assertion.html new file mode 100644 index 0000000..8aee79e --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_testing_Assertion.html @@ -0,0 +1,32 @@ +webdriver.testing.Assertion

Class webdriver.testing.Assertion

code »

Utility for performing assertions against a given value. If the + value is a webdriver.promise.Promise, this assertion will wait + for it to resolve before applying any matchers.

Constructor

webdriver.testing.Assertion ( value )
Parameters
value: *
The value to wrap and apply matchers to.

Classes

webdriver.testing.Assertion.DelegatingMatcher_
Wraps an object literal implementing the Matcher interface.
Show:

Instance Methods

code »apply ( matcher, opt_message )webdriver.promise.Promise

Asserts that the given matcher accepts the value wrapped by this + instance. If the wrapped value is a promise, this function will defer + applying the assertion until the value has been resolved. Otherwise, it + will be applied immediately.

Parameters
matcher: !goog.labs.testing.Matcher
The matcher to apply
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The deferred assertion result, or + null if the assertion was immediately applied.
code »closeTo ( value, range, opt_message )webdriver.promise.Promise

Asserts that the wrapped value is a number within a given distance of an + expected value.

Parameters
value: number
The expected value.
range: number
The maximum amount the actual value is permitted to + differ from the expected value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.
code »contains ( value, opt_message )webdriver.promise.Promise

Asserts that the wrapped value is a string or array-like structure + containing the given value.

Parameters
value: *
The expected value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.
code »endsWith ( suffix, opt_message )webdriver.promise.Promise

Asserts that the wrapped value is a string ending with the given suffix.

Parameters
suffix: string
The expected suffix.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.
code »equalTo ( value, opt_message )webdriver.promise.Promise

Asserts that the value managed by this assertion is strictly equal to the + given value.

Parameters
value: *
The expected value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the value managed by this assertion is a number strictly + greater than value.

Parameters
value: number
The minimum value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the value managed by this assertion is a number >= the given + value.

Parameters
value: number
The minimum value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the wrapped value is an instance of the given class.

Parameters
ctor: !Function
The expected class constructor.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the value managed by this assertion is strictly false.

Returns
The assertion result.

Asserts that the wrapped value is null.

Parameters
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the wrapped value is null or undefined.

Parameters
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the value managed by this assertion is strictly true.

Returns
The assertion result.

Asserts that the wrapped value is undefined.

Parameters
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.
code »lessThan ( value, opt_message )webdriver.promise.Promise

Asserts that the value managed by this assertion is a number strictly less + than the given value.

Parameters
value: number
The maximum value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the value managed by this assertion is a number <= the given + value.

Parameters
value: number
The maximum value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.
code »matches ( regex, opt_message )webdriver.promise.Promise

Asserts that the wrapped value is a string that matches the given RegExp.

Parameters
regex: !RegExp
The regex to test.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.
code »startsWith ( prefix, opt_message )webdriver.promise.Promise

Asserts that the wrapped value is a string starting with the given prefix.

Parameters
prefix: string
The expected prefix.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Instance Properties

A self reference provided for writing fluent assertions: + webdriver.testing.assert(x).is.equalTo(y);

Negates any matchers applied to this instance's value: + webdriver.testing.assert(x).not.equalTo(y);

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_testing_Assertion_DelegatingMatcher_.html b/node_modules/selenium-webdriver/docs/class_webdriver_testing_Assertion_DelegatingMatcher_.html new file mode 100644 index 0000000..22a3d65 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_testing_Assertion_DelegatingMatcher_.html @@ -0,0 +1,3 @@ +webdriver.testing.Assertion.DelegatingMatcher_

Class webdriver.testing.Assertion.DelegatingMatcher_

code »
All implemented interfaces:
goog.labs.testing.Matcher

Wraps an object literal implementing the Matcher interface. This is used + to appease the Closure compiler, which will not treat an object literal as + implementing an interface.

Constructor

webdriver.testing.Assertion.DelegatingMatcher_ ( obj )
Parameters
obj: {matches: function(*): boolean, describe: function(): string}
The object literal to delegate to.
Show:

Instance Methods

code »matches ( value )
Parameters
value
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_testing_ContainsMatcher.html b/node_modules/selenium-webdriver/docs/class_webdriver_testing_ContainsMatcher.html new file mode 100644 index 0000000..d56b8a3 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_testing_ContainsMatcher.html @@ -0,0 +1 @@ +webdriver.testing.ContainsMatcher

Class webdriver.testing.ContainsMatcher

code »
All implemented interfaces:
goog.labs.testing.Matcher

Accepts strins or array-like structures that contain value.

Constructor

webdriver.testing.ContainsMatcher ( value )
Parameters
value: *
The value to check for.
Show:

Instance Methods

code »describe ( actualValue )string
Parameters
actualValue
code »matches ( actualValue )boolean
Parameters
actualValue

Instance Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/class_webdriver_testing_NegatedAssertion.html b/node_modules/selenium-webdriver/docs/class_webdriver_testing_NegatedAssertion.html new file mode 100644 index 0000000..6a7d073 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/class_webdriver_testing_NegatedAssertion.html @@ -0,0 +1,26 @@ +webdriver.testing.NegatedAssertion

Class webdriver.testing.NegatedAssertion

code »
webdriver.testing.Assertion
+  └ webdriver.testing.NegatedAssertion

An assertion that negates any applied matchers.

Constructor

webdriver.testing.NegatedAssertion ( value )
Parameters
value: *
The value to perform assertions on.
Show:

Instance Methods

Defined in webdriver.testing.NegatedAssertion

code »apply ( matcher, opt_message )(null|webdriver.promise.Promise)
Parameters
matcher
opt_message

Defined in webdriver.testing.Assertion

code »closeTo ( value, range, opt_message )webdriver.promise.Promise

Asserts that the wrapped value is a number within a given distance of an + expected value.

Parameters
value: number
The expected value.
range: number
The maximum amount the actual value is permitted to + differ from the expected value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.
code »contains ( value, opt_message )webdriver.promise.Promise

Asserts that the wrapped value is a string or array-like structure + containing the given value.

Parameters
value: *
The expected value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.
code »endsWith ( suffix, opt_message )webdriver.promise.Promise

Asserts that the wrapped value is a string ending with the given suffix.

Parameters
suffix: string
The expected suffix.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.
code »equalTo ( value, opt_message )webdriver.promise.Promise

Asserts that the value managed by this assertion is strictly equal to the + given value.

Parameters
value: *
The expected value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the value managed by this assertion is a number strictly + greater than value.

Parameters
value: number
The minimum value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the value managed by this assertion is a number >= the given + value.

Parameters
value: number
The minimum value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the wrapped value is an instance of the given class.

Parameters
ctor: !Function
The expected class constructor.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the value managed by this assertion is strictly false.

Returns
The assertion result.

Asserts that the wrapped value is null.

Parameters
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the wrapped value is null or undefined.

Parameters
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the value managed by this assertion is strictly true.

Returns
The assertion result.

Asserts that the wrapped value is undefined.

Parameters
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.
code »lessThan ( value, opt_message )webdriver.promise.Promise

Asserts that the value managed by this assertion is a number strictly less + than the given value.

Parameters
value: number
The maximum value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Asserts that the value managed by this assertion is a number <= the given + value.

Parameters
value: number
The maximum value.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.
code »matches ( regex, opt_message )webdriver.promise.Promise

Asserts that the wrapped value is a string that matches the given RegExp.

Parameters
regex: !RegExp
The regex to test.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.
code »startsWith ( prefix, opt_message )webdriver.promise.Promise

Asserts that the wrapped value is a string starting with the given prefix.

Parameters
prefix: string
The expected prefix.
opt_message: string=
A message to include if the matcher does not + accept the value wrapped by this assertion.
Returns
The assertion result.

Instance Properties

Defined in webdriver.testing.NegatedAssertion

Defined in webdriver.testing.Assertion

A self reference provided for writing fluent assertions: + webdriver.testing.assert(x).is.equalTo(y);

Negates any matchers applied to this instance's value: + webdriver.testing.assert(x).not.equalTo(y);

Static Properties

\ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/dossier.css b/node_modules/selenium-webdriver/docs/dossier.css new file mode 100644 index 0000000..53ce031 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/dossier.css @@ -0,0 +1 @@ +article,details,main,nav,section,summary{display:block}html{font-size:10px}html,body{height:100%}body{margin:0;padding:0;font-size:1.2rem;font-size:1.2em;font-family:sans-serif;background:#fff;color:#424242}a{text-decoration:none}a[href]{color:#66f}a[href]:hover{text-decoration:underline}code{font-size:1.2rem}code.type,code.type a[href],code.type a.unresolved-link{font-weight:normal;color:#080}code.type a.unresolved-link{border-bottom:1px dotted #080}pre,p{margin:1rem 0}.args{color:#828282;font-weight:normal}h1{border-bottom:1px solid #8f8f8f;margin:.2rem 0 0 0;padding:.5rem 0 .1rem;font-size:2.5rem}h1 code{font-size:1.85rem}h1 .deprecation-notice{color:#828282;font-weight:normal;font-style:italic;font-size:.66em}table{border-collapse:collapse;border-spacing:0;margin:0;padding:0;width:100%}tr{border:0;margin:0;padding:0}th{border-bottom:1px solid #8f8f8f;text-align:left;padding-top:.5rem}td>dl{margin-left:1rem}summary:focus{outline:0}summary::-webkit-details-marker{display:none}a.source{float:right}header>dl{margin-left:0}header>dl,header>pre,header>a.source{margin-top:.5rem}header+*{clear:right}dl{margin:0 0 0 1.25rem}dt{font-weight:bold}dd{margin-left:1.25rem}dd+dt{margin-top:.5rem}.type-summary{border-top:1px solid #8f8f8f;border-left:1px solid #8f8f8f}.type-summary dl{padding:.5rem 0 0 1rem;margin-left:0}.member{font-weight:bold}.member.deprecation-notice{text-decoration:line-through}#sidenav-toggle,#menubutton{display:none}#topnav{position:absolute;top:0;right:0;left:0;height:4rem;background:#424242;color:#fff;font-weight:bold;z-index:1}#topnav>div{position:relative;height:4rem;width:100%}#searchbox{position:absolute;right:1.5rem}#searchbox div{display:table-cell;vertical-align:middle;height:4rem}#searchbox input{width:25rem;box-shadow:inset 1px 2px rgba(0,0,0,0.18);border-radius:15px;border:1px solid #0f0f0f;padding:.2rem .5rem}.ac-renderer{position:absolute;background:#fcfcfc;border:1px solid #424242;-moz-box-shadow:2px 2px 2px rgba(102,102,102,0.4);-webkit-box-shadow:2px 2px 2px rgba(102,102,102,0.4);box-shadow:2px 2px 2px rgba(102,102,102,0.4);z-index:2;width:30rem;overflow:auto}.ac-row{cursor:pointer;padding:.5rem}.ac-highlighted{font-weight:bold}.ac-active{background-color:rgba(82,82,82,0.1)}main{margin-top:4rem;padding-bottom:2.5rem;padding-left:2rem;width:-webkit-calc(75% - 2rem);width:calc(75% - 2rem);float:left}.ctor{padding:.5rem 0 .5rem .5rem}dl.public{border-left:.7rem solid rgba(34,139,34,0.6)}dl.protected{border-left:.7rem solid rgba(218,165,32,0.6)}dl.private{border-left:.7rem solid rgba(255,0,0,0.5)}.wrap-details{border-top:1px solid #8f8f8f;border-left:1px solid #8f8f8f;margin-bottom:1px;display:none}.wrap-details.ctor{padding:0;display:block}main.public .wrap-details.public,main.protected .wrap-details.protected,main.private .wrap-details.private{display:block}.wrap-details.public>div:first-child{border-left:.7rem solid rgba(34,139,34,0.6)}.wrap-details.protected>div:first-child{border-left:.7rem solid rgba(218,165,32,0.6)}.wrap-details.private>div:first-child{border-left:.7rem solid rgba(255,0,0,0.5)}.wrap-details.inv{display:block}main.public .wrap-details.inv.public,main.protected .wrap-details.inv.protected,main.private .wrap-details.inv.private{display:none}.wrap-details.inv.public{color:#828282;font-weight:normal}.wrap-details.inv.public>div:first-child{border-left:.7rem solid rgba(34,139,34,0.4)}.wrap-details.inv.protected{color:#828282;font-weight:normal}.wrap-details.inv.protected>div:first-child{border-left:.7rem solid rgba(218,165,32,0.4)}.wrap-details.inv.private{color:#828282;font-weight:normal}.wrap-details.inv.private>div:first-child{border-left:.7rem solid rgba(255,0,0,0.4)}#visibility-controls{float:right}label{cursor:pointer}label[for=show-public]>span{border:1px outset #228b22;border-radius:5px;background:rgba(34,139,34,0.6);margin:0 .3rem}label[for=show-protected]>span{border:1px outset #daa520;border-radius:5px;background:rgba(218,165,32,0.6);margin:0 .3rem}label[for=show-private]>span{border:1px outset #f00;border-radius:5px;background:rgba(255,0,0,0.5);margin:0 .3rem}details>summary{padding-top:.5rem;margin-left:1.25rem;padding-bottom:.5rem}details>summary p{margin-top:.5rem;margin-bottom:0}details>summary pre:last-child{margin-bottom:0}details.function>summary:before{content:'\2b';float:left;margin-left:-1rem}details.function[open]>summary:before{content:'\2212'}details.function[open]>:last-child{padding-bottom:.5rem}header div.deprecation-notice{margin-top:1rem}h2{font-size:1.8rem;margin-top:1.25rem;margin-bottom:.15rem}section h3{margin:.75rem 0 .25rem;font-size:1.4rem}section+section{margin-top:1.75rem}div.deprecation-notice{font-weight:bold;margin:.25rem 0}h1 span.deprecation-notice,span.deprecation-reason{font-weight:normal;font-style:italic}.info{padding:0 1.25rem}table.srcfile,table.licensefile{border:1px solid #8f8f8f;font-size:1.1rem;width:auto}table.srcfile tr:first-child td,table.licensefile tr:first-child td{padding-top:.5rem}table.srcfile tr:last-child td,table.licensefile tr:last-child td{padding-bottom:.5rem}.licensefile td,.srcfile td,.srcfile a{color:#424242}.licensefile td,.srcfile td{padding:.15rem 1rem;background-color:#f4f4f4}.srcfile td:first-child{text-align:right;padding:0 .5rem 0 1rem;border-right:1px solid #8f8f8f;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-ms-user-select:none;user-select:none}#sidenav{width:24%;margin-top:4rem;float:right;overflow:hidden;line-height:1.5;font-size:1.2rem;background:#fff}#sidenav input{display:none}#sidenav>a[href]{color:#fff}#sidenav h4{color:#fff;width:100%;font-size:1.4rem;font-weight:500;padding:.5rem 1.2rem 0;height:3rem;margin:0;border-top:1px solid rgba(255,255,255,0.2);border-bottom:1px solid #292929;background:#424242}#sidenav h4:hover{background:#545454}#sidenav li{list-style:none}#sidenav li.link:hover{background:rgba(82,82,82,0.1)}#sidenav li ul{padding:0 0 0 1.5rem}#sidenav ul{margin:0;padding:0 0 0 1rem;overflow:hidden;-webkit-transition:height .25s ease;-moz-transition:height .25s ease;-o-transition:height .25s ease;-ms-transition:height .25s ease;transition:height .25s ease}#main-wrapper{min-height:100%;height:100%;margin-bottom:-3rem}footer,#push-footer{clear:both;height:2rem}footer{font-size:1rem;background:#424242;padding:.5rem 0 .5rem 2.25rem;width:-webkit-calc(100% - 2.25rem);width:calc(100% - 2.25rem)}footer a[href]{color:rgba(255,255,255,0.8)} \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/dossier.js b/node_modules/selenium-webdriver/docs/dossier.js new file mode 100644 index 0000000..b2ebb52 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/dossier.js @@ -0,0 +1,135 @@ +(function(){var h,m=this;function aa(){} +function ba(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"== +b&&"undefined"==typeof a.call)return"object";return b}function r(a){return"array"==ba(a)}function ca(a){var b=ba(a);return"array"==b||"object"==b&&"number"==typeof a.length}function s(a){return"string"==typeof a}function da(a){return"number"==typeof a}function ea(a){return"function"==ba(a)}function fa(a){var b=typeof a;return"object"==b&&null!=a||"function"==b}function ga(a){return a[ha]||(a[ha]=++ia)}var ha="closure_uid_"+(1E9*Math.random()>>>0),ia=0; +function ja(a,b,c){return a.call.apply(a.bind,arguments)}function ka(a,b,c){if(!a)throw Error();if(2")&&(a=a.replace(sa,">"));-1!=a.indexOf('"')&&(a=a.replace(ta,"""));return a}var qa=/&/g,ra=//g,ta=/\"/g,pa=/[&<>\"]/;function ua(a){return String(a).replace(/([-()\[\]{}+?*.$\^|,:#c?Math.max(0,a.length+c):c;if(s(a))return s(b)&&1==b.length?a.indexOf(b,c):-1;for(;cc?null:s(a)?a.charAt(c):a[c]}function Aa(a){return z.concat.apply(z,arguments)} +function Ba(a){var b=a.length;if(0=arguments.length?z.slice.call(a,b):z.slice.call(a,b,c)};var Ea,Fa,Ga,Ha,B;function Ia(){return m.navigator?m.navigator.userAgent:null}function Ja(){return m.navigator}Ha=Ga=Fa=Ea=!1;var Ka;if(Ka=Ia()){var La=Ja();Ea=0==Ka.lastIndexOf("Opera",0);Fa=!Ea&&(-1!=Ka.indexOf("MSIE")||-1!=Ka.indexOf("Trident"));Ga=!Ea&&-1!=Ka.indexOf("WebKit");Ha=!Ea&&!Ga&&!Fa&&"Gecko"==La.product}var C=Ea,D=Fa,E=Ha,F=Ga,Ma=Ja();B=-1!=(Ma&&Ma.platform||"").indexOf("Mac");var Na=!!Ja()&&-1!=(Ja().appVersion||"").indexOf("X11"); +function Oa(){var a=m.document;return a?a.documentMode:void 0}var Pa;a:{var Qa="",Ra;if(C&&m.opera)var Sa=m.opera.version,Qa="function"==typeof Sa?Sa():Sa;else if(E?Ra=/rv\:([^\);]+)(\)|;)/:D?Ra=/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/:F&&(Ra=/WebKit\/(\S+)/),Ra)var Ta=Ra.exec(Ia()),Qa=Ta?Ta[1]:"";if(D){var Ua=Oa();if(Ua>parseFloat(Qa)){Pa=String(Ua);break a}}Pa=Qa}var Va={}; +function G(a){var b;if(!(b=Va[a])){b=0;for(var c=na(String(Pa)).split("."),d=na(String(a)).split("."),e=Math.max(c.length,d.length),f=0;0==b&&f(0==q[1].length?0:parseInt(q[1],10))?1:0)||((0==p[2].length)<(0==q[2].length)?-1: +(0==p[2].length)>(0==q[2].length)?1:0)||(p[2]q[2]?1:0)}while(0==b)}b=Va[a]=0<=b}return b}var Wa=m.document,H=Wa&&D?Oa()||("CSS1Compat"==Wa.compatMode?parseInt(Pa,10):5):void 0;var Xa=!D||D&&9<=H;!E&&!D||D&&D&&9<=H||E&&G("1.9.1");D&&G("9");var Ya="H3";function Za(a,b){var c;c=a.className;c=s(c)&&c.match(/\S+/g)||[];for(var d=Da(arguments,1),e=c.length+d.length,f=c,g=0;g");c=c.join("")}c=a.createElement(c);d&&(s(d)?c.className=d:r(d)?Za.apply(null,[c].concat(d)):hb(c,d));2"+d,c.removeChild(c.firstChild)):c.innerHTML=d;if(1==c.childNodes.length)d=c.removeChild(c.firstChild);else for(d=e.createDocumentFragment();c.firstChild;)d.appendChild(c.firstChild);return d}function vb(a){return fa(a)?"zSoyz":String(a)}var wb={};/* + + Copyright 2008 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +function N(a){return a&&a.va&&a.va===sb?a.content:String(a).replace(xb,yb)}var zb={"\x00":"�",'"':""","&":"&","'":"'","<":"<",">":">","\t":" ","\n":" ","\x0B":" ","\f":" ","\r":" "," ":" ","-":"-","/":"/","=":"=","`":"`","\u0085":"…","\u00a0":" ","\u2028":"
","\u2029":"
"};function yb(a){return zb[a]}var xb=/[\x00\x22\x26\x27\x3c\x3e]/g;function Ab(a){return'
"} +function Bb(a){var b="";if(a.types.length){for(var b=b+""}return b} +function Cb(a){var b,c=0");if(c){b+=a.file.name?"
  • "+N(a.file.name)+"/
      ":"";for(var c=a.file.children,d=c.length,e=0;e":""}else a.file.name&&(b+='
    "};var Db=!D||D&&9<=H,Eb=D&&!G("9");!F||G("528");E&&G("1.9b")||D&&G("8")||C&&G("9.5")||F&&G("528");E&&!G("8")||D&&G("9");function O(){0!=Fb&&(Gb[ga(this)]=this)}var Fb=0,Gb={};O.prototype.Oa=!1;O.prototype.B=function(){if(!this.Oa&&(this.Oa=!0,this.e(),0!=Fb)){var a=ga(this);delete Gb[a]}};O.prototype.e=function(){if(this.bb)for(;this.bb.length;)this.bb.shift()()};function Hb(a){a&&"function"==typeof a.B&&a.B()};function P(a,b){this.type=a;this.currentTarget=this.target=b}h=P.prototype;h.e=function(){};h.B=function(){};h.G=!1;h.defaultPrevented=!1;h.nb=!0;h.stopPropagation=function(){this.G=!0};h.preventDefault=function(){this.defaultPrevented=!0;this.nb=!1};var Ib="change";function Jb(a){Jb[" "](a);return a}Jb[" "]=aa;function Q(a,b){a&&Kb(this,a,b)}x(Q,P);h=Q.prototype;h.target=null;h.relatedTarget=null;h.offsetX=0;h.offsetY=0;h.clientX=0;h.clientY=0;h.screenX=0;h.screenY=0;h.button=0;h.keyCode=0;h.charCode=0;h.ctrlKey=!1;h.altKey=!1;h.shiftKey=!1;h.metaKey=!1;h.O=null; +function Kb(a,b,c){var d=a.type=b.type;P.call(a,d);a.target=b.target||b.srcElement;a.currentTarget=c;if(c=b.relatedTarget){if(E){var e;a:{try{Jb(c.nodeName);e=!0;break a}catch(f){}e=!1}e||(c=null)}}else"mouseover"==d?c=b.fromElement:"mouseout"==d&&(c=b.toElement);a.relatedTarget=c;a.offsetX=F||void 0!==b.offsetX?b.offsetX:b.layerX;a.offsetY=F||void 0!==b.offsetY?b.offsetY:b.layerY;a.clientX=void 0!==b.clientX?b.clientX:b.pageX;a.clientY=void 0!==b.clientY?b.clientY:b.pageY;a.screenX=b.screenX||0; +a.screenY=b.screenY||0;a.button=b.button;a.keyCode=b.keyCode||0;a.charCode=b.charCode||("keypress"==d?b.keyCode:0);a.ctrlKey=b.ctrlKey;a.altKey=b.altKey;a.shiftKey=b.shiftKey;a.metaKey=b.metaKey;a.state=b.state;a.O=b;b.defaultPrevented&&a.preventDefault();delete a.G}h.stopPropagation=function(){Q.i.stopPropagation.call(this);this.O.stopPropagation?this.O.stopPropagation():this.O.cancelBubble=!0}; +h.preventDefault=function(){Q.i.preventDefault.call(this);var a=this.O;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,Eb)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};h.e=function(){};var Lb="closure_listenable_"+(1E6*Math.random()|0);function Mb(a){try{return!(!a||!a[Lb])}catch(b){return!1}}var Nb=0;function Ob(a,b,c,d,e){this.K=a;this.ma=null;this.src=b;this.type=c;this.capture=!!d;this.ga=e;this.key=++Nb;this.U=this.ea=!1}function Pb(a){a.U=!0;a.K=null;a.ma=null;a.src=null;a.ga=null};function Qb(a){this.src=a;this.l={};this.da=0}Qb.prototype.add=function(a,b,c,d,e){var f=this.l[a];f||(f=this.l[a]=[],this.da++);var g=Rb(f,b,d,e);-1e.keyCode||void 0!=e.returnValue)){a:{var f=!1;if(0==e.keyCode)try{e.keyCode=-1;break a}catch(g){f=!0}if(f||void 0==e.returnValue)e.returnValue=!0}e=[];for(f=c.currentTarget;f;f=f.parentNode)e.push(f);for(var f=a.type,k=e.length-1;!c.G&&0<=k;k--)c.currentTarget=e[k],d&=bc(e[k],f,!0,c);for(k=0;!c.G&&k>>0);function Wb(a){return ea(a)?a:a[dc]||(a[dc]=function(b){return a.handleEvent(b)})};var ec=!!m.DOMTokenList,fc=ec?function(a){return a.classList}:function(a){a=a.className;return s(a)&&a.match(/\S+/g)||[]},S=ec?function(a,b){return a.classList.contains(b)}:function(a,b){var c=fc(a);return 0<=va(c,b)},gc=ec?function(a,b){a.classList.add(b)}:function(a,b){S(a,b)||(a.className+=0=this.left&&a.right<=this.right&&a.top>=this.top&&a.bottom<=this.bottom:a.x>=this.left&&a.x<=this.right&&a.y>=this.top&&a.y<=this.bottom:!1}; +T.prototype.round=function(){this.top=Math.round(this.top);this.right=Math.round(this.right);this.bottom=Math.round(this.bottom);this.left=Math.round(this.left);return this};function kc(a,b,c,d){this.left=a;this.top=b;this.width=c;this.height=d}kc.prototype.X=function(){return new kc(this.left,this.top,this.width,this.height)};kc.prototype.contains=function(a){return a instanceof kc?this.left<=a.left&&this.left+this.width>=a.left+a.width&&this.top<=a.top&&this.top+this.height>=a.top+a.height:a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this.top+this.height}; +kc.prototype.round=function(){this.left=Math.round(this.left);this.top=Math.round(this.top);this.width=Math.round(this.width);this.height=Math.round(this.height);return this};function U(a,b){var c=K(a);return c.defaultView&&c.defaultView.getComputedStyle&&(c=c.defaultView.getComputedStyle(a,null))?c[b]||c.getPropertyValue(b)||"":""}function V(a,b){return U(a,b)||(a.currentStyle?a.currentStyle[b]:null)||a.style&&a.style[b]} +function lc(a){var b;try{b=a.getBoundingClientRect()}catch(c){return{left:0,top:0,right:0,bottom:0}}D&&a.ownerDocument.body&&(a=a.ownerDocument,b.left-=a.documentElement.clientLeft+a.body.clientLeft,b.top-=a.documentElement.clientTop+a.body.clientTop);return b} +function mc(a){if(D&&!(D&&8<=H))return a.offsetParent;var b=K(a),c=V(a,"position"),d="fixed"==c||"absolute"==c;for(a=a.parentNode;a&&a!=b;a=a.parentNode)if(c=V(a,"position"),d=d&&"static"==c&&a!=b.documentElement&&a!=b.body,!d&&(a.scrollWidth>a.clientWidth||a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return null} +function nc(a){for(var b=new T(0,Infinity,Infinity,0),c=J(a),d=c.j.body,e=c.j.documentElement,f=jb(c.j);a=mc(a);)if(!(D&&0==a.clientWidth||F&&0==a.clientHeight&&a==d||a==d||a==e||"visible"==V(a,"overflow"))){var g=W(a),k;k=a;if(E&&!G("1.9")){var l=parseFloat(U(k,"borderLeftWidth"));if(oc(k))var n=k.offsetWidth-k.clientWidth-l-parseFloat(U(k,"borderRightWidth")),l=l+n;k=new I(l,parseFloat(U(k,"borderTopWidth")))}else k=new I(k.clientLeft,k.clientTop);g.x+=k.x;g.y+=k.y;b.top=Math.max(b.top,g.y);b.right= +Math.min(b.right,g.x+a.clientWidth);b.bottom=Math.min(b.bottom,g.y+a.clientHeight);b.left=Math.max(b.left,g.x)}d=f.scrollLeft;f=f.scrollTop;b.left=Math.max(b.left,d);b.top=Math.max(b.top,f);c=(c.j.parentWindow||c.j.defaultView||window).document;c="CSS1Compat"==c.compatMode?c.documentElement:c.body;c=new ab(c.clientWidth,c.clientHeight);b.right=Math.min(b.right,d+c.width);b.bottom=Math.min(b.bottom,f+c.height);return 0<=b.top&&0<=b.left&&b.bottom>b.top&&b.right>b.left?b:null} +function W(a){var b,c=K(a),d=V(a,"position"),e=E&&c.getBoxObjectFor&&!a.getBoundingClientRect&&"absolute"==d&&(b=c.getBoxObjectFor(a))&&(0>b.screenX||0>b.screenY),f=new I(0,0),g;b=c?K(c):document;g=!D||D&&9<=H||pb(J(b))?b.documentElement:b.body;if(a==g)return f;if(a.getBoundingClientRect)b=lc(a),a=qb(J(c)),f.x=b.left+a.x,f.y=b.top+a.y;else if(c.getBoxObjectFor&&!e)b=c.getBoxObjectFor(a),a=c.getBoxObjectFor(g),f.x=b.screenX-a.screenX,f.y=b.screenY-a.screenY;else{b=a;do{f.x+=b.offsetLeft;f.y+=b.offsetTop; +b!=a&&(f.x+=b.clientLeft||0,f.y+=b.clientTop||0);if(F&&"fixed"==V(b,"position")){f.x+=c.body.scrollLeft;f.y+=c.body.scrollTop;break}b=b.offsetParent}while(b&&b!=a);if(C||F&&"absolute"==d)f.y-=c.body.offsetTop;for(b=a;(b=mc(b))&&b!=c.body&&b!=g;)f.x-=b.scrollLeft,C&&"TR"==b.tagName||(f.y-=b.scrollTop)}return f}function pc(a,b){"number"==typeof a&&(a=(b?Math.round(a):a)+"px");return a} +function qc(a){var b=rc;if("none"!=V(a,"display"))return b(a);var c=a.style,d=c.display,e=c.visibility,f=c.position;c.visibility="hidden";c.position="absolute";c.display="inline";a=b(a);c.display=d;c.position=f;c.visibility=e;return a}function rc(a){var b=a.offsetWidth,c=a.offsetHeight,d=F&&!b&&!c;return(void 0===b||d)&&a.getBoundingClientRect?(a=lc(a),new ab(a.right-a.left,a.bottom-a.top)):new ab(b,c)}function sc(a,b){a.style.display=b?"":"none"}function oc(a){return"rtl"==V(a,"direction")} +var tc=E?"MozUserSelect":F?"WebkitUserSelect":null;function uc(a){var b=a.getElementsByTagName("*");if(tc){var c="none";a.style[tc]=c;if(b){a=0;for(var d;d=b[a];a++)d.style[tc]=c}}else if(D||C)if(c="on",a.setAttribute("unselectable",c),b)for(a=0;d=b[a];a++)d.setAttribute("unselectable",c)} +function vc(a,b){if(/^\d+px?$/.test(b))return parseInt(b,10);var c=a.style.left,d=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;a.style.left=b;var e=a.style.pixelLeft;a.style.left=c;a.runtimeStyle.left=d;return e}function wc(a,b){var c=a.currentStyle?a.currentStyle[b]:null;return c?vc(a,c):0}var xc={thin:2,medium:4,thick:6}; +function yc(a,b){if("none"==(a.currentStyle?a.currentStyle[b+"Style"]:null))return 0;var c=a.currentStyle?a.currentStyle[b+"Width"]:null;return c in xc?xc[c]:vc(a,c)}function zc(a){if(D&&!(D&&9<=H)){var b=yc(a,"borderLeft"),c=yc(a,"borderRight"),d=yc(a,"borderTop");a=yc(a,"borderBottom");return new T(d,c,a,b)}b=U(a,"borderLeftWidth");c=U(a,"borderRightWidth");d=U(a,"borderTopWidth");a=U(a,"borderBottomWidth");return new T(parseFloat(d),parseFloat(c),parseFloat(a),parseFloat(b))} +var Ac=/[^\d]+$/,Bc={cm:1,"in":1,mm:1,pc:1,pt:1},Cc={em:1,ex:1};function Dc(){var a=document.documentElement,b=V(a,"fontSize"),c;c=(c=b.match(Ac))&&c[0]||null;if(b&&"px"==c)return parseInt(b,10);if(D){if(c in Bc)return vc(a,b);if(a.parentNode&&1==a.parentNode.nodeType&&c in Cc)return a=a.parentNode,c=V(a,"fontSize"),vc(a,b==c?"1em":b)}c=kb("span",{style:"visibility:hidden;position:absolute;line-height:0;padding:0;margin:0;border:0;height:1em;"});a.appendChild(c);b=c.offsetHeight;ob(c);return b} +var Ec=/matrix\([0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, ([0-9\.\-]+)p?x?, ([0-9\.\-]+)p?x?\)/;function Fc(a){this.c=a||[];this.Ub=!0}function Gc(a,b,c){var d=[];if(""!=a){a=ua(a);a=RegExp("(^|\\W+)"+a,"i");for(var e=0;ep?(p=u-p-1,p>q-5&&(p=q-5),l+=p,p=u):(l+=q,q+=5);l<6*g.length&&d.push({Rb:f,ob:l,index:e})}d.sort(function(a,b){var c=a.ob-b.ob;return 0!=c?c:a.index-b.index});a=[];for(y=0;y=a.k&&ca.k)c--;else if(a.Ma&&c==a.k){a.A(-1);break}else if(!a.tb||-1!=c&&c!=a.k)break;else c=b;if(a.A(c))break}}h.A=function(a){var b=Oc(this,a),c=this.c[b];return c&&this.R.za&&this.R.za(c)?!1:(this.D=a,this.p.A(a),-1!=b)}; +function Pc(a){var b=Oc(a,a.D);if(-1!=b){var b=a.c[b],c=a.aa,d=b.toString();if(c.S){var e=Uc(c,c.a.value,Vc(c.a)),f=Wc(c,c.a.value);c.Ob.test(d)||(d=d.replace(/[\s\xa0]+$/,"")+c.yb);c.Wb&&(0==e||/^[\s\xa0]*$/.test(f[e-1])||(d=" "+d),e==f.length-1&&(d+=" "));if(d!=f[e]){f[e]=d;d=c.a;(E||D&&G("9"))&&d.blur();d.value=f.join("");for(var g=0,k=0;k<=e;k++)g+=f[k].length;d.focus();e=g;f=c.a;d=e;Xc(f)?f.selectionStart=d:D&&(g=Yc(f),k=g[0],k.inRange(g[1])&&(d=Zc(f,d),k.collapse(!0),k.move("character",d),k.select())); +f=c.a;Xc(f)?f.selectionEnd=e:D&&(g=Yc(f),d=g[1],g[0].inRange(d)&&(e=Zc(f,e),f=Zc(f,Vc(f)),d.collapse(!0),d.moveEnd("character",e-f),d.select()))}}else c.a.value=d;c.Ja=!0;a.qb?(a.q=null,Rc(a)):a.u();a.dispatchEvent({type:"update",V:b});a.qb&&a.aa.update(!0);return!0}a.u();a.dispatchEvent({type:"update",V:null});return!1}h.u=function(){this.D=-1;this.q=null;this.k+=this.c.length;this.c=[];window.clearTimeout(this.J);this.J=null;this.p.u();this.dispatchEvent("suggestionsupdate");this.dispatchEvent(Nc)}; +function Rc(a){a.J||(a.J=window.setTimeout(t(a.u,a),100))}h.Ua=function(){return this.J?(window.clearTimeout(this.J),this.J=null,!0):!1};function Qc(a){a.Ua()||window.setTimeout(t(a.Ua,a),10)}h.e=function(){Jc.i.e.call(this);delete this.Va;this.p.B();this.aa.B();this.R=null};h.Ib=function(a,b,c){this.q==a&&this.Ha(b,c)}; +h.Ha=function(a,b){var c="object"==ba(b)&&b,d=(c?c.Yb():b)?Oc(this,this.D):-1;this.k+=this.c.length;this.c=a;for(var e=[],f=0;fc||c>=a.c.length?-1:c} +h.ta=function(a){var b=this.aa;b.ta.apply(b,arguments)};h.update=function(a){this.aa.update(a)};function $c(a,b){X.call(this);this.Q=a||1;this.W=b||m;this.ua=t(this.Sb,this);this.Ca=w()}x($c,X);h=$c.prototype;h.enabled=!1;h.f=null;h.Sb=function(){if(this.enabled){var a=w()-this.Ca;0=a||96<=a&&106>=a||65<=a&&90>=a||F&&0==a)return!0;switch(a){case 32:case 63:case 107:case 109:case 110:case 111:case 186:case 59:case 189:case 187:case 61:case 188:case 190:case 191:case 192:case 222:case 219:case 220:case 221:return!0;default:return!1}}function jd(a){if(E)a=kd(a);else if(B&&F)a:switch(a){case 93:a=91;break a}return a} +function kd(a){switch(a){case 61:return 187;case 59:return 186;case 173:return 189;case 224:return 91;case 0:return 224;default:return a}};function ld(a,b){X.call(this);a&&md(this,a,b)}x(ld,X);h=ld.prototype;h.b=null;h.ia=null;h.Aa=null;h.ja=null;h.m=-1;h.F=-1;h.sa=!1; +var nd={3:13,12:144,63232:38,63233:40,63234:37,63235:39,63236:112,63237:113,63238:114,63239:115,63240:116,63241:117,63242:118,63243:119,63244:120,63245:121,63246:122,63247:123,63248:44,63272:46,63273:36,63275:35,63276:33,63277:34,63289:144,63302:45},od={Up:38,Down:40,Left:37,Right:39,Enter:13,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,"U+007F":46,Home:36,End:35,PageUp:33,PageDown:34,Insert:45},pd=D||F&&G("525"),qd=B&&E;h=ld.prototype; +h.Eb=function(a){F&&(17==this.m&&!a.ctrlKey||18==this.m&&!a.altKey||B&&91==this.m&&!a.metaKey)&&(this.F=this.m=-1);-1==this.m&&(a.ctrlKey&&17!=a.keyCode?this.m=17:a.altKey&&18!=a.keyCode?this.m=18:a.metaKey&&91!=a.keyCode&&(this.m=91));pd&&!hd(a.keyCode,this.m,a.shiftKey,a.ctrlKey,a.altKey)?this.handleEvent(a):(this.F=jd(a.keyCode),qd&&(this.sa=a.altKey))};h.Gb=function(a){this.F=this.m=-1;this.sa=a.altKey}; +h.handleEvent=function(a){var b=a.O,c,d,e=b.altKey;D&&"keypress"==a.type?(c=this.F,d=13!=c&&27!=c?b.keyCode:0):F&&"keypress"==a.type?(c=this.F,d=0<=b.charCode&&63232>b.charCode&&id(c)?b.charCode:0):C?(c=this.F,d=id(c)?b.keyCode:0):(c=b.keyCode||this.F,d=b.charCode||0,qd&&(e=this.sa),B&&63==d&&224==c&&(c=191));var f=c=jd(c),g=b.keyIdentifier;c?63232<=c&&c in nd?f=nd[c]:25==c&&a.shiftKey&&(f=9):g&&g in od&&(f=od[g]);a=f==this.m;this.m=f;b=new rd(f,d,a,b);b.altKey=e;this.dispatchEvent(b)}; +function md(a,b,c){a.ja&&a.detach();a.b=b;a.ia=R(a.b,"keypress",a,c);a.Aa=R(a.b,"keydown",a.Eb,c,a);a.ja=R(a.b,"keyup",a.Gb,c,a)}h.detach=function(){this.ia&&(ac(this.ia),ac(this.Aa),ac(this.ja),this.ja=this.Aa=this.ia=null);this.b=null;this.F=this.m=-1};h.e=function(){ld.i.e.call(this);this.detach()};function rd(a,b,c,d){d&&Kb(this,d,void 0);this.type="key";this.keyCode=a;this.charCode=b;this.repeat=c}x(rd,Q);var sd,td;td=sd=!1;var ud=Ia();ud&&(-1!=ud.indexOf("Firefox")||-1!=ud.indexOf("Camino")||(-1!=ud.indexOf("iPhone")||-1!=ud.indexOf("iPod")?sd=!0:-1!=ud.indexOf("iPad")&&(td=!0)));var vd=sd,wd=td;function xd(a,b,c,d){O.call(this);d=d||150;this.S=null!=c?c:!0;this.ba=a||",;";this.yb=this.ba.substring(0,1);a=this.S?"[\\s"+this.ba+"]+":"[\\s]+";this.rb=RegExp("^"+a+"|"+a+"$","g");this.Ob=RegExp("\\s*["+this.ba+"]$");this.Za=b||"";this.Lb=this.S;this.f=0=d.right)&&(k&=-2),132==(k&132)&&(g.y=d.bottom)&&(k&=-5),g.xd.right&&k&16&&(e.width=Math.max(e.width-(g.x+e.width-d.right),0),n|=4),g.x+e.width>d.right&&k&1&&(g.x=Math.max(d.right-e.width,d.left),n|=1),k&2&&(n=n|(g.xd.right?32:0)),g.y=d.top&&g.y+e.height>d.bottom&&k&32&&(e.height=Math.max(e.height-(g.y+e.height-d.bottom),0),n|=8),g.y+e.height>d.bottom&&k&4&&(g.y=Math.max(d.bottom-e.height,d.top),n|=2),k&8&&(n=n|(g.yd.bottom?128:0)),d=n):d=256;d&496||(g=f,f=E&&(B||Na)&&G("1.9"),g instanceof I?(d=g.x,g=g.y):(d=g,g=void 0),c.style.left= +pc(d,f),c.style.top=pc(g,f),b==e||b&&e&&b.width==e.width&&b.height==e.height||(d=pb(J(K(c))),!D||d&&G("8")?(c=c.style,E?c.MozBoxSizing="border-box":F?c.WebkitBoxSizing="border-box":c.boxSizing="border-box",c.width=Math.max(e.width,0)+"px",c.height=Math.max(e.height,0)+"px"):(b=c.style,d?(D?(d=wc(c,"paddingLeft"),f=wc(c,"paddingRight"),g=wc(c,"paddingTop"),k=wc(c,"paddingBottom"),d=new T(g,f,k,d)):(d=U(c,"paddingLeft"),f=U(c,"paddingRight"),g=U(c,"paddingTop"),k=U(c,"paddingBottom"),d=new T(parseFloat(g), +parseFloat(f),parseFloat(k),parseFloat(d))),c=zc(c),b.pixelWidth=e.width-c.left-d.left-d.right-c.right,b.pixelHeight=e.height-c.top-d.top-d.bottom-c.bottom):(b.pixelWidth=e.width,b.pixelHeight=e.height))));a.oa&&(a.b.style.visibility="visible")}}h.e=function(){this.b&&($b(this.b,"click",this.Qa,!1,this),$b(this.b,"mousedown",this.Sa,!1,this),$b(this.b,"mouseover",this.Ta,!1,this),this.w.removeNode(this.b),this.b=null,this.t=!1);Hb(this.N);this.Ga=null;Rd.i.e.call(this)}; +function Vd(a,b,c){if(3==b.nodeType){var d=null;r(c)&&1w()-this.pb)&&this.dispatchEvent({type:Kc,V:this.c[a].id})};function Zd(a,b){var c=new Fc(a),d=new Rd,e=new xd(null,null,!1),c=new Jc(c,d,e);e.d=c;e.ta(b);return c};/* + Copyright 2013 Jason Leyba + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +function $d(){var a=m.TYPES;ae(a);M("type-index")&&M("file-index")&&M("module-index")&&(be("file-index",a.files),ce("type-index",a.types),ce("module-index",a.modules,!0));de();setTimeout(la(ee,a),0);setTimeout(fe,0)}var ge=["init"],$=m;ge[0]in $||!$.execScript||$.execScript("var "+ge[0]);for(var he;ge.length&&(he=ge.shift());)ge.length||void 0===$d?$=$[he]?$[he]:$[he]={}:$[he]=$d; +var ie=function(){var a="./";za(document.getElementsByTagName("script"),function(b){b=b.src;var c=b.length;return"dossier.js"===b.substr(c-10)?(a=b.substr(0,c-10),!0):!1});return a}(); +function ee(a){function b(){var a=c[e.value];a&&(window.location.href=ie+a)}var c={},d=Aa(ya(a.files,function(a){var b="file://"+a.name;c[b]=a.href;return b}),ya(a.types,function(a){c[a.name]=a.href;return a.name}));A(a.modules,function(a){c[a.name]=a.href;d=Aa(d,a.name,ya(a.types||[],function(b){var d=a.name+"."+b.name;c[d]=b.href;return d}))});a=M("searchbox");R(a,"submit",function(a){a.preventDefault();a.stopPropagation();b();return!1});var e=a.getElementsByTagName("input")[0];a=Zd(d,e);a.$a=15; +R(a,"update",b)} +function ae(a){function b(a,b,c,d){R(a,Ib,function(){b.style.height=pc(a.checked?c:0,!0);je(d,a)})}if(M("sidenav")){M("sidenav-overview").href=ie+"index.html";var c=M("sidenav-types-ctrl"),d=ce("sidenav-types",a.types),e=M("sidenav-modules-ctrl"),f=ce("sidenav-modules",a.modules),g=M("sidenav-files-ctrl");a=be("sidenav-files",a.files);var k=Dc(),l=qc(d).height/k+"rem",n=qc(a).height/k+"rem",k=qc(f).height/k+"rem";c.checked=ke("dossier.typesList");g.checked=ke("dossier.filesList");e.checked=ke("dossier.modulesList"); +d.style.height=pc(c.checked?l:0,!0);a.style.height=pc(g.checked?n:0,!0);f.style.height=pc(e.checked?k:0,!0);b(c,d,l,"dossier.typesList");b(g,a,n,"dossier.filesList");b(e,f,k,"dossier.modulesList")}}function le(a,b){this.name=a;this.href=b||"";this.children=[]} +function me(a){function b(a){A(a.children,b);!a.href&&1===a.children.length&&a.children[0].children.length&&(a.name=(a.name?a.name+"/":"")+a.children[0].name,a.href=a.children[0].href,a.children=a.children[0].children)}var c=new le("");A(a,function(a){var b=a.name.split(/[\/\\]/),f=c;A(b,function(c,k){if(c)if(k===b.length-1)f.children.push(new le(c,a.href));else{var l=za(f.children,function(a){return a.name===c});l||(l=new le(c),f.children.push(l));f=l}})});b(c);return c} +function be(a,b){var c=M(a),d=c.querySelector("i");if(!b.length)return d;var e=me(b),e=ub(Cb,{file:e,I:ie});ob(d);c.appendChild(e);return e}function ce(a,b,c){a=M(a);var d=a.querySelector("i");return(b=ub(Bb,{types:b,I:ie,ya:!!c}))&&b.childNodes.length?(ob(d),a.appendChild(b),b):d} +function fe(){var a=document.getElementsByTagName("DETAILS");a.length&&!a[0].hasOwnProperty("open")&&A(a,function(a){function c(){(d=!d)?a.setAttribute("open",""):a.removeAttribute("open");A(a.childNodes,function(a){1===a.nodeType&&"SUMMARY"!==a.tagName.toUpperCase()&&sc(a,d)})}var d=!0;a.setAttribute("open","");R(a,"click",c);c()})}function je(a,b){window.localStorage&&(b.checked?window.localStorage.setItem(a,"1"):window.localStorage.removeItem(a))} +function ke(a){return window.localStorage?!!window.localStorage.getItem(a):!1}var ne="public",oe="protected",pe="private";function qe(a){return"dossier.visibility."+a} +function de(){function a(){var a=window.localStorage;a&&!a.getItem("dossier.visibility")&&(a.setItem("dossier.visibility","1"),a.setItem(qe(ne),"1"),a.removeItem(qe(oe)),a.removeItem(qe(pe)))}function b(a,b){var d=document.getElementById(a);if(d){var e=qe(b);d.checked=ke(e);c(d,b);R(d,Ib,function(){je(e,d);c(d,b)})}}function c(a,b){a.checked?gc(f,b):ic(f,b)}function d(a){function b(){for(var a=[],e=d=f=y=0,k=c.length;ebot.ErrorCode \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_bot_Error_State.html b/node_modules/selenium-webdriver/docs/enum_bot_Error_State.html new file mode 100644 index 0000000..49054c1 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_bot_Error_State.html @@ -0,0 +1 @@ +bot.Error.State \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_goog_dom_NodeType.html b/node_modules/selenium-webdriver/docs/enum_goog_dom_NodeType.html new file mode 100644 index 0000000..a85c299 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_goog_dom_NodeType.html @@ -0,0 +1,10 @@ +goog.dom.NodeType

    Enum goog.dom.NodeType

    code »
    Type: number

    Constants for the nodeType attribute in the Node interface. + + These constants match those specified in the Node interface. These are + usually present on the Node object in recent browsers, but not in older + browsers (specifically, early IEs) and thus are given here. + + In some browsers (early IEs), these are not defined on the Node object, + so they are provided here. + + See http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247

    Values and Descriptions

    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_goog_net_XmlHttp_OptionType.html b/node_modules/selenium-webdriver/docs/enum_goog_net_XmlHttp_OptionType.html new file mode 100644 index 0000000..0a54e80 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_goog_net_XmlHttp_OptionType.html @@ -0,0 +1,4 @@ +goog.net.XmlHttp.OptionType

    Enum goog.net.XmlHttp.OptionType

    code »
    Type: number

    Type of options that an XmlHttp object can have.

    Values and Descriptions

    LOCAL_REQUEST_ERROR
    NOTE(user): In IE if send() errors on a *local* request the readystate + is still changed to COMPLETE. We need to ignore it and allow the + try/catch around send() to pick up the error.
    USE_NULL_FUNCTION
    Whether a goog.nullFunction should be used to clear the onreadystatechange + handler instead of null.
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_goog_net_XmlHttp_ReadyState.html b/node_modules/selenium-webdriver/docs/enum_goog_net_XmlHttp_ReadyState.html new file mode 100644 index 0000000..34c76b3 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_goog_net_XmlHttp_ReadyState.html @@ -0,0 +1,3 @@ +goog.net.XmlHttp.ReadyState

    Enum goog.net.XmlHttp.ReadyState

    code »
    Type: number

    Status constants for XMLHTTP, matches: + http://msdn.microsoft.com/library/default.asp?url=/library/ + en-us/xmlsdk/html/0e6a34e4-f90c-489d-acff-cb44242fafc6.asp

    Values and Descriptions

    COMPLETE
    Constant for when xmlhttprequest.readyState is completed
    INTERACTIVE
    Constant for when xmlhttprequest.readyState is in an interactive state.
    LOADED
    Constant for when xmlhttprequest.readyState is loaded.
    LOADING
    Constant for when xmlhttprequest.readyState is loading.
    UNINITIALIZED
    Constant for when xmlhttprequest.readyState is uninitialized
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_goog_string_Unicode.html b/node_modules/selenium-webdriver/docs/enum_goog_string_Unicode.html new file mode 100644 index 0000000..becb661 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_goog_string_Unicode.html @@ -0,0 +1 @@ +goog.string.Unicode

    Enum goog.string.Unicode

    code »
    Type: string

    Common Unicode string characters.

    Values and Descriptions

    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_goog_uri_utils_CharCode_.html b/node_modules/selenium-webdriver/docs/enum_goog_uri_utils_CharCode_.html new file mode 100644 index 0000000..4c9fb9e --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_goog_uri_utils_CharCode_.html @@ -0,0 +1 @@ +goog.uri.utils.CharCode_

    Enum goog.uri.utils.CharCode_

    code »
    Type: number

    Character codes inlined to avoid object allocations due to charCode.

    Values and Descriptions

    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_goog_uri_utils_ComponentIndex.html b/node_modules/selenium-webdriver/docs/enum_goog_uri_utils_ComponentIndex.html new file mode 100644 index 0000000..82afbbb --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_goog_uri_utils_ComponentIndex.html @@ -0,0 +1 @@ +goog.uri.utils.ComponentIndex

    Enum goog.uri.utils.ComponentIndex

    code »
    Type: number

    The index of each URI component in the return value of goog.uri.utils.split.

    Values and Descriptions

    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_goog_uri_utils_StandardQueryParam.html b/node_modules/selenium-webdriver/docs/enum_goog_uri_utils_StandardQueryParam.html new file mode 100644 index 0000000..ced027a --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_goog_uri_utils_StandardQueryParam.html @@ -0,0 +1 @@ +goog.uri.utils.StandardQueryParam

    Enum goog.uri.utils.StandardQueryParam

    code »
    Type: string

    Standard supported query parameters.

    Values and Descriptions

    RANDOM
    Unused parameter for unique-ifying.
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_webdriver_Browser.html b/node_modules/selenium-webdriver/docs/enum_webdriver_Browser.html new file mode 100644 index 0000000..a50d566 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_webdriver_Browser.html @@ -0,0 +1 @@ +webdriver.Browser

    Enum webdriver.Browser

    code »
    Type: string

    Recognized browser names.

    Values and Descriptions

    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_webdriver_Button.html b/node_modules/selenium-webdriver/docs/enum_webdriver_Button.html new file mode 100644 index 0000000..7b2018b --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_webdriver_Button.html @@ -0,0 +1 @@ +webdriver.Button

    Enum webdriver.Button

    code »
    Type: number

    Enumeration of the buttons used in the advanced interactions API.

    Values and Descriptions

    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_webdriver_Capability.html b/node_modules/selenium-webdriver/docs/enum_webdriver_Capability.html new file mode 100644 index 0000000..a16afd9 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_webdriver_Capability.html @@ -0,0 +1,14 @@ +webdriver.Capability

    Enum webdriver.Capability

    code »
    Type: string

    Common webdriver capability keys.

    Values and Descriptions

    ACCEPT_SSL_CERTS
    Indicates whether a driver should accept all SSL certs by default. This + capability only applies when requesting a new session. To query whether + a driver can handle insecure SSL certs, see + webdriver.Capability.SECURE_SSL.
    BROWSER_NAME
    The browser name. Common browser names are defined in the + webdriver.Browser enum.
    HANDLES_ALERTS
    Whether the driver is capable of handling modal alerts (e.g. alert, + confirm, prompt). To define how a driver should handle alerts, + use webdriver.Capability.UNEXPECTED_ALERT_BEHAVIOR.
    LOGGING_PREFS
    Key for the logging driver logging preferences.
    PLATFORM
    Describes the platform the browser is running on. Will be one of + ANDROID, IOS, LINUX, MAC, UNIX, or WINDOWS. When requesting a + session, ANY may be used to indicate no platform preference (this is + semantically equivalent to omitting the platform capability).
    PROXY
    Describes the proxy configuration to use for a new WebDriver session.
    ROTATABLE
    Whether the driver supports changing the brower's orientation.
    SECURE_SSL
    Whether a driver is only capable of handling secure SSL certs. To request + that a driver accept insecure SSL certs by default, use + webdriver.Capability.ACCEPT_SSL_CERTS.
    SUPPORTS_APPLICATION_CACHE
    Whether the driver supports manipulating the app cache.
    SUPPORTS_BROWSER_CONNECTION
    Whether the driver supports controlling the browser's internet + connectivity.
    SUPPORTS_CSS_SELECTORS
    Whether the driver supports locating elements with CSS selectors.
    SUPPORTS_JAVASCRIPT
    Whether the browser supports JavaScript.
    SUPPORTS_LOCATION_CONTEXT
    Whether the driver supports controlling the browser's location info.
    TAKES_SCREENSHOT
    Whether the driver supports taking screenshots.
    UNEXPECTED_ALERT_BEHAVIOR
    Defines how the driver should handle unexpected alerts. The value should + be one of "accept", "dismiss", or "ignore.
    VERSION
    Defines the browser version.
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_webdriver_CommandName.html b/node_modules/selenium-webdriver/docs/enum_webdriver_CommandName.html new file mode 100644 index 0000000..51e2c1b --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_webdriver_CommandName.html @@ -0,0 +1,2 @@ +webdriver.CommandName

    Enum webdriver.CommandName

    code »
    Type: string

    Enumeration of predefined names command names that all command processors + will support.

    Values and Descriptions

    ACCEPT_ALERT
    ADD_COOKIE
    CLEAR_APP_CACHE
    CLEAR_ELEMENT
    CLEAR_LOCAL_STORAGE
    CLEAR_SESSION_STORAGE
    CLICK
    CLICK_ELEMENT
    CLOSE
    DELETE_ALL_COOKIES
    DELETE_COOKIE
    DESCRIBE_SESSION
    DISMISS_ALERT
    DOUBLE_CLICK
    ELEMENT_EQUALS
    EXECUTE_ASYNC_SCRIPT
    EXECUTE_SCRIPT
    EXECUTE_SQL
    FIND_CHILD_ELEMENT
    FIND_CHILD_ELEMENTS
    FIND_ELEMENT
    FIND_ELEMENTS
    GET
    GET_ACTIVE_ELEMENT
    GET_ALERT_TEXT
    GET_ALL_COOKIES
    GET_APP_CACHE
    GET_APP_CACHE_STATUS
    GET_AVAILABLE_LOG_TYPES
    GET_COOKIE
    GET_CURRENT_URL
    GET_CURRENT_WINDOW_HANDLE
    GET_ELEMENT_ATTRIBUTE
    GET_ELEMENT_LOCATION
    GET_ELEMENT_LOCATION_IN_VIEW
    GET_ELEMENT_SIZE
    GET_ELEMENT_TAG_NAME
    GET_ELEMENT_TEXT
    GET_ELEMENT_VALUE_OF_CSS_PROPERTY
    GET_LOCAL_STORAGE_ITEM
    GET_LOCAL_STORAGE_KEYS
    GET_LOCAL_STORAGE_SIZE
    GET_LOCATION
    GET_LOG
    GET_PAGE_SOURCE
    GET_SCREEN_ORIENTATION
    GET_SERVER_STATUS
    GET_SESSIONS
    GET_SESSION_LOGS
    GET_SESSION_STORAGE_ITEM
    GET_SESSION_STORAGE_KEYS
    GET_SESSION_STORAGE_SIZE
    GET_TITLE
    GET_WINDOW_HANDLES
    GET_WINDOW_POSITION
    GET_WINDOW_SIZE
    GO_BACK
    GO_FORWARD
    IMPLICITLY_WAIT
    IS_BROWSER_ONLINE
    IS_ELEMENT_DISPLAYED
    IS_ELEMENT_ENABLED
    IS_ELEMENT_SELECTED
    MAXIMIZE_WINDOW
    MOUSE_DOWN
    MOUSE_UP
    MOVE_TO
    NEW_SESSION
    QUIT
    REFRESH
    REMOVE_LOCAL_STORAGE_ITEM
    REMOVE_SESSION_STORAGE_ITEM
    SCREENSHOT
    SEND_KEYS_TO_ACTIVE_ELEMENT
    SEND_KEYS_TO_ELEMENT
    SET_ALERT_TEXT
    SET_BROWSER_ONLINE
    SET_LOCAL_STORAGE_ITEM
    SET_LOCATION
    SET_SCREEN_ORIENTATION
    SET_SCRIPT_TIMEOUT
    SET_SESSION_STORAGE_ITEM
    SET_TIMEOUT
    SET_WINDOW_POSITION
    SET_WINDOW_SIZE
    SUBMIT_ELEMENT
    SWITCH_TO_FRAME
    SWITCH_TO_WINDOW
    TOUCH_DOUBLE_TAP
    TOUCH_DOWN
    TOUCH_FLICK
    TOUCH_LONG_PRESS
    TOUCH_MOVE
    TOUCH_SCROLL
    TOUCH_SINGLE_TAP
    TOUCH_UP
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_webdriver_FirefoxDomExecutor_Attribute_.html b/node_modules/selenium-webdriver/docs/enum_webdriver_FirefoxDomExecutor_Attribute_.html new file mode 100644 index 0000000..991d820 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_webdriver_FirefoxDomExecutor_Attribute_.html @@ -0,0 +1 @@ +webdriver.FirefoxDomExecutor.Attribute_

    Enum webdriver.FirefoxDomExecutor.Attribute_

    code »
    Type: string

    Attributes used to communicate with the FirefoxDriver extension.

    Values and Descriptions

    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_webdriver_FirefoxDomExecutor_EventType_.html b/node_modules/selenium-webdriver/docs/enum_webdriver_FirefoxDomExecutor_EventType_.html new file mode 100644 index 0000000..77449eb --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_webdriver_FirefoxDomExecutor_EventType_.html @@ -0,0 +1 @@ +webdriver.FirefoxDomExecutor.EventType_

    Enum webdriver.FirefoxDomExecutor.EventType_

    code »
    Type: string

    Events used to communicate with the FirefoxDriver extension.

    Values and Descriptions

    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_webdriver_Key.html b/node_modules/selenium-webdriver/docs/enum_webdriver_Key.html new file mode 100644 index 0000000..68acdcf --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_webdriver_Key.html @@ -0,0 +1,9 @@ +webdriver.Key

    Enum webdriver.Key

    code »
    Type: string

    Representations of pressable keys that aren't text. These are stored in + the Unicode PUA (Private Use Area) code points, 0xE000-0xF8FF. Refer to + http://www.google.com.au/search?&q=unicode+pua&btnG=Search

    Values and Descriptions

    Show:

    Global Functions

    Simulate pressing many keys at once in a "chord". Takes a sequence of + webdriver.Keys or strings, appends each of the values to a string, + and adds the chord termination key (webdriver.Key.NULL) and returns + the resultant string. + + Note: when the low-level webdriver key handlers see Keys.NULL, active + modifier keys (CTRL/ALT/SHIFT/etc) release via a keyup event.

    Parameters
    var_args: ...string
    The key sequence to concatenate.
    Returns
    The null-terminated key sequence.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_webdriver_logging_Level.html b/node_modules/selenium-webdriver/docs/enum_webdriver_logging_Level.html new file mode 100644 index 0000000..96cce56 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_webdriver_logging_Level.html @@ -0,0 +1 @@ +webdriver.logging.Level

    Enum webdriver.logging.Level

    code »
    Type: {value: number, name: webdriver.logging.LevelName}

    Logging levels.

    Values and Descriptions

    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_webdriver_logging_LevelName.html b/node_modules/selenium-webdriver/docs/enum_webdriver_logging_LevelName.html new file mode 100644 index 0000000..2df7088 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_webdriver_logging_LevelName.html @@ -0,0 +1 @@ +webdriver.logging.LevelName

    Enum webdriver.logging.LevelName

    code »
    Type: string

    Log level names from WebDriver's JSON wire protocol.

    Values and Descriptions

    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_webdriver_logging_Type.html b/node_modules/selenium-webdriver/docs/enum_webdriver_logging_Type.html new file mode 100644 index 0000000..c69f777 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_webdriver_logging_Type.html @@ -0,0 +1 @@ +webdriver.logging.Type

    Enum webdriver.logging.Type

    code »
    Type: string

    Common log types.

    Values and Descriptions

    BROWSER
    Logs originating from the browser.
    CLIENT
    Logs from a WebDriver client.
    DRIVER
    Logs from a WebDriver implementation.
    PERFORMANCE
    Logs related to performance.
    SERVER
    Logs from the remote server.
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_webdriver_promise_ControlFlow_EventType.html b/node_modules/selenium-webdriver/docs/enum_webdriver_promise_ControlFlow_EventType.html new file mode 100644 index 0000000..ad2c4ca --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_webdriver_promise_ControlFlow_EventType.html @@ -0,0 +1,4 @@ +webdriver.promise.ControlFlow.EventType

    Enum webdriver.promise.ControlFlow.EventType

    code »
    Type: string

    Events that may be emitted by an webdriver.promise.ControlFlow.

    Values and Descriptions

    IDLE
    Emitted when all tasks have been successfully executed.
    SCHEDULE_TASK
    Emitted whenever a new task has been scheduled.
    UNCAUGHT_EXCEPTION
    Emitted whenever a control flow aborts due to an unhandled promise + rejection. This event will be emitted along with the offending rejection + reason. Upon emitting this event, the control flow will empty its task + queue and revert to its initial state.
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/enum_webdriver_promise_Deferred_State_.html b/node_modules/selenium-webdriver/docs/enum_webdriver_promise_Deferred_State_.html new file mode 100644 index 0000000..9f7c155 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/enum_webdriver_promise_Deferred_State_.html @@ -0,0 +1 @@ +webdriver.promise.Deferred.State_

    Enum webdriver.promise.Deferred.State_

    code »
    Type: number

    The three states a webdriver.promise.Deferred object may be in.

    Values and Descriptions

    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/index.html b/node_modules/selenium-webdriver/docs/index.html new file mode 100644 index 0000000..9ae9991 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/index.html @@ -0,0 +1,62 @@ +Index

    selenium-webdriver

    +

    Installation

    +

    Install the latest published version using npm:

    +
    npm install selenium-webdriver
    +
    +

    In addition to the npm package, you will to download the WebDriver +implementations you wish to utilize. As of 2.34.0, selenium-webdriver +natively supports the ChromeDriver. +Simply download a copy and make sure it can be found on your PATH. The other +drivers (e.g. Firefox, Internet Explorer, and Safari), still require the +standalone Selenium server.

    +

    Running the tests

    +

    To run the tests, you will need to download a copy of the +ChromeDriver and make +sure it can be found on your PATH.

    +
    npm test selenium-webdriver
    +
    +

    To run the tests against multiple browsers, download the +Selenium server and +specify its location through the SELENIUM_SERVER_JAR environment variable. +You can use the SELENIUM_BROWSER environment variable to define a +comma-separated list of browsers you wish to test against. For example:

    +
    export SELENIUM_SERVER_JAR=path/to/selenium-server-standalone-2.33.0.jar
    +SELENIUM_BROWSER=chrome,firefox npm test selenium-webdriver
    +
    +

    Usage

    +
    var webdriver = require('selenium-webdriver');
    +
    +var driver = new webdriver.Builder().
    +    withCapabilities(webdriver.Capabilities.chrome()).
    +    build();
    +
    +driver.get('http://www.google.com');
    +driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
    +driver.findElement(webdriver.By.name('btnG')).click();
    +driver.wait(function() {
    +  return driver.getTitle().then(function(title) {
    +    return title === 'webdriver - Google Search';
    +  });
    +}, 1000);
    +
    +driver.quit();
    +
    +

    Documentation

    +

    API documentation is included in the docs module. The API documentation for the +current release are also available online from the Selenium project. A full user guide is available on the +Selenium project wiki.

    +

    Issues

    +

    Please report any issues using the Selenium issue tracker.

    +

    License

    +

    Copyright 2009-2014 Software Freedom Conservancy

    +

    Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at

    +
     http://www.apache.org/licenses/LICENSE-2.0
    +
    +

    Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License.

    +
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/interface_goog_labs_testing_Matcher.html b/node_modules/selenium-webdriver/docs/interface_goog_labs_testing_Matcher.html new file mode 100644 index 0000000..fb8e889 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/interface_goog_labs_testing_Matcher.html @@ -0,0 +1,2 @@ +goog.labs.testing.Matcher

    Interface goog.labs.testing.Matcher

    code »

    A matcher object to be used in assertThat statements.

    Show:

    Instance Methods

    code »describe ( value, opt_description )string

    Describes why the matcher failed.

    Parameters
    value: *
    The value that didn't match.
    opt_description: string=
    A partial description to which the reason + will be appended.
    Returns
    Description of why the matcher failed.
    code »matches ( value )boolean

    Determines whether a value matches the constraints of the match.

    Parameters
    value: *
    The object to match.
    Returns
    Whether the input value matches this matcher.

    Global Functions

    code »goog.labs.testing.Matcher.makeMatcher ( matchesFunction, opt_describeFunction )!Function

    Generates a Matcher from the ‘matches’ and ‘describe’ functions passed in.

    Parameters
    matchesFunction: !Function
    The ‘matches’ function.
    opt_describeFunction: Function=
    The ‘describe’ function.
    Returns
    The custom matcher.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/interface_goog_net_XhrLike.html b/node_modules/selenium-webdriver/docs/interface_goog_net_XhrLike.html new file mode 100644 index 0000000..3858328 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/interface_goog_net_XhrLike.html @@ -0,0 +1,3 @@ +goog.net.XhrLike

    Interface goog.net.XhrLike

    code »

    Interface for the common parts of XMLHttpRequest. + + Mostly copied from externs/w3c_xml.js.

    Show:

    Type Definitions

    Typedef that refers to either native or custom-implemented XHR objects.

    Instance Methods

    Parameters
    header
    code »open ( method, url, opt_async, opt_user, opt_password )
    Parameters
    method
    url
    opt_async
    opt_user
    opt_password
    code »send ( opt_data )
    Parameters
    opt_data
    code »setRequestHeader ( header, value )
    Parameters
    header
    value

    Instance Properties

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/interface_webdriver_CommandExecutor.html b/node_modules/selenium-webdriver/docs/interface_webdriver_CommandExecutor.html new file mode 100644 index 0000000..9b45f41 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/interface_webdriver_CommandExecutor.html @@ -0,0 +1,5 @@ +webdriver.CommandExecutor

    Interface webdriver.CommandExecutor

    code »

    Handles the execution of webdriver.Command objects.

    Show:

    Instance Methods

    code »execute ( command, callback )

    Executes the given command. If there is an error executing the + command, the provided callback will be invoked with the offending error. + Otherwise, the callback will be invoked with a null Error and non-null + bot.response.ResponseObject object.

    Parameters
    command: !webdriver.Command
    The command to execute.
    callback: function(Error, !bot.response.ResponseObject==)
    the function + to invoke when the command response is ready.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/interface_webdriver_http_Client.html b/node_modules/selenium-webdriver/docs/interface_webdriver_http_Client.html new file mode 100644 index 0000000..68f0fcc --- /dev/null +++ b/node_modules/selenium-webdriver/docs/interface_webdriver_http_Client.html @@ -0,0 +1,6 @@ +webdriver.http.Client

    Interface webdriver.http.Client

    code »

    Interface used for sending individual HTTP requests to the server.

    Show:

    Instance Methods

    code »send ( request, callback )

    Sends a request to the server. If an error occurs while sending the request, + such as a failure to connect to the server, the provided callback will be + invoked with a non-null Error describing the error. Otherwise, when + the server's response has been received, the callback will be invoked with a + null Error and non-null webdriver.http.Response object.

    Parameters
    request: !webdriver.http.Request
    The request to send.
    callback: function(Error, !webdriver.http.Response==)
    the function to + invoke when the server's response is ready.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/license.html b/node_modules/selenium-webdriver/docs/license.html new file mode 100644 index 0000000..962258d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/license.html @@ -0,0 +1,205 @@ +License

    License

    + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2007-2009 Google Inc. + Copyright 2007-2009 WebDriver committers + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver.html new file mode 100644 index 0000000..2764d07 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver.html @@ -0,0 +1,4 @@ +selenium-webdriver

    Module selenium-webdriver

    code »

    The main user facing module. Exports WebDriver's primary + public API and provides convenience assessors to certain sub-modules.

    Classes

    ActionSequence
    Class for defining sequences of complex user interactions.
    Builder
    Creates new WebDriver instances.
    Capabilities
    No Description.
    Command
    Describes a command to be executed by the WebDriverJS framework.
    EventEmitter
    Object that can emit events for others to listen for.
    Session
    Contains information about a WebDriver session.
    WebDriver
    Creates a new WebDriver client, which provides control over a browser.
    WebElement
    Represents a DOM element.

    Enumerations

    Browser
    Recognized browser names.
    Button
    Enumeration of the buttons used in the advanced interactions API.
    Capability
    Common webdriver capability keys.
    CommandName
    Enumeration of predefined names command names that all command processors + will support.
    Key
    Representations of pressable keys that aren't text.
    Show:

    Properties

    A collection of factory functions for creating webdriver.Locator + instances.

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver__base.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver__base.html new file mode 100644 index 0000000..02cc0a1 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver__base.html @@ -0,0 +1,14 @@ +selenium-webdriver/_base

    Module selenium-webdriver/_base

    code »

    The base module responsible for bootstrapping the Closure + library and providing a means of loading Closure-based modules. + +

    Each script loaded by this module will be granted access to this module's + require function; all required non-native modules must be specified + relative to this module. + +

    This module will load all scripts from the "lib" subdirectory, unless the + SELENIUM_DEV_MODE environment variable has been set to 1, in which case all + scripts will be loaded from the Selenium client containing this script.

    Show:

    Functions

    Loads a symbol by name from the protected Closure context and exports its + public API to the provided object. This function relies on Closure code + conventions to define the public API of an object as those properties whose + name does not end with "_".

    Parameters
    symbol: string
    The symbol to load. This must resolve to an object.
    Returns
    An object with the exported API.
    Throws
    Error
    If the symbol has not been defined or does not resolve to + an object.
    Returns
    Whether this script was loaded in dev mode.
    code »require ( symbol )

    Loads a symbol by name from the protected Closure context.

    Parameters
    symbol: string
    The symbol to load.
    Returns
    The loaded symbol, or null if not found.
    Throws
    Error
    If the symbol has not been defined.

    Properties

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_builder.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_builder.html new file mode 100644 index 0000000..6b20841 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_builder.html @@ -0,0 +1 @@ +selenium-webdriver/builder

    Module selenium-webdriver/builder

    code »

    Classes

    Builder
    Creates new WebDriver instances.
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_builder_class_Builder.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_builder_class_Builder.html new file mode 100644 index 0000000..bac7e53 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_builder_class_Builder.html @@ -0,0 +1,13 @@ +Builder

    Class Builder

    code »
    webdriver.AbstractBuilder
    +  └ Builder

    Creates new WebDriver instances.

    Constructor

    Builder ( )
    Show:

    Instance Methods

    Defined in Builder

    code »build ( )webdriver.WebDriver
    code »setChromeOptions ( options )!Builder

    Sets Chrome-specific options for drivers created by this builder.

    Parameters
    options: !chrome.Options
    The ChromeDriver options to use.
    Returns
    A self reference.
    code »setProxy ( config )!Builder

    Sets the proxy configuration to use for WebDriver clients created by this + builder. Any calls to #withCapabilities after this function will + overwrite these settings.

    Parameters
    config: !proxy.ProxyConfig
    The configuration to use.
    Returns
    A self reference.

    Defined in webdriver.AbstractBuilder

    Returns
    The current desired capabilities for this + builder.
    Returns
    The URL of the WebDriver server this instance is configured + to use.

    Configures which WebDriver server should be used for new sessions. Overrides + the value loaded from the webdriver.AbstractBuilder.SERVER_URL_ENV + upon creation of this instance.

    Parameters
    url: string
    URL of the server to use.
    Returns
    This Builder instance for chain calling.

    Sets the desired capabilities when requesting a new session. This will + overwrite any previously set desired capabilities.

    Parameters
    capabilities: !(Object|webdriver.Capabilities)
    The desired + capabilities for a new session.
    Returns
    This Builder instance for chain calling.

    Instance Properties

    Defined in webdriver.AbstractBuilder

    The desired capabilities to use when creating a new session.

    URL of the remote server to use for new clients; initialized from the + value of the webdriver.AbstractBuilder.SERVER_URL_ENV environment + variable, but may be overridden using + webdriver.AbstractBuilder#usingServer.

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_chrome.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_chrome.html new file mode 100644 index 0000000..3adf8b7 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_chrome.html @@ -0,0 +1,5 @@ +selenium-webdriver/chrome

    Module selenium-webdriver/chrome

    code »

    Classes

    Options
    Class for managing ChromeDriver specific options.
    ServiceBuilder
    Creates remote.DriverService instances that manage a ChromeDriver + server.
    Show:

    Functions

    code »createDriver ( opt_options, opt_service )!webdriver.WebDriver

    Creates a new ChromeDriver session.

    Parameters
    opt_options: (webdriver.Capabilities|Options)=
    The session options.
    opt_service: remote.DriverService=
    The session to use; will use + the default service by default.
    Returns
    A new WebDriver instance.
    code »getDefaultService ( )!remote.DriverService

    Returns the default ChromeDriver service. If such a service has not been + configured, one will be constructed using the default configuration for + a ChromeDriver executable found on the system PATH.

    Returns
    The default ChromeDriver service.

    Sets the default service to use for new ChromeDriver instances.

    Parameters
    service: !remote.DriverService
    The service to use.
    Throws
    Error
    If the default service is currently running.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_chrome_class_Options.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_chrome_class_Options.html new file mode 100644 index 0000000..171be4f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_chrome_class_Options.html @@ -0,0 +1,22 @@ +Options

    Class Options

    code »

    Class for managing ChromeDriver specific options.

    Constructor

    Options ( )
    Show:

    Instance Methods

    code »addArguments ( var_args )!Options

    Add additional command line arguments to use when launching the Chrome + browser. Each argument may be specified with or without the "--" prefix + (e.g. "--foo" and "foo"). Arguments with an associated value should be + delimited by an "=": "foo=bar".

    Parameters
    var_args: ...(string|!Array.<string>)
    The arguments to add.
    Returns
    A self reference.
    code »addExtensions ( var_args )!Options

    Add additional extensions to install when launching Chrome. Each extension + should be specified as the path to the packed CRX file, or a Buffer for an + extension.

    Parameters
    var_args: ...(string|!Buffer|!Array)
    The + extensions to add.
    Returns
    A self reference.
    code »detachDriver ( detach )!Options

    Sets whether to leave the started Chrome browser running if the controlling + ChromeDriver service is killed before webdriver.WebDriver#quit() is + called.

    Parameters
    detach: boolean
    Whether to leave the browser running if the + chromedriver service is killed before the session.
    Returns
    A self reference.
    code »setChromeBinaryPath ( path )!Options

    Sets the path to the Chrome binary to use. On Mac OS X, this path should + reference the actual Chrome executable, not just the application binary + (e.g. "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"). + + The binary path be absolute or relative to the chromedriver server + executable, but it must exist on the machine that will launch Chrome.

    Parameters
    path: string
    The path to the Chrome binary to use.
    Returns
    A self reference.
    code »setChromeLogFile ( path )!Options

    Sets the path to Chrome's log file. This path should exist on the machine + that will launch Chrome.

    Parameters
    path: string
    Path to the log file to use.
    Returns
    A self reference.
    code »setLocalState ( state )!Options

    Sets preferences for the "Local State" file in Chrome's user data + directory.

    Parameters
    state: !Object
    Dictionary of local state preferences.
    Returns
    A self reference.
    code »setLoggingPreferences ( prefs )!Options

    Sets the logging preferences for the new session.

    Parameters
    prefs: !webdriver.logging.Preferences
    The logging preferences.
    Returns
    A self reference.
    code »setProxy ( proxy )!Options

    Sets the proxy settings for the new session.

    Parameters
    proxy: ProxyConfig
    The proxy configuration to use.
    Returns
    A self reference.
    code »setUserPreferences ( prefs )!Options

    Sets the user preferences for Chrome's user profile. See the "Preferences" + file in Chrome's user data directory for examples.

    Parameters
    prefs: !Object
    Dictionary of user preferences to use.
    Returns
    A self reference.

    Converts this options instance to a webdriver.Capabilities object.

    Parameters
    opt_capabilities: webdriver.Capabilities=
    The capabilities to merge + these options into, if any.
    Returns
    The capabilities.
    code »toJSON ( ){args: !Array.<string>, binary: (string|undefined), detach: boolean, extensions: !Array.<string>, localState: (Object|undefined), logFile: (string|undefined), prefs: (Object|undefined)}

    Converts this instance to its JSON wire protocol representation. Note this + function is an implementation not intended for general use.

    Returns
    The JSON wire protocol representation + of this instance.

    Instance Properties

    Static Functions

    code »Options.fromCapabilities ( capabilities )!Options

    Extracts the ChromeDriver specific options from the given capabilities + object.

    Parameters
    capabilities: !webdriver.Capabilities
    The capabilities object.
    Returns
    The ChromeDriver options.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_chrome_class_ServiceBuilder.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_chrome_class_ServiceBuilder.html new file mode 100644 index 0000000..1b117df --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_chrome_class_ServiceBuilder.html @@ -0,0 +1,13 @@ +ServiceBuilder

    Class ServiceBuilder

    code »

    Creates remote.DriverService instances that manage a ChromeDriver + server.

    Constructor

    ServiceBuilder ( opt_exe )
    Parameters
    opt_exe: string=
    Path to the server executable to use. If omitted, + the builder will attempt to locate the chromedriver on the current + PATH.
    Throws
    Error
    If provided executable does not exist, or the chromedriver + cannot be found on the PATH.
    Show:

    Instance Methods

    code »build ( )remote.DriverService

    Creates a new DriverService using this instance's current configuration.

    Returns
    A new driver service using this instance's + current configuration.
    Throws
    Error
    If the driver exectuable was not specified and a default + could not be found on the current PATH.
    code »enableVerboseLogging ( )!ServiceBuilder

    Enables verbose logging.

    Returns
    A self reference.
    code »loggingTo ( path )!ServiceBuilder

    Sets the path of the log file the driver should log to. If a log file is + not specified, the driver will log to stderr.

    Parameters
    path: string
    Path of the log file to use.
    Returns
    A self reference.
    code »setNumHttpThreads ( n )!ServiceBuilder

    Sets the number of threads the driver should use to manage HTTP requests. + By default, the driver will use 4 threads.

    Parameters
    n: number
    The number of threads to use.
    Returns
    A self reference.
    code »setStdio ( config )!ServiceBuilder

    Defines the stdio configuration for the driver service. See + child_process.spawn for more information.

    Parameters
    config: (string|!Array)
    The + configuration to use.
    Returns
    A self reference.
    code »setUrlBasePath ( path )!ServiceBuilder

    Sets the base path for WebDriver REST commands (e.g. "/wd/hub"). + By default, the driver will accept commands relative to "/".

    Parameters
    path: string
    The base path to use.
    Returns
    A self reference.
    code »usingPort ( port )!ServiceBuilder

    Sets the port to start the ChromeDriver on.

    Parameters
    port: number
    The port to use, or 0 for any free port.
    Returns
    A self reference.
    Throws
    Error
    If the port is invalid.
    code »withEnvironment ( env )!ServiceBuilder

    Defines the environment to start the server under. This settings will be + inherited by every browser session started by the server.

    Parameters
    env: !Object.<string, string>
    The environment to use.
    Returns
    A self reference.

    Instance Properties

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_error.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_error.html new file mode 100644 index 0000000..dc4ba90 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_error.html @@ -0,0 +1,4 @@ +selenium-webdriver/error

    Module selenium-webdriver/error

    code »

    Classes

    Error
    Error extension that includes error status codes from the WebDriver wire + protocol: + http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes

    Enumerations

    ErrorCode
    Error codes from the WebDriver wire protocol: + http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_executors.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_executors.html new file mode 100644 index 0000000..4cd5307 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_executors.html @@ -0,0 +1,3 @@ +selenium-webdriver/executors

    Module selenium-webdriver/executors

    code »

    Various utilities for working with + webdriver.CommandExecutor implementations.

    Show:

    Functions

    Creates a command executor that uses WebDriver's JSON wire protocol.

    Parameters
    url: (string|!webdriver.promise.Promise.<string>)
    The server's URL, + or a promise that will resolve to that URL.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_http.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_http.html new file mode 100644 index 0000000..a5b2f98 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_http.html @@ -0,0 +1,4 @@ +selenium-webdriver/http

    Module selenium-webdriver/http

    code »

    Defines a the webdriver.http.Client for use with + NodeJS.

    Classes

    Executor
    A command executor that communicates with a server using the WebDriver + command protocol.
    HttpClient
    A webdriver.http.Client implementation using Node's built-in http + module.
    Request
    Describes a partial HTTP request.
    Response
    Represents a HTTP response.
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_http_class_HttpClient.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_http_class_HttpClient.html new file mode 100644 index 0000000..d61157e --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_http_class_HttpClient.html @@ -0,0 +1,2 @@ +HttpClient

    Class HttpClient

    code »
    All implemented interfaces:
    webdriver.http.Client

    A webdriver.http.Client implementation using Node's built-in http + module.

    Constructor

    HttpClient ( serverUrl )
    Parameters
    serverUrl: string
    URL for the WebDriver server to send commands to.
    Show:

    Instance Methods

    code »send ( httpRequest, callback )
    Parameters
    httpRequest
    callback

    Instance Properties

    Base options for each request.

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_http_util.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_http_util.html new file mode 100644 index 0000000..e85d100 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_http_util.html @@ -0,0 +1,5 @@ +selenium-webdriver/http/util

    Module selenium-webdriver/http/util

    code »

    Various HTTP utilities.

    Show:

    Functions

    Queries a WebDriver server for its current status.

    Parameters
    url: string
    Base URL of the server to query.
    Returns
    A promise that resolves with + a hash of the server status.

    Waits for a WebDriver server to be healthy and accepting requests.

    Parameters
    url: string
    Base URL of the server to query.
    timeout: number
    How long to wait for the server.
    Returns
    A promise that will resolve when the + server is ready.

    Polls a URL with GET requests until it returns a 2xx response or the + timeout expires.

    Parameters
    url: string
    The URL to poll.
    timeout: number
    How long to wait, in milliseconds.
    Returns
    A promise that will resolve when the + URL responds with 2xx.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_io.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_io.html new file mode 100644 index 0000000..aabdf7f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_io.html @@ -0,0 +1,4 @@ +selenium-webdriver/io

    Module selenium-webdriver/io

    code »
    Show:

    Functions

    code »findInPath ( file, opt_checkCwd )?string

    Searches the PATH environment variable for the given file.

    Parameters
    file: string
    The file to locate on the PATH.
    opt_checkCwd: boolean=
    Whether to always start with the search with + the current working directory, regardless of whether it is explicitly + listed on the PATH.
    Returns
    Path to the located file, or null if it could + not be found.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_net.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_net.html new file mode 100644 index 0000000..5915f59 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_net.html @@ -0,0 +1 @@ +selenium-webdriver/net

    Module selenium-webdriver/net

    code »
    Show:

    Functions

    code »getAddress ( opt_family )string

    Retrieves the external IP address for this host.

    Parameters
    opt_family: string=
    The IP family to retrieve. Defaults to "IPv4".
    Returns
    The IP address or undefined if not available.

    Retrieves a loopback address for this machine.

    Parameters
    opt_family: string=
    The IP family to retrieve. Defaults to "IPv4".
    Returns
    The IP address or undefined if not available.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_net_portprober.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_net_portprober.html new file mode 100644 index 0000000..0ae96a6 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_net_portprober.html @@ -0,0 +1,6 @@ +selenium-webdriver/net/portprober

    Module selenium-webdriver/net/portprober

    code »
    Show:

    Functions

    Parameters
    opt_host: string=
    The bound host to test the port against. + Defaults to INADDR_ANY.
    Returns
    A promise that will resolve + to a free port. If a port cannot be found, the promise will be + rejected.

    Tests if a port is free.

    Parameters
    port: number
    The port to test.
    opt_host: string=
    The bound host to test the port against. + Defaults to INADDR_ANY.
    Returns
    A promise that will resolve + with whether the port is free.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_phantomjs.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_phantomjs.html new file mode 100644 index 0000000..a4fd791 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_phantomjs.html @@ -0,0 +1 @@ +selenium-webdriver/phantomjs

    Module selenium-webdriver/phantomjs

    code »
    Show:

    Functions

    code »createDriver ( opt_capabilities )!webdriver.WebDriver

    Creates a new PhantomJS WebDriver client.

    Parameters
    opt_capabilities: webdriver.Capabilities=
    The desired capabilities.
    Returns
    A new WebDriver instance.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_proxy.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_proxy.html new file mode 100644 index 0000000..67b9e60 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_proxy.html @@ -0,0 +1,24 @@ +selenium-webdriver/proxy

    Module selenium-webdriver/proxy

    code »

    Defines functions for configuring a webdriver proxy: +

    
    + var webdriver = require('selenium-webdriver'),
    +     proxy = require('selenium-webdriver/proxy');
    +
    + var driver = new webdriver.Builder()
    +     .withCapabilities(webdriver.Capabilities.chrome())
    +     .setProxy(proxy.manual({http: 'host:1234'}))
    +     .build();
    + 
    Show:

    Type Definitions

    code »ProxyConfig : ({proxyType: string}|{proxyType: string, proxyAutoconfigUrl: string}|{proxyType: string, ftpProxy: string, httpProxy: string, sslProxy: string, noProxy: string})
    Proxy configuration object, as defined by the WebDriver wire protocol.

    Functions

    code »direct ( )!ProxyConfig

    Configures WebDriver to bypass all browser proxies.

    Returns
    A new proxy configuration object.
    code »manual ( options )!ProxyConfig

    Manually configures the browser proxy. The following options are + supported: +

      +
    • ftp: Proxy host to use for FTP requests +
    • http: Proxy host to use for HTTP requests +
    • https: Proxy host to use for HTTPS requests +
    • bypass: A list of hosts requests should directly connect to, + bypassing any other proxies for that request. May be specified as a + comma separated string, or a list of strings. +
    + + Behavior is undefined for FTP, HTTP, and HTTPS requests if the + corresponding key is omitted from the configuration options.
    Parameters
    options: {ftp: (string|undefined), http: (string|undefined), https: (string|undefined), bypass: (string|!Array.<string>|undefined)}
    Proxy + configuration options.
    Returns
    A new proxy configuration object.
    code »pac ( url )!ProxyConfig

    Configures WebDriver to configure the browser proxy using the PAC file at + the given URL.

    Parameters
    url: string
    URL for the PAC proxy to use.
    Returns
    A new proxy configuration object.
    code »system ( )!ProxyConfig

    Configures WebDriver to use the current system's proxy.

    Returns
    A new proxy configuration object.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_remote.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_remote.html new file mode 100644 index 0000000..1abf5aa --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_remote.html @@ -0,0 +1,19 @@ +selenium-webdriver/remote

    Module selenium-webdriver/remote

    code »

    Classes

    DriverService
    Manages the life and death of a native executable WebDriver server.
    SeleniumServer
    Manages the life and death of the Selenium standalone server.
    Show:

    Type Definitions

    Configuration options for a DriverService instance. +
      +
    • +
    • loopback - Whether the service should only be accessed on this + host's loopback address. +
    • port - The port to start the server on (must be > 0). If the + port is provided as a promise, the service will wait for the promise to + resolve before starting. +
    • args - The arguments to pass to the service. If a promise is + provided, the service will wait for it to resolve before starting. +
    • path - The base path on the server for the WebDriver wire + protocol (e.g. '/wd/hub'). Defaults to '/'. +
    • env - The environment variables that should be visible to the + server process. Defaults to inheriting the current process's + environment. +
    • stdio - IO configuration for the spawned server process. For + more information, refer to the documentation of + child_process.spawn. +
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_remote_class_DriverService.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_remote_class_DriverService.html new file mode 100644 index 0000000..44a90b5 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_remote_class_DriverService.html @@ -0,0 +1,19 @@ +DriverService

    Class DriverService

    code »

    Manages the life and death of a native executable WebDriver server. + +

    It is expected that the driver server implements the + WebDriver + Wire Protocol. Furthermore, the managed server should support multiple + concurrent sessions, so that this class may be reused for multiple clients.

    Constructor

    DriverService ( executable, options )
    Parameters
    executable: string
    Path to the executable to run.
    options: !ServiceOptions
    Configuration options for the service.
    Show:

    Instance Methods

    Returns
    A promise that resolves to + the server's address.
    Throws
    Error
    If the server has not been started.
    Returns
    Whether the underlying service process is running.

    Stops the service if it is not currently running. This function will kill + the server immediately. To synchronize with the active control flow, use + #stop().

    Returns
    A promise that will be resolved when + the server has been stopped.

    Starts the server if it is not already running.

    Parameters
    opt_timeoutMs: number=
    How long to wait, in milliseconds, for the + server to start accepting requests. Defaults to 30 seconds.
    Returns
    A promise that will resolve + to the server's base URL when it has started accepting requests. If the + timeout expires before the server has started, the promise will be + rejected.

    Schedules a task in the current control flow to stop the server if it is + currently running.

    Returns
    A promise that will be resolved when + the server has been stopped.

    Instance Properties

    Promise that resolves to the server's address or null if the server has not + been started.

    code »process_ : child_process.ChildProcess

    Promise that tracks the status of shutting down the server, or null if the + server is not currently shutting down.

    Static Properties

    The default amount of time, in milliseconds, to wait for the server to + start.

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_remote_class_SeleniumServer.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_remote_class_SeleniumServer.html new file mode 100644 index 0000000..0b5bcce --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_remote_class_SeleniumServer.html @@ -0,0 +1,31 @@ +SeleniumServer

    Class SeleniumServer

    code »
    DriverService
    +  └ SeleniumServer

    Manages the life and death of the Selenium standalone server. The server + may be obtained from http://selenium-release.storage.googleapis.com/index.html.

    Constructor

    SeleniumServer ( jar, options )
    Parameters
    jar: string
    Path to the Selenium server jar.
    options: !SeleniumServer.Options
    Configuration options for the + server.
    Throws
    Error
    If an invalid port is specified.
    Show:

    Type Definitions

    Options for the Selenium server: +
      +
    • port - The port to start the server on (must be > 0). If the + port is provided as a promise, the service will wait for the promise to + resolve before starting. +
    • args - The arguments to pass to the service. If a promise is + provided, the service will wait for it to resolve before starting. +
    • jvmArgs - The arguments to pass to the JVM. If a promise is + provided, the service will wait for it to resolve before starting. +
    • env - The environment variables that should be visible to the + server process. Defaults to inheriting the current process's + environment. +
    • stdio - IO configuration for the spawned server process. For + more information, refer to the documentation of + child_process.spawn. +

    Instance Methods

    Returns
    A promise that resolves to + the server's address.
    Throws
    Error
    If the server has not been started.
    Returns
    Whether the underlying service process is running.

    Stops the service if it is not currently running. This function will kill + the server immediately. To synchronize with the active control flow, use + #stop().

    Returns
    A promise that will be resolved when + the server has been stopped.

    Starts the server if it is not already running.

    Parameters
    opt_timeoutMs: number=
    How long to wait, in milliseconds, for the + server to start accepting requests. Defaults to 30 seconds.
    Returns
    A promise that will resolve + to the server's base URL when it has started accepting requests. If the + timeout expires before the server has started, the promise will be + rejected.

    Schedules a task in the current control flow to stop the server if it is + currently running.

    Returns
    A promise that will be resolved when + the server has been stopped.

    Instance Properties

    Promise that resolves to the server's address or null if the server has not + been started.

    code »process_ : child_process.ChildProcess

    Promise that tracks the status of shutting down the server, or null if the + server is not currently shutting down.

    Static Properties

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_testing.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_testing.html new file mode 100644 index 0000000..6d72a8e --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_testing.html @@ -0,0 +1,73 @@ +selenium-webdriver/testing

    Module selenium-webdriver/testing

    code »

    Provides wrappers around the following global functions from + Mocha's BDD interface: +

      +
    • after +
    • afterEach +
    • before +
    • beforeEach +
    • it +
    • it.only +
    • it.skip +
    • xit +
    + +

    The provided wrappers leverage the webdriver.promise.ControlFlow + to simplify writing asynchronous tests: +

    
    + var webdriver = require('selenium-webdriver'),
    +     portprober = require('selenium-webdriver/net/portprober'),
    +     remote = require('selenium-webdriver/remote'),
    +     test = require('selenium-webdriver/testing');
    +
    + test.describe('Google Search', function() {
    +   var driver, server;
    +
    +   test.before(function() {
    +     server = new remote.SeleniumServer(
    +         'path/to/selenium-server-standalone.jar',
    +         {port: portprober.findFreePort()});
    +     server.start();
    +
    +     driver = new webdriver.Builder().
    +         withCapabilities({'browserName': 'firefox'}).
    +         usingServer(server.address()).
    +         build();
    +   });
    +
    +   test.after(function() {
    +     driver.quit();
    +     server.stop();
    +   });
    +
    +   test.it('should append query to title', function() {
    +     driver.get('http://www.google.com');
    +     driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
    +     driver.findElement(webdriver.By.name('btnG')).click();
    +     driver.wait(function() {
    +       return driver.getTitle().then(function(title) {
    +         return 'webdriver - Google Search' === title;
    +       });
    +     }, 1000, 'Waiting for title to update');
    +   });
    + });
    + 
    + +

    You may conditionally suppress a test function using the exported + "ignore" function. If the provided predicate returns true, the attached + test case will be skipped: +

    
    +   test.ignore(maybe()).it('is flaky', function() {
    +     if (Math.random() < 0.5) throw Error();
    +   });
    +
    +   function maybe() { return Math.random() < 0.5; }
    + 
    Show:

    Functions

    Register a function to call after the current suite finishes.

    Parameters
    fn: function()
    .

    Register a function to call after each test in a suite.

    Parameters
    fn: function()
    .

    Register a function to call before the current suite starts.

    Parameters
    fn: function()
    .

    Register a function to call before each test in a suite.

    Parameters
    fn: function()
    .
    code »describe ( name, fn )

    Registers a new test suite.

    Parameters
    name: string
    The suite name.
    fn: function()=
    The suite function, or undefined to define + a pending test suite.
    code »ignore ( predicateFn )!Object

    Ignores the test chained to this function if the provided predicate returns + true.

    Parameters
    predicateFn: function(): boolean
    A predicate to call to determine + if the test should be suppressed. This function MUST be synchronous.
    Returns
    An object with wrapped versions of #it() and + #describe() that ignore tests as indicated by the predicate.
    code »iit ( name, fn )

    An alias for #it() that flags the test as the only one that should + be run within the current suite.

    Parameters
    name: string
    The test name.
    fn: function()=
    The test function, or undefined to define + a pending test case.
    code »it ( name, fn )

    Add a test to the current suite.

    Parameters
    name: string
    The test name.
    fn: function()=
    The test function, or undefined to define + a pending test case.
    code »xdescribe ( name, fn )

    Defines a suppressed test suite.

    Parameters
    name: string
    The suite name.
    fn: function()=
    The suite function, or undefined to define + a pending test suite.
    code »xit ( name, fn )

    Adds a test to the current suite while suppressing it so it is not run.

    Parameters
    name: string
    The test name.
    fn: function()=
    The test function, or undefined to define + a pending test case.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/module_selenium-webdriver_testing_assert.html b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_testing_assert.html new file mode 100644 index 0000000..d214b1f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/module_selenium-webdriver_testing_assert.html @@ -0,0 +1,19 @@ +selenium-webdriver/testing/assert

    Module selenium-webdriver/testing/assert

    code »

    Defines a library that simplifies writing assertions against + promised values. + +

    +
    + NOTE: This module is considered experimental and is subject to + change, or removal, at any time! +
    +
    + + Sample usage: +
    
    + var driver = new webdriver.Builder().build();
    + driver.get('http://www.google.com');
    +
    + assert(driver.getTitle()).equalTo('Google');
    + 

    Main

    assert ( value )!webdriver.testing.Assertion
    Parameters
    value: *
    The value to perform an assertion on.
    Returns
    The new assertion.
    Show:

    Functions

    code »register ( name, matcherTemplate )

    Registers a new assertion to expose from the + webdriver.testing.Assertion prototype.

    Parameters
    name: string
    The assertion name.
    matcherTemplate: (function(new: goog.labs.testing.Matcher, *)|{matches: function(*): boolean, describe: function(): string})
    Either the + matcher constructor to use, or an object literal defining a matcher.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_bot.html b/node_modules/selenium-webdriver/docs/namespace_bot.html new file mode 100644 index 0000000..b3d27b1 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_bot.html @@ -0,0 +1,4 @@ +bot

    Namespace bot

    code »

    Classes

    bot.Error
    Error extension that includes error status codes from the WebDriver wire + protocol: + http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes

    Enumerations

    bot.ErrorCode
    Error codes from the WebDriver wire protocol: + http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_bot_json.html b/node_modules/selenium-webdriver/docs/namespace_bot_json.html new file mode 100644 index 0000000..fa0a57e --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_bot_json.html @@ -0,0 +1,4 @@ +bot.json

    Namespace bot.json

    code »
    Show:

    Global Functions

    code »bot.json.parse ( jsonStr )*

    Parses a JSON string and returns the result.

    Parameters
    jsonStr: string
    The string to parse.
    Returns
    The JSON object.
    Throws
    Error
    If the input string is an invalid JSON string.
    code »bot.json.stringify ( jsonObj, opt_replacer )string

    Converts a JSON object to its string representation.

    Parameters
    jsonObj: *
    The input object.
    opt_replacer: ?(function(string, *): *)=
    A replacer function called + for each (key, value) pair that determines how the value should be + serialized. By default, this just returns the value and allows default + serialization to kick in.
    Returns
    A JSON string representation of the input object.

    Global Properties

    Whether the current browser supports the native JSON interface.

    Compiler Constants

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_bot_response.html b/node_modules/selenium-webdriver/docs/namespace_bot_response.html new file mode 100644 index 0000000..3525f53 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_bot_response.html @@ -0,0 +1,5 @@ +bot.response

    Namespace bot.response

    code »
    Show:

    Type Definitions

    code »bot.response.ResponseObject : {status: bot.ErrorCode, value: (*|{message: string})}
    Type definition for a response object, as defined by the JSON wire protocol.

    Global Functions

    Checks that a response object does not specify an error as defined by the + WebDriver wire protocol. If the response object defines an error, it will + be thrown. Otherwise, the response will be returned as is.

    Parameters
    responseObj: !bot.response.ResponseObject
    The response object to + check.
    Returns
    The checked response object.
    Throws
    bot.Error
    If the response describes an error.

    Converts an error value into its JSON representation as defined by the + WebDriver wire protocol.

    Parameters
    error: (bot.Error|Error|*)
    The error value to convert.
    Returns
    The new response object.

    Creates a new success response object with the provided value.

    Parameters
    value: *
    The response value.
    Returns
    The new response object.
    Parameters
    value: *
    The value to test.
    Returns
    Whether the given value is a response object.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_bot_userAgent.html b/node_modules/selenium-webdriver/docs/namespace_bot_userAgent.html new file mode 100644 index 0000000..cde2533 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_bot_userAgent.html @@ -0,0 +1,21 @@ +bot.userAgent

    Namespace bot.userAgent

    code »
    Show:

    Global Functions

    Whether the rendering engine version of the current browser is equal to or + greater than the given version. This implementation differs from + goog.userAgent.isVersion in the following ways: +

      +
    1. in a Firefox extension, tests the engine version through the XUL version + comparator service, because no window.navigator object is available +
    2. in IE, compares the given version to the current documentMode +
    Parameters
    version: (string|number)
    The version number to check.
    Returns
    Whether the browser engine version is the same or higher + than the given version.

    Whether the product version of the current browser is equal to or greater + than the given version. This implementation differs from + goog.userAgent.product.isVersion in the following ways: +

      +
    1. in a Firefox extension, tests the product version through the XUL version + comparator service, because no window.navigator object is available +
    2. on Android, always compares to the version to the OS version +
    Parameters
    version: (string|number)
    The version number to check.
    Returns
    Whether the browser product version is the same or higher + than the given version.

    Global Properties

    Whether the current browser is Android pre-gingerbread.

    Whether the current browser is Android pre-icecreamsandwich

    Android Operating System Version.

    Whether we are in a Firefox extension.

    When we are in a Firefox extension, this is a function that accepts a version + and returns whether the version of Gecko we are on is the same or higher + than the given version. When we are not in a Firefox extension, this is null.

    When we are in a Firefox extension, this is a function that accepts a version + and returns whether the version of Firefox we are on is the same or higher + than the given version. When we are not in a Firefox extension, this is null.

    Whether the current document is IE in IE10 (or newer) standards mode.

    Whether the current document is IE in IE9 (or newer) standards mode.

    Whether the current document is IE in a documentMode older than 10.

    Whether the current document is IE in a documentMode older than 8.

    Whether the current document is IE in a documentMode older than 9.

    Whether we are on IOS.

    Whether we are on a mobile browser.

    Whether the current browser is Safari 6.

    Whether the current browser is Windows Phone.

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog.html b/node_modules/selenium-webdriver/docs/namespace_goog.html new file mode 100644 index 0000000..10818ad --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog.html @@ -0,0 +1,242 @@ +goog

    Namespace goog

    code »

    Base namespace for the Closure library. Checks to see goog is already + defined in the current scope before assigning to prevent clobbering if + base.js is loaded more than once.

    Classes

    goog.Uri
    This class contains setters and getters for the parts of the URI.
    Show:

    Global Functions

    When defining a class Foo with an abstract method bar(), you can do: + Foo.prototype.bar = goog.abstractMethod + + Now if a subclass of Foo fails to override bar(), an error will be thrown + when bar() is invoked. + + Note: This does not take the name of the function to override as an argument + because that would make it more difficult to obfuscate our JavaScript code.

    Throws
    Error
    when invoked to indicate the method should be overridden.
    code »goog.addDependency ( relPath, provides, requires )

    Adds a dependency from a file to the files it requires.

    Parameters
    relPath: string
    The path to the js file.
    provides: Array
    An array of strings with the names of the objects + this file provides.
    requires: Array
    An array of strings with the names of the objects + this file requires.

    Adds a getInstance static method that always returns the same + instance object.

    Parameters
    ctor: !Function
    The constructor for the class to add the static + method to.
    code »goog.base ( me, opt_methodName, var_args )*

    Call up to the superclass. + + If this is called from a constructor, then this calls the superclass + constructor with arguments 1-N. + + If this is called from a prototype method, then you must pass the name of the + method as the second argument to this function. If you do not, you will get a + runtime error. This calls the superclass' method with arguments 2-N. + + This function only works if you use goog.inherits to express inheritance + relationships between your classes. + + This function is a compiler primitive. At compile-time, the compiler will do + macro expansion to remove a lot of the extra overhead that this function + introduces. The compiler will also enforce a lot of the assumptions that this + function makes, and treat it as a compiler error if you break them.

    Parameters
    me: !Object
    Should always be "this".
    opt_methodName: *=
    The method name if calling a super method.
    var_args: ...*
    The rest of the arguments.
    Returns
    The return value of the superclass method.
    code »<T> goog.bind ( fn, selfObj, var_args )!Function

    Partially applies this function to a particular 'this object' and zero or + more arguments. The result is a new function with some arguments of the first + function pre-filled and the value of this 'pre-specified'. + + Remaining arguments specified at call-time are appended to the pre-specified + ones. + + Also see: #partial. + + Usage: +

    var barMethBound = bind(myFunction, myObj, 'arg1', 'arg2');
    + barMethBound('arg3', 'arg4');
    Parameters
    fn: ?function(this: T, ...)
    A function to partially apply.
    selfObj: T
    Specifies the object which this should point to when the + function is run.
    var_args: ...*
    Additional arguments that are partially applied to the + function.
    Returns
    A partially-applied form of the function bind() was + invoked as a method of.
    code »goog.bindJs_ ( fn, selfObj, var_args )!Function

    A pure-JS implementation of goog.bind.

    Parameters
    fn: Function
    A function to partially apply.
    selfObj: (Object|undefined)
    Specifies the object which this should + point to when the function is run.
    var_args: ...*
    Additional arguments that are partially applied to the + function.
    Returns
    A partially-applied form of the function bind() was + invoked as a method of.
    code »goog.bindNative_ ( fn, selfObj, var_args )!Function

    A native implementation of goog.bind.

    Parameters
    fn: Function
    A function to partially apply.
    selfObj: (Object|undefined)
    Specifies the object which this should + point to when the function is run.
    var_args: ...*
    Additional arguments that are partially applied to the + function.
    Returns
    A partially-applied form of the function bind() was + invoked as a method of.
    Deprecated: goog.cloneObject is unsafe. Prefer the goog.object methods.

    Clones a value. The input may be an Object, Array, or basic type. Objects and + arrays will be cloned recursively. + + WARNINGS: + goog.cloneObject does not detect reference loops. Objects that + refer to themselves will cause infinite recursion. + + goog.cloneObject is unaware of unique identifiers, and copies + UIDs created by getUid into cloned results.

    Parameters
    obj: *
    The value to clone.
    Returns
    A clone of the input value.
    code »goog.define ( name, defaultValue )

    Defines a named value. In uncompiled mode, the value is retreived from + CLOSURE_DEFINES or CLOSURE_UNCOMPILED_DEFINES if the object is defined and + has the property specified, and otherwise used the defined defaultValue. + When compiled, the default can be overridden using compiler command-line + options.

    Parameters
    name: string
    The distinguished name to provide.
    defaultValue
    code »goog.exportPath_ ( name, opt_object, opt_objectToExportTo )

    Builds an object structure for the provided namespace path, ensuring that + names that already exist are not overwritten. For example: + "a.b.c" -> a = {};a.b={};a.b.c={}; + Used by goog.provide and goog.exportSymbol.

    Parameters
    name: string
    name of the object that this file defines.
    opt_object: *=
    the object to expose at the end of the path.
    opt_objectToExportTo: Object=
    The object to add the path to; default + is |goog.global|.
    code »goog.exportProperty ( object, publicName, symbol )

    Exports a property unobfuscated into the object's namespace. + ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction); + ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod);

    Parameters
    object: Object
    Object whose static property is being exported.
    publicName: string
    Unobfuscated name to export.
    symbol: *
    Object the name should point to.
    code »goog.exportSymbol ( publicPath, object, opt_objectToExportTo )

    Exposes an unobfuscated global namespace path for the given object. + Note that fields of the exported object *will* be obfuscated, unless they are + exported in turn via this function or goog.exportProperty. + + Also handy for making public items that are defined in anonymous closures. + + ex. goog.exportSymbol('public.path.Foo', Foo); + + ex. goog.exportSymbol('public.path.Foo.staticFunction', Foo.staticFunction); + public.path.Foo.staticFunction(); + + ex. goog.exportSymbol('public.path.Foo.prototype.myMethod', + Foo.prototype.myMethod); + new public.path.Foo().myMethod();

    Parameters
    publicPath: string
    Unobfuscated name to export.
    object: *
    Object the name should point to.
    opt_objectToExportTo: Object=
    The object to add the path to; default + is goog.global.

    Tries to detect the base path of base.js script that bootstraps Closure.

    Forward declares a symbol. This is an indication to the compiler that the + symbol may be used in the source yet is not required and may not be provided + in compilation. + + The most common usage of forward declaration is code that takes a type as a + function parameter but does not need to require it. By forward declaring + instead of requiring, no hard dependency is made, and (if not required + elsewhere) the namespace may never be required and thus, not be pulled + into the JavaScript binary. If it is required elsewhere, it will be type + checked as normal.

    Parameters
    name: string
    The namespace to forward declare in the form of + "goog.package.part".
    code »goog.getCssName ( className, opt_modifier )string

    Handles strings that are intended to be used as CSS class names. + + This function works in tandem with @see goog.setCssNameMapping. + + Without any mapping set, the arguments are simple joined with a hyphen and + passed through unaltered. + + When there is a mapping, there are two possible styles in which these + mappings are used. In the BY_PART style, each part (i.e. in between hyphens) + of the passed in css name is rewritten according to the map. In the BY_WHOLE + style, the full css name is looked up in the map directly. If a rewrite is + not specified by the map, the compiler will output a warning. + + When the mapping is passed to the compiler, it will replace calls to + goog.getCssName with the strings from the mapping, e.g. + var x = goog.getCssName('foo'); + var y = goog.getCssName(this.baseClass, 'active'); + becomes: + var x= 'foo'; + var y = this.baseClass + '-active'; + + If one argument is passed it will be processed, if two are passed only the + modifier will be processed, as it is assumed the first argument was generated + as a result of calling goog.getCssName.

    Parameters
    className: string
    The class name.
    opt_modifier: string=
    A modifier to be appended to the class name.
    Returns
    The class name or the concatenation of the class name and + the modifier.
    Deprecated: Use goog.getUid instead.

    Adds a hash code field to an object. The hash code is unique for the + given object.

    Parameters
    obj: Object
    The object to get the hash code for.
    Returns
    The hash code for the object.
    code »goog.getMsg ( str, opt_values )string

    Gets a localized message. + + This function is a compiler primitive. If you give the compiler a localized + message bundle, it will replace the string at compile-time with a localized + version, and expand goog.getMsg call to a concatenated string. + + Messages must be initialized in the form: + + var MSG_NAME = goog.getMsg('Hello {$placeholder}', {'placeholder': 'world'}); +

    Parameters
    str: string
    Translatable string, places holders in the form {$foo}.
    opt_values: Object=
    Map of place holder name to value.
    Returns
    message with placeholders filled.

    Gets a localized message. If the message does not have a translation, gives a + fallback message. + + This is useful when introducing a new message that has not yet been + translated into all languages. + + This function is a compiler primitive. Must be used in the form: + var x = goog.getMsgWithFallback(MSG_A, MSG_B); + where MSG_A and MSG_B were initialized with goog.getMsg.

    Parameters
    a: string
    The preferred message.
    b: string
    The fallback message.
    Returns
    The best translated message.
    code »goog.getObjectByName ( name, opt_obj )

    Returns an object based on its fully qualified external name. The object + is not found if null or undefined. If you are using a compilation pass that + renames property names beware that using this function will not find renamed + properties.

    Parameters
    name: string
    The fully qualified name.
    opt_obj: Object=
    The object within which to look; default is + |goog.global|.
    Returns
    The value (object or primitive) or, if not found, null.

    Looks at the dependency rules and tries to determine the script file that + fulfills a particular rule.

    Parameters
    rule: string
    In the form goog.namespace.Class or project.script.
    Returns
    Url corresponding to the rule, or null.

    Gets a unique ID for an object. This mutates the object so that further calls + with the same object as a parameter returns the same value. The unique ID is + guaranteed to be unique across the current session amongst objects that are + passed into getUid. There is no guarantee that the ID is unique or + consistent across sessions. It is unsafe to generate unique ID for function + prototypes.

    Parameters
    obj: Object
    The object to get the unique ID for.
    Returns
    The unique ID for the object.

    Evals JavaScript in the global scope. In IE this uses execScript, other + browsers use goog.global.eval. If goog.global.eval does not evaluate in the + global scope (for example, in Safari), appends a script tag instead. + Throws an exception if neither execScript or eval is defined.

    Parameters
    script: string
    JavaScript string.
    code »goog.globalize ( obj, opt_global )
    Deprecated: Properties may be explicitly exported to the global scope, but + this should no longer be done in bulk.

    Globalizes a whole namespace, such as goog or goog.lang.

    Parameters
    obj: Object
    The namespace to globalize.
    opt_global: Object=
    The object to add the properties to.

    Whether the given object is alreay assigned a unique ID. + + This does not modify the object.

    Parameters
    obj: Object
    The object to check.
    Returns
    Whether there an assigned unique id for the object.
    code »goog.identityFunction ( opt_returnValue, var_args )
    Deprecated: Use goog.functions.identity instead.

    The identity function. Returns its first argument.

    Parameters
    opt_returnValue: *=
    The single value that will be returned.
    var_args: ...*
    Optional trailing arguments. These are ignored.
    Returns
    The first argument. We can't know the type -- just pass it along + without type.

    Imports a script if, and only if, that script hasn't already been imported. + (Must be called at execution time)

    Parameters
    src: string
    Script source.

    Tries to detect whether is in the context of an HTML document.

    Returns
    True if it looks like HTML document.
    code »goog.inherits ( childCtor, parentCtor )

    Inherit the prototype methods from one constructor into another. + + Usage: +

    + function ParentClass(a, b) { }
    + ParentClass.prototype.foo = function(a) { }
    +
    + function ChildClass(a, b, c) {
    +   goog.base(this, a, b);
    + }
    + goog.inherits(ChildClass, ParentClass);
    +
    + var child = new ChildClass('a', 'b', 'see');
    + child.foo(); // This works.
    + 
    + + In addition, a superclass' implementation of a method can be invoked as + follows: + +
    + ChildClass.prototype.foo = function(a) {
    +   ChildClass.superClass_.foo.call(this, a);
    +   // Other code here.
    + };
    + 
    Parameters
    childCtor: Function
    Child class.
    parentCtor: Function
    Parent class.

    Returns true if the specified value is an array.

    Parameters
    val: ?
    Variable to test.
    Returns
    Whether variable is an array.

    Returns true if the object looks like an array. To qualify as array like + the value needs to be either a NodeList or an object with a Number length + property.

    Parameters
    val: ?
    Variable to test.
    Returns
    Whether variable is an array.

    Returns true if the specified value is a boolean.

    Parameters
    val: ?
    Variable to test.
    Returns
    Whether variable is boolean.

    Returns true if the object looks like a Date. To qualify as Date-like the + value needs to be an object and have a getFullYear() function.

    Parameters
    val: ?
    Variable to test.
    Returns
    Whether variable is a like a Date.

    Returns true if the specified value is not undefined. + WARNING: Do not use this to test if an object has a property. Use the in + operator instead.

    Parameters
    val: ?
    Variable to test.
    Returns
    Whether variable is defined.

    Returns true if the specified value is defined and not null.

    Parameters
    val: ?
    Variable to test.
    Returns
    Whether variable is defined and not null.

    Returns true if the specified value is a function.

    Parameters
    val: ?
    Variable to test.
    Returns
    Whether variable is a function.

    Returns true if the specified value is null.

    Parameters
    val: ?
    Variable to test.
    Returns
    Whether variable is null.

    Returns true if the specified value is a number.

    Parameters
    val: ?
    Variable to test.
    Returns
    Whether variable is a number.

    Returns true if the specified value is an object. This includes arrays and + functions.

    Parameters
    val: ?
    Variable to test.
    Returns
    Whether variable is an object.

    Check if the given name has been goog.provided. This will return false for + names that are available only as implicit namespaces.

    Parameters
    name: string
    name of the object to look for.
    Returns
    Whether the name has been provided.

    Returns true if the specified value is a string.

    Parameters
    val: ?
    Variable to test.
    Returns
    Whether variable is a string.
    code »goog.mixin ( target, source )

    Copies all the members of a source object to a target object. This method + does not work on all browsers for all objects that contain keys such as + toString or hasOwnProperty. Use goog.object.extend for this purpose.

    Parameters
    target: Object
    Target.
    source: Object
    Source.
    Returns
    An integer value representing the number of milliseconds + between midnight, January 1, 1970 and the current time.

    Null function used for default values of callbacks, etc.

    Returns
    Nothing.
    code »goog.partial ( fn, var_args )!Function

    Like bind(), except that a 'this object' is not required. Useful when the + target function is already bound. + + Usage: + var g = partial(f, arg1, arg2); + g(arg3, arg4);

    Parameters
    fn: Function
    A function to partially apply.
    var_args: ...*
    Additional arguments that are partially applied to fn.
    Returns
    A partially-applied form of the function bind() was + invoked as a method of.

    Creates object stubs for a namespace. The presence of one or more + goog.provide() calls indicate that the file defines the given + objects/namespaces. Provided objects must not be null or undefined. + Build tools also scan for provide/require statements + to discern dependencies, build dependency files (see deps.js), etc.

    Parameters
    name: string
    Namespace provided by this file in the form + "goog.package.part".
    Deprecated: Use goog.removeUid instead.

    Removes the hash code field from an object.

    Parameters
    obj: Object
    The object to remove the field from.

    Removes the unique ID from an object. This is useful if the object was + previously mutated using goog.getUid in which case the mutation is + undone.

    Parameters
    obj: Object
    The object to remove the unique ID field from.

    Implements a system for the dynamic resolution of dependencies that works in + parallel with the BUILD system. Note that all calls to goog.require will be + stripped by the JSCompiler when the --closure_pass option is used.

    Parameters
    name: string
    Namespace to include (as was given in goog.provide()) in + the form "goog.package.part".

    Allow for aliasing within scope functions. This function exists for + uncompiled code - in compiled code the calls will be inlined and the aliases + applied. In uncompiled code the function is simply run since the aliases as + written are valid JavaScript.

    Parameters
    fn: function()
    Function to call. This function can contain aliases + to namespaces (e.g. "var dom = goog.dom") or classes + (e.g. "var Timer = goog.Timer").
    code »goog.setCssNameMapping ( mapping, opt_style )

    Sets the map to check when returning a value from goog.getCssName(). Example: +

    + goog.setCssNameMapping({
    +   "goog": "a",
    +   "disabled": "b",
    + });
    +
    + var x = goog.getCssName('goog');
    + // The following evaluates to: "a a-b".
    + goog.getCssName('goog') + ' ' + goog.getCssName(x, 'disabled')
    + 
    + When declared as a map of string literals to string literals, the JSCompiler + will replace all calls to goog.getCssName() using the supplied map if the + --closure_pass flag is set.
    Parameters
    mapping: !Object
    A map of strings to strings where keys are possible + arguments to goog.getCssName() and values are the corresponding values + that should be returned.
    opt_style: string=
    The style of css name mapping. There are two valid + options: 'BY_PART', and 'BY_WHOLE'.
    code »goog.setTestOnly ( opt_message )

    Marks that the current file should only be used for testing, and never for + live code in production. + + In the case of unit tests, the message may optionally be an exact namespace + for the test (e.g. 'goog.stringTest'). The linter will then ignore the extra + provide (if not explicitly defined in the code).

    Parameters
    opt_message: string=
    Optional message to add to the error that's + raised when used in production code.

    This is a "fixed" version of the typeof operator. It differs from the typeof + operator in such a way that null returns 'null' and arrays return 'array'.

    Parameters
    value: *
    The value to get the type of.
    Returns
    The name of the type.

    The default implementation of the import function. Writes a script tag to + import the script.

    Parameters
    src: string
    The script source.
    Returns
    True if the script was imported, false otherwise.

    Resolves dependencies based on the dependencies added using addDependency + and calls importScript_ in the correct order.

    Global Properties

    True if goog.dependencies_ is available.

    Name for unique ID property. Initialized in a way to help avoid collisions + with other closure JavaScript on the same page.

    Path for included scripts.

    Optional obfuscation style for CSS class names. Should be set to either + 'BY_WHOLE' or 'BY_PART' if defined.

    Optional map of CSS class names to obfuscated names used with + goog.getCssName().

    This object is used to keep track of dependencies and other data that is + used for loading scripts.

    Indicates whether or not we can call 'eval' directly to eval code in the + global scope. Set to a Boolean by the first call to goog.globalEval (which + empirically tests whether eval works for globals). @see goog.globalEval

    code »goog.global : global this

    Reference to the global context. In most cases this will be 'window'.

    Namespaces implicitly defined by goog.provide. For example, + goog.provide('goog.events.Event') implicitly declares that 'goog' and + 'goog.events' must be namespaces.

    Object used to keep track of urls that have already been added. This record + allows the prevention of circular dependencies.

    All singleton classes that have been instantiated, for testing. Don't read + it directly, use the goog.testing.singleton module. The compiler + removes this variable if unused.

    Compiler Constants

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_array.html b/node_modules/selenium-webdriver/docs/namespace_goog_array.html new file mode 100644 index 0000000..1eb2185 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_array.html @@ -0,0 +1,337 @@ +goog.array

    Namespace goog.array

    code »
    Show:

    Type Definitions

    Global Functions

    code »<VALUE> goog.array.binaryInsert ( array, value, opt_compareFn )boolean

    Inserts a value into a sorted array. The array is not modified if the + value is already present.

    Parameters
    array: (Array.<VALUE>|goog.array.ArrayLike)
    The array to modify.
    value: VALUE
    The object to insert.
    opt_compareFn: function(VALUE, VALUE): number=
    Optional comparison + function by which the array is ordered. Should take 2 arguments to + compare, and return a negative number, zero, or a positive number + depending on whether the first argument is less than, equal to, or + greater than the second.
    Returns
    True if an element was inserted.
    code »<VALUE> goog.array.binaryRemove ( array, value, opt_compareFn )boolean

    Removes a value from a sorted array.

    Parameters
    array: (!Array.<VALUE>|!goog.array.ArrayLike)
    The array to modify.
    value: VALUE
    The object to remove.
    opt_compareFn: function(VALUE, VALUE): number=
    Optional comparison + function by which the array is ordered. Should take 2 arguments to + compare, and return a negative number, zero, or a positive number + depending on whether the first argument is less than, equal to, or + greater than the second.
    Returns
    True if an element was removed.
    code »<TARGET, VALUE> goog.array.binarySearch ( arr, target, opt_compareFn )number

    Searches the specified array for the specified target using the binary + search algorithm. If no opt_compareFn is specified, elements are compared + using goog.array.defaultCompare, which compares the elements + using the built in < and > operators. This will produce the expected + behavior for homogeneous arrays of String(s) and Number(s). The array + specified must be sorted in ascending order (as defined by the + comparison function). If the array is not sorted, results are undefined. + If the array contains multiple instances of the specified target value, any + of these instances may be found. + + Runtime: O(log n)

    Parameters
    arr: (Array.<VALUE>|goog.array.ArrayLike)
    The array to be searched.
    target: TARGET
    The sought value.
    opt_compareFn: function(TARGET, VALUE): number=
    Optional comparison + function by which the array is ordered. Should take 2 arguments to + compare, and return a negative number, zero, or a positive number + depending on whether the first argument is less than, equal to, or + greater than the second.
    Returns
    Lowest index of the target value if found, otherwise + (-(insertion point) - 1). The insertion point is where the value should + be inserted into arr to preserve the sorted property. Return value >= 0 + iff target is found.
    code »<THIS, VALUE, TARGET> goog.array.binarySearch_ ( arr, compareFn, isEvaluator, opt_target, opt_selfObj )number

    Implementation of a binary search algorithm which knows how to use both + comparison functions and evaluators. If an evaluator is provided, will call + the evaluator with the given optional data object, conforming to the + interface defined in binarySelect. Otherwise, if a comparison function is + provided, will call the comparison function against the given data object. + + This implementation purposefully does not use goog.bind or goog.partial for + performance reasons. + + Runtime: O(log n)

    Parameters
    arr: (Array.<VALUE>|goog.array.ArrayLike)
    The array to be searched.
    compareFn: (function(TARGET, VALUE): number|function(this: THIS, VALUE, number, ?): number)
    Either an + evaluator or a comparison function, as defined by binarySearch + and binarySelect above.
    isEvaluator: boolean
    Whether the function is an evaluator or a + comparison function.
    opt_target: TARGET=
    If the function is a comparison function, then + this is the target to binary search for.
    opt_selfObj: THIS=
    If the function is an evaluator, this is an + optional this object for the evaluator.
    Returns
    Lowest index of the target value if found, otherwise + (-(insertion point) - 1). The insertion point is where the value should + be inserted into arr to preserve the sorted property. Return value >= 0 + iff target is found.
    code »<THIS, VALUE> goog.array.binarySelect ( arr, evaluator, opt_obj )number

    Selects an index in the specified array using the binary search algorithm. + The evaluator receives an element and determines whether the desired index + is before, at, or after it. The evaluator must be consistent (formally, + goog.array.map(goog.array.map(arr, evaluator, opt_obj), goog.math.sign) + must be monotonically non-increasing). + + Runtime: O(log n)

    Parameters
    arr: (Array.<VALUE>|goog.array.ArrayLike)
    The array to be searched.
    evaluator: function(this: THIS, VALUE, number, ?): number
    Evaluator function that receives 3 arguments (the element, the index and + the array). Should return a negative number, zero, or a positive number + depending on whether the desired index is before, at, or after the + element passed to it.
    opt_obj: THIS=
    The object to be used as the value of 'this' + within evaluator.
    Returns
    Index of the leftmost element matched by the evaluator, if + such exists; otherwise (-(insertion point) - 1). The insertion point is + the index of the first element for which the evaluator returns negative, + or arr.length if no such element exists. The return value is non-negative + iff a match is found.
    code »<T, S> goog.array.bucket ( array, sorter, opt_obj )!Object

    Splits an array into disjoint buckets according to a splitting function.

    Parameters
    array: Array.<T>
    The array.
    sorter: function(this: S, T, number, Array.<T>): ?
    Function to call for + every element. This takes 3 arguments (the element, the index and the + array) and must return a valid object key (a string, number, etc), or + undefined, if that object should not be placed in a bucket.
    opt_obj: S=
    The object to be used as the value of 'this' within + sorter.
    Returns
    An object, with keys being all of the unique return values + of sorter, and values being arrays containing the items for + which the splitter returned that key.

    Clears the array.

    Parameters
    arr: goog.array.ArrayLike
    Array or array like object to clear.
    code »<T> goog.array.clone ( arr )!Array.<T>

    Does a shallow copy of an array.

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array-like object to + clone.
    Returns
    Clone of the input array.
    code »<VALUE> goog.array.compare3 ( arr1, arr2, opt_compareFn )number

    3-way array compare function.

    Parameters
    arr1: (!Array.<VALUE>|!goog.array.ArrayLike)
    The first array to + compare.
    arr2: (!Array.<VALUE>|!goog.array.ArrayLike)
    The second array to + compare.
    opt_compareFn: function(VALUE, VALUE): number=
    Optional comparison + function by which the array is to be ordered. Should take 2 arguments to + compare, and return a negative number, zero, or a positive number + depending on whether the first argument is less than, equal to, or + greater than the second.
    Returns
    Negative number, zero, or a positive number depending on + whether the first argument is less than, equal to, or greater than the + second.

    Returns a new array that is the result of joining the arguments. If arrays + are passed then their items are added, however, if non-arrays are passed they + will be added to the return array as is. + + Note that ArrayLike objects will be added as is, rather than having their + items added. + + goog.array.concat([1, 2], [3, 4]) -> [1, 2, 3, 4] + goog.array.concat(0, [1, 2]) -> [0, 1, 2] + goog.array.concat([1, 2], null) -> [1, 2, null] + + There is bug in all current versions of IE (6, 7 and 8) where arrays created + in an iframe become corrupted soon (not immediately) after the iframe is + destroyed. This is common if loading data via goog.net.IframeIo, for example. + This corruption only affects the concat method which will start throwing + Catastrophic Errors (#-2147418113). + + See http://endoflow.com/scratch/corrupted-arrays.html for a test case. + + Internally goog.array should use this, so that all methods will continue to + work on these broken array objects.

    Parameters
    var_args: ...*
    Items to concatenate. Arrays will have each item + added, while primitives and objects will be added as is.
    Returns
    The new resultant array.

    Whether the array contains the given object.

    Parameters
    arr: goog.array.ArrayLike
    The array to test for the presence of the + element.
    obj: *
    The object for which to test.
    Returns
    true if obj is present.
    code »<T, S> goog.array.count ( arr, f, opt_obj )number

    Counts the array elements that fulfill the predicate, i.e. for which the + callback function returns true. Skips holes in the array.

    Parameters
    arr: !(Array.<T>|goog.array.ArrayLike)
    Array or array like object + over which to iterate.
    f: function(this: S, T, number, ?): boolean
    The function to call for + every element. Takes 3 arguments (the element, the index and the array).
    opt_obj: S=
    The object to be used as the value of 'this' within f.
    Returns
    The number of the matching elements.

    Compares its two arguments for order, using the built in < and > + operators.

    Parameters
    a: VALUE
    The first object to be compared.
    b: VALUE
    The second object to be compared.
    Returns
    A negative number, zero, or a positive number as the first + argument is less than, equal to, or greater than the second.

    Compares its two arguments for equality, using the built in === operator.

    Parameters
    a: *
    The first object to compare.
    b: *
    The second object to compare.
    Returns
    True if the two arguments are equal, false otherwise.
    code »goog.array.equals ( arr1, arr2, opt_equalsFn )boolean

    Compares two arrays for equality. Two arrays are considered equal if they + have the same length and their corresponding elements are equal according to + the comparison function.

    Parameters
    arr1: goog.array.ArrayLike
    The first array to compare.
    arr2: goog.array.ArrayLike
    The second array to compare.
    opt_equalsFn: Function=
    Optional comparison function. + Should take 2 arguments to compare, and return true if the arguments + are equal. Defaults to goog.array.defaultCompareEquality which + compares the elements using the built-in '===' operator.
    Returns
    Whether the two arrays are equal.
    code »<T, S> goog.array.every ( arr, f, opt_obj )boolean

    Call f for each element of an array. If all calls return true, every() + returns true. If any call returns false, every() returns false and + does not continue to check the remaining elements. + + See http://tinyurl.com/developer-mozilla-org-array-every

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array + like object over which to iterate.
    f: ?function(this: S, T, number, ?): boolean
    The function to call for + for every element. This function takes 3 arguments (the element, the + index and the array) and should return a boolean.
    opt_obj: S=
    The object to be used as the value of 'this' + within f.
    Returns
    false if any element fails the test.
    code »<VALUE> goog.array.extend ( arr1, var_args )

    Extends an array with another array, element, or "array like" object. + This function operates 'in-place', it does not create a new Array. + + Example: + var a = []; + goog.array.extend(a, [0, 1]); + a; // [0, 1] + goog.array.extend(a, 2); + a; // [0, 1, 2]

    Parameters
    arr1: Array.<VALUE>
    The array to modify.
    var_args: ...(Array.<VALUE>|VALUE)
    The elements or arrays of elements + to add to arr1.
    code »<T, S> goog.array.filter ( arr, f, opt_obj )!Array.<T>

    Calls a function for each element in an array, and if the function returns + true adds the element to a new array. + + See http://tinyurl.com/developer-mozilla-org-array-filter

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array + like object over which to iterate.
    f: ?function(this: S, T, number, ?): boolean
    The function to call for + every element. This function + takes 3 arguments (the element, the index and the array) and must + return a Boolean. If the return value is true the element is added to the + result array. If it is false the element is not included.
    opt_obj: S=
    The object to be used as the value of 'this' + within f.
    Returns
    a new array in which only elements that passed the test + are present.
    code »<T, S> goog.array.find ( arr, f, opt_obj )?T

    Search an array for the first element that satisfies a given condition and + return that element.

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array + like object over which to iterate.
    f: ?function(this: S, T, number, ?): boolean
    The function to call + for every element. This function takes 3 arguments (the element, the + index and the array) and should return a boolean.
    opt_obj: S=
    An optional "this" context for the function.
    Returns
    The first array element that passes the test, or null if no + element is found.
    code »<T, S> goog.array.findIndex ( arr, f, opt_obj )number

    Search an array for the first element that satisfies a given condition and + return its index.

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array + like object over which to iterate.
    f: ?function(this: S, T, number, ?): boolean
    The function to call for + every element. This function + takes 3 arguments (the element, the index and the array) and should + return a boolean.
    opt_obj: S=
    An optional "this" context for the function.
    Returns
    The index of the first array element that passes the test, + or -1 if no element is found.
    code »<T, S> goog.array.findIndexRight ( arr, f, opt_obj )number

    Search an array (in reverse order) for the last element that satisfies a + given condition and return its index.

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array + like object over which to iterate.
    f: ?function(this: S, T, number, ?): boolean
    The function to call + for every element. This function + takes 3 arguments (the element, the index and the array) and should + return a boolean.
    opt_obj: Object=
    An optional "this" context for the function.
    Returns
    The index of the last array element that passes the test, + or -1 if no element is found.
    code »<T, S> goog.array.findRight ( arr, f, opt_obj )?T

    Search an array (in reverse order) for the last element that satisfies a + given condition and return that element.

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array + like object over which to iterate.
    f: ?function(this: S, T, number, ?): boolean
    The function to call + for every element. This function + takes 3 arguments (the element, the index and the array) and should + return a boolean.
    opt_obj: S=
    An optional "this" context for the function.
    Returns
    The last array element that passes the test, or null if no + element is found.

    Returns an array consisting of every argument with all arrays + expanded in-place recursively.

    Parameters
    var_args: ...*
    The values to flatten.
    Returns
    An array containing the flattened values.
    code »<T, S> goog.array.forEach ( arr, f, opt_obj )

    Calls a function for each element in an array. Skips holes in the array. + See http://tinyurl.com/developer-mozilla-org-array-foreach

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array like object over + which to iterate.
    f: ?function(this: S, T, number, ?): ?
    The function to call for every + element. This function takes 3 arguments (the element, the index and the + array). The return value is ignored.
    opt_obj: S=
    The object to be used as the value of 'this' within f.
    code »<T, S> goog.array.forEachRight ( arr, f, opt_obj )

    Calls a function for each element in an array, starting from the last + element rather than the first.

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array + like object over which to iterate.
    f: ?function(this: S, T, number, ?): ?
    The function to call for every + element. This function + takes 3 arguments (the element, the index and the array). The return + value is ignored.
    opt_obj: S=
    The object to be used as the value of 'this' + within f.
    code »<T> goog.array.indexOf ( arr, obj, opt_fromIndex )number

    Returns the index of the first element of an array with a specified value, or + -1 if the element is not present in the array. + + See http://tinyurl.com/developer-mozilla-org-array-indexof

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    The array to be searched.
    obj: T
    The object for which we are searching.
    opt_fromIndex: number=
    The index at which to start the search. If + omitted the search starts at index 0.
    Returns
    The index of the first matching array element.
    code »<T> goog.array.insert ( arr, obj )

    Pushes an item into an array, if it's not already in the array.

    Parameters
    arr: Array.<T>
    Array into which to insert the item.
    obj: T
    Value to add.
    code »goog.array.insertArrayAt ( arr, elementsToAdd, opt_i )

    Inserts at the given index of the array, all elements of another array.

    Parameters
    arr: goog.array.ArrayLike
    The array to modify.
    elementsToAdd: goog.array.ArrayLike
    The array of elements to add.
    opt_i: number=
    The index at which to insert the object. If omitted, + treated as 0. A negative index is counted from the end of the array.
    code »goog.array.insertAt ( arr, obj, opt_i )

    Inserts an object at the given index of the array.

    Parameters
    arr: goog.array.ArrayLike
    The array to modify.
    obj: *
    The object to insert.
    opt_i: number=
    The index at which to insert the object. If omitted, + treated as 0. A negative index is counted from the end of the array.
    code »<T> goog.array.insertBefore ( arr, obj, opt_obj2 )

    Inserts an object into an array before a specified object.

    Parameters
    arr: Array.<T>
    The array to modify.
    obj: T
    The object to insert.
    opt_obj2: T=
    The object before which obj should be inserted. If obj2 + is omitted or not found, obj is inserted at the end of the array.

    Whether the array is empty.

    Parameters
    arr: goog.array.ArrayLike
    The array to test.
    Returns
    true if empty.
    code »<T> goog.array.isSorted ( arr, opt_compareFn, opt_strict )boolean

    Tells if the array is sorted.

    Parameters
    arr: !Array.<T>
    The array.
    opt_compareFn: ?function(T, T): number=
    Function to compare the + array elements. + Should take 2 arguments to compare, and return a negative number, zero, + or a positive number depending on whether the first argument is less + than, equal to, or greater than the second.
    opt_strict: boolean=
    If true no equal elements are allowed.
    Returns
    Whether the array is sorted.
    code »<T> goog.array.join ( var_args )!Array.<T>

    Returns a new array that contains the contents of all the arrays passed.

    Parameters
    var_args
    code »<T> goog.array.last ( array )T

    Returns the last element in an array without removing it. + Same as goog.array.peek.

    Parameters
    array: (Array.<T>|goog.array.ArrayLike)
    The array.
    Returns
    Last item in array.
    code »<T> goog.array.lastIndexOf ( arr, obj, opt_fromIndex )number

    Returns the index of the last element of an array with a specified value, or + -1 if the element is not present in the array. + + See http://tinyurl.com/developer-mozilla-org-array-lastindexof

    Parameters
    arr: (!Array.<T>|!goog.array.ArrayLike)
    The array to be searched.
    obj: T
    The object for which we are searching.
    opt_fromIndex: ?number=
    The index at which to start the search. If + omitted the search starts at the end of the array.
    Returns
    The index of the last matching array element.
    code »<THIS, VALUE, RESULT> goog.array.map ( arr, f, opt_obj )!Array.<RESULT>

    Calls a function for each element in an array and inserts the result into a + new array. + + See http://tinyurl.com/developer-mozilla-org-array-map

    Parameters
    arr: (Array.<VALUE>|goog.array.ArrayLike)
    Array or array like object + over which to iterate.
    f: function(this: THIS, VALUE, number, ?): RESULT
    The function to call + for every element. This function takes 3 arguments (the element, + the index and the array) and should return something. The result will be + inserted into a new array.
    opt_obj: THIS=
    The object to be used as the value of 'this' within f.
    Returns
    a new array with the results from f.
    code »goog.array.moveItem ( arr, fromIndex, toIndex )

    Moves one item of an array to a new position keeping the order of the rest + of the items. Example use case: keeping a list of JavaScript objects + synchronized with the corresponding list of DOM elements after one of the + elements has been dragged to a new position.

    Parameters
    arr: !(Array|Arguments|{length: number})
    The array to modify.
    fromIndex: number
    Index of the item to move between 0 and + arr.length - 1.
    toIndex: number
    Target index between 0 and arr.length - 1.
    code »<T> goog.array.peek ( array )T

    Returns the last element in an array without removing it. + Same as goog.array.last.

    Parameters
    array: (Array.<T>|goog.array.ArrayLike)
    The array.
    Returns
    Last item in array.
    code »goog.array.range ( startOrEnd, opt_end, opt_step )!Array.<number>

    Creates a range of numbers in an arithmetic progression. + + Range takes 1, 2, or 3 arguments: +

    + range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]
    + range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]
    + range(-2, -5, -1) produces [-2, -3, -4]
    + range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.
    + 
    Parameters
    startOrEnd: number
    The starting value of the range if an end argument + is provided. Otherwise, the start value is 0, and this is the end value.
    opt_end: number=
    The optional end value of the range.
    opt_step: number=
    The step size between range values. Defaults to 1 + if opt_step is undefined or 0.
    Returns
    An array of numbers for the requested range. May be + an empty array if adding the step would not converge toward the end + value.
    code »<T, S, R> goog.array.reduce ( arr, f, val, opt_obj )R

    Passes every element of an array into a function and accumulates the result. + + See http://tinyurl.com/developer-mozilla-org-array-reduce + + For example: + var a = [1, 2, 3, 4]; + goog.array.reduce(a, function(r, v, i, arr) {return r + v;}, 0); + returns 10

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array + like object over which to iterate.
    f: ?function(this: S, R, T, number, ?): R
    The function to call for + every element. This function + takes 4 arguments (the function's previous result or the initial value, + the value of the current array element, the current array index, and the + array itself) + function(previousValue, currentValue, index, array).
    val: ?
    The initial value to pass into the function on the first call.
    opt_obj: S=
    The object to be used as the value of 'this' + within f.
    Returns
    Result of evaluating f repeatedly across the values of the array.
    code »<T, S, R> goog.array.reduceRight ( arr, f, val, opt_obj )R

    Passes every element of an array into a function and accumulates the result, + starting from the last element and working towards the first. + + See http://tinyurl.com/developer-mozilla-org-array-reduceright + + For example: + var a = ['a', 'b', 'c']; + goog.array.reduceRight(a, function(r, v, i, arr) {return r + v;}, ''); + returns 'cba'

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array + like object over which to iterate.
    f: ?function(this: S, R, T, number, ?): R
    The function to call for + every element. This function + takes 4 arguments (the function's previous result or the initial value, + the value of the current array element, the current array index, and the + array itself) + function(previousValue, currentValue, index, array).
    val: ?
    The initial value to pass into the function on the first call.
    opt_obj: S=
    The object to be used as the value of 'this' + within f.
    Returns
    Object returned as a result of evaluating f repeatedly across the + values of the array.
    code »<T> goog.array.remove ( arr, obj )boolean

    Removes the first occurrence of a particular value from an array.

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array from which to remove + value.
    obj: T
    Object to remove.
    Returns
    True if an element was removed.

    Removes from an array the element at index i

    Parameters
    arr: goog.array.ArrayLike
    Array or array like object from which to + remove value.
    i: number
    The index to remove.
    Returns
    True if an element was removed.
    code »<T> goog.array.removeDuplicates ( arr, opt_rv, opt_hashFn )

    Removes all duplicates from an array (retaining only the first + occurrence of each array element). This function modifies the + array in place and doesn't change the order of the non-duplicate items. + + For objects, duplicates are identified as having the same unique ID as + defined by goog.getUid. + + Alternatively you can specify a custom hash function that returns a unique + value for each item in the array it should consider unique. + + Runtime: N, + Worstcase space: 2N (no dupes)

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    The array from which to remove + duplicates.
    opt_rv: Array=
    An optional array in which to return the results, + instead of performing the removal inplace. If specified, the original + array will remain unchanged.
    opt_hashFn: function(T): string=
    An optional function to use to + apply to every item in the array. This function should return a unique + value for each item in the array it should consider unique.
    code »<T, S> goog.array.removeIf ( arr, f, opt_obj )boolean

    Removes the first value that satisfies the given condition.

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array + like object over which to iterate.
    f: ?function(this: S, T, number, ?): boolean
    The function to call + for every element. This function + takes 3 arguments (the element, the index and the array) and should + return a boolean.
    opt_obj: S=
    An optional "this" context for the function.
    Returns
    True if an element was removed.
    code »<VALUE> goog.array.repeat ( value, n )!Array.<VALUE>

    Returns an array consisting of the given value repeated N times.

    Parameters
    value: VALUE
    The value to repeat.
    n: number
    The repeat count.
    Returns
    An array with the repeated value.
    code »<T> goog.array.rotate ( array, n )!Array.<T>

    Rotates an array in-place. After calling this method, the element at + index i will be the element previously at index (i - n) % + array.length, for all values of i between 0 and array.length - 1, + inclusive. + + For example, suppose list comprises [t, a, n, k, s]. After invoking + rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].

    Parameters
    array: !Array.<T>
    The array to rotate.
    n: number
    The amount to rotate.
    Returns
    The array.
    code »goog.array.shuffle ( arr, opt_randFn )

    Shuffles the values in the specified array using the Fisher-Yates in-place + shuffle (also known as the Knuth Shuffle). By default, calls Math.random() + and so resets the state of that random number generator. Similarly, may reset + the state of the any other specified random number generator. + + Runtime: O(n)

    Parameters
    arr: !Array
    The array to be shuffled.
    opt_randFn: function(): number=
    Optional random function to use for + shuffling. + Takes no arguments, and returns a random number on the interval [0, 1). + Defaults to Math.random() using JavaScript's built-in Math library.
    code »<T> goog.array.slice ( arr, start, opt_end )!Array.<T>

    Returns a new array from a segment of an array. This is a generic version of + Array slice. This means that it might work on other objects similar to + arrays, such as the arguments object.

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    The array from + which to copy a segment.
    start: number
    The index of the first element to copy.
    opt_end: number=
    The index after the last element to copy.
    Returns
    A new array containing the specified segment of the + original array.
    code »<T, S> goog.array.some ( arr, f, opt_obj )boolean

    Calls f for each element of an array. If any call returns true, some() + returns true (without checking the remaining elements). If all calls + return false, some() returns false. + + See http://tinyurl.com/developer-mozilla-org-array-some

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array + like object over which to iterate.
    f: ?function(this: S, T, number, ?): boolean
    The function to call for + for every element. This function takes 3 arguments (the element, the + index and the array) and should return a boolean.
    opt_obj: S=
    The object to be used as the value of 'this' + within f.
    Returns
    true if any element passes the test.
    code »<T> goog.array.sort ( arr, opt_compareFn )

    Sorts the specified array into ascending order. If no opt_compareFn is + specified, elements are compared using + goog.array.defaultCompare, which compares the elements using + the built in < and > operators. This will produce the expected behavior + for homogeneous arrays of String(s) and Number(s), unlike the native sort, + but will give unpredictable results for heterogenous lists of strings and + numbers with different numbers of digits. + + This sort is not guaranteed to be stable. + + Runtime: Same as Array.prototype.sort

    Parameters
    arr: Array.<T>
    The array to be sorted.
    opt_compareFn: ?function(T, T): number=
    Optional comparison + function by which the + array is to be ordered. Should take 2 arguments to compare, and return a + negative number, zero, or a positive number depending on whether the + first argument is less than, equal to, or greater than the second.
    code »goog.array.sortObjectsByKey ( arr, key, opt_compareFn )

    Sorts an array of objects by the specified object key and compare + function. If no compare function is provided, the key values are + compared in ascending order using goog.array.defaultCompare. + This won't work for keys that get renamed by the compiler. So use + {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.

    Parameters
    arr: Array.<Object>
    An array of objects to sort.
    key: string
    The object key to sort by.
    opt_compareFn: Function=
    The function to use to compare key + values.
    code »<T> goog.array.splice ( arr, index, howMany, var_args )!Array.<T>

    Adds or removes elements from an array. This is a generic version of Array + splice. This means that it might work on other objects similar to arrays, + such as the arguments object.

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    The array to modify.
    index: (number|undefined)
    The index at which to start changing the + array. If not defined, treated as 0.
    howMany: number
    How many elements to remove (0 means no removal. A + value below 0 is treated as zero and so is any other non number. Numbers + are floored).
    var_args: ...T
    Optional, additional elements to insert into the + array.
    Returns
    the removed elements.
    code »<T> goog.array.stableSort ( arr, opt_compareFn )

    Sorts the specified array into ascending order in a stable way. If no + opt_compareFn is specified, elements are compared using + goog.array.defaultCompare, which compares the elements using + the built in < and > operators. This will produce the expected behavior + for homogeneous arrays of String(s) and Number(s). + + Runtime: Same as Array.prototype.sort, plus an additional + O(n) overhead of copying the array twice.

    Parameters
    arr: Array.<T>
    The array to be sorted.
    opt_compareFn: ?function(T, T): number=
    Optional comparison function + by which the array is to be ordered. Should take 2 arguments to compare, + and return a negative number, zero, or a positive number depending on + whether the first argument is less than, equal to, or greater than the + second.
    code »<T> goog.array.toArray ( object )!Array.<T>

    Converts an object to an array.

    Parameters
    object: (Array.<T>|goog.array.ArrayLike)
    The object to convert to an + array.
    Returns
    The object converted into an array. If object has a + length property, every property indexed with a non-negative number + less than length will be included in the result. If object does not + have a length property, an empty array will be returned.
    code »<T, S> goog.array.toObject ( arr, keyFunc, opt_obj )!Object.<T>

    Creates a new object built from the provided array and the key-generation + function.

    Parameters
    arr: (Array.<T>|goog.array.ArrayLike)
    Array or array like object over + which to iterate whose elements will be the values in the new object.
    keyFunc: ?function(this: S, T, number, ?): string
    The function to + call for every element. This function takes 3 arguments (the element, the + index and the array) and should return a string that will be used as the + key for the element in the new object. If the function returns the same + key for more than one element, the value for that key is + implementation-defined.
    opt_obj: S=
    The object to be used as the value of 'this' + within keyFunc.
    Returns
    The new object.
    code »goog.array.zip ( var_args )!Array

    Creates a new array for which the element at position i is an array of the + ith element of the provided arrays. The returned array will only be as long + as the shortest array provided; additional values are ignored. For example, + the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]]. + + This is similar to the zip() function in Python. See http://docs.python.org/library/functions.html#zip

    Parameters
    var_args: ...!goog.array.ArrayLike
    Arrays to be combined.
    Returns
    A new array of arrays created from provided arrays.

    Global Properties

    Reference to the original Array.prototype.

    Compiler Constants

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_asserts.html b/node_modules/selenium-webdriver/docs/namespace_goog_asserts.html new file mode 100644 index 0000000..bdb36c7 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_asserts.html @@ -0,0 +1,22 @@ +goog.asserts

    Namespace goog.asserts

    code »

    Classes

    goog.asserts.AssertionError
    Error object for failed assertions.
    Show:

    Global Functions

    code »<T> goog.asserts.assert ( condition, opt_message, var_args )T

    Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is + true.

    Parameters
    condition: T
    The condition to check.
    opt_message: string=
    Error message in case of failure.
    var_args: ...*
    The items to substitute into the failure message.
    Returns
    The value of the condition.
    Throws
    goog.asserts.AssertionError
    When the condition evaluates to false.
    code »goog.asserts.assertArray ( value, opt_message, var_args )!Array

    Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true.

    Parameters
    value: *
    The value to check.
    opt_message: string=
    Error message in case of failure.
    var_args: ...*
    The items to substitute into the failure message.
    Returns
    The value, guaranteed to be a non-null array.
    Throws
    goog.asserts.AssertionError
    When the value is not an array.
    code »goog.asserts.assertBoolean ( value, opt_message, var_args )boolean

    Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true.

    Parameters
    value: *
    The value to check.
    opt_message: string=
    Error message in case of failure.
    var_args: ...*
    The items to substitute into the failure message.
    Returns
    The value, guaranteed to be a boolean when asserts are + enabled.
    Throws
    goog.asserts.AssertionError
    When the value is not a boolean.
    code »goog.asserts.assertElement ( value, opt_message, var_args )!Element

    Checks if the value is a DOM Element if goog.asserts.ENABLE_ASSERTS is true.

    Parameters
    value: *
    The value to check.
    opt_message: string=
    Error message in case of failure.
    var_args: ...*
    The items to substitute into the failure message.
    Returns
    The value, likely to be a DOM Element when asserts are + enabled.
    Throws
    goog.asserts.AssertionError
    When the value is not a boolean.
    code »goog.asserts.assertFunction ( value, opt_message, var_args )!Function

    Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true.

    Parameters
    value: *
    The value to check.
    opt_message: string=
    Error message in case of failure.
    var_args: ...*
    The items to substitute into the failure message.
    Returns
    The value, guaranteed to be a function when asserts + enabled.
    Throws
    goog.asserts.AssertionError
    When the value is not a function.
    code »<T> goog.asserts.assertInstanceof ( value, type, opt_message, var_args )!T

    Checks if the value is an instance of the user-defined type if + goog.asserts.ENABLE_ASSERTS is true. + + The compiler may tighten the type returned by this function.

    Parameters
    value: *
    The value to check.
    type: function(new: T, ...)
    A user-defined constructor.
    opt_message: string=
    Error message in case of failure.
    var_args: ...*
    The items to substitute into the failure message.
    Throws
    goog.asserts.AssertionError
    When the value is not an instance of + type.
    code »goog.asserts.assertNumber ( value, opt_message, var_args )number

    Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true.

    Parameters
    value: *
    The value to check.
    opt_message: string=
    Error message in case of failure.
    var_args: ...*
    The items to substitute into the failure message.
    Returns
    The value, guaranteed to be a number when asserts enabled.
    Throws
    goog.asserts.AssertionError
    When the value is not a number.
    code »goog.asserts.assertObject ( value, opt_message, var_args )!Object

    Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true.

    Parameters
    value: *
    The value to check.
    opt_message: string=
    Error message in case of failure.
    var_args: ...*
    The items to substitute into the failure message.
    Returns
    The value, guaranteed to be a non-null object.
    Throws
    goog.asserts.AssertionError
    When the value is not an object.

    Checks that no enumerable keys are present in Object.prototype. Such keys + would break most code that use for (var ... in ...) loops.

    code »goog.asserts.assertString ( value, opt_message, var_args )string

    Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true.

    Parameters
    value: *
    The value to check.
    opt_message: string=
    Error message in case of failure.
    var_args: ...*
    The items to substitute into the failure message.
    Returns
    The value, guaranteed to be a string when asserts enabled.
    Throws
    goog.asserts.AssertionError
    When the value is not a string.
    code »goog.asserts.doAssertFailure_ ( defaultMessage, defaultArgs, givenMessage, givenArgs )

    Throws an exception with the given message and "Assertion failed" prefixed + onto it.

    Parameters
    defaultMessage: string
    The message to use if givenMessage is empty.
    defaultArgs: Array
    The substitution arguments for defaultMessage.
    givenMessage: (string|undefined)
    Message supplied by the caller.
    givenArgs: Array
    The substitution arguments for givenMessage.
    Throws
    goog.asserts.AssertionError
    When the value is not a number.
    code »goog.asserts.fail ( opt_message, var_args )

    Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case + when we want to add a check in the unreachable area like switch-case + statement: + +

    +  switch(type) {
    +    case FOO: doSomething(); break;
    +    case BAR: doSomethingElse(); break;
    +    default: goog.assert.fail('Unrecognized type: ' + type);
    +      // We have only 2 types - "default:" section is unreachable code.
    +  }
    + 
    Parameters
    opt_message: string=
    Error message in case of failure.
    var_args: ...*
    The items to substitute into the failure message.
    Throws
    goog.asserts.AssertionError
    Failure.

    Compiler Constants

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_debug.html b/node_modules/selenium-webdriver/docs/namespace_goog_debug.html new file mode 100644 index 0000000..351be28 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_debug.html @@ -0,0 +1 @@ +goog.debug

    Namespace goog.debug

    code »

    Classes

    goog.debug.Error
    Base class for custom error objects.
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_dom.html b/node_modules/selenium-webdriver/docs/namespace_goog_dom.html new file mode 100644 index 0000000..3331708 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_dom.html @@ -0,0 +1 @@ +goog.dom

    Namespace goog.dom

    code »

    Enumerations

    goog.dom.NodeType
    Constants for the nodeType attribute in the Node interface.
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_functions.html b/node_modules/selenium-webdriver/docs/namespace_goog_functions.html new file mode 100644 index 0000000..2c6b22d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_functions.html @@ -0,0 +1,30 @@ +goog.functions

    Namespace goog.functions

    code »
    Show:

    Global Functions

    Always returns false.

    Always returns NULL.

    Always returns true.

    code »goog.functions.and ( var_args )function(?): boolean

    Creates a function that returns true if each of its components evaluates + to true. The components are evaluated in order, and the evaluation will be + short-circuited as soon as a function returns false. + For example, (goog.functions.and(f, g))(x) is equivalent to f(x) && g(x).

    Parameters
    var_args: ...Function
    A list of functions.
    Returns
    A function that ANDs its component + functions.
    code »<T> goog.functions.cacheReturnValue ( fn )!function(): T

    Gives a wrapper function that caches the return value of a parameterless + function when first called. + + When called for the first time, the given function is called and its + return value is cached (thus this is only appropriate for idempotent + functions). Subsequent calls will return the cached return value. This + allows the evaluation of expensive functions to be delayed until first used. + + To cache the return values of functions with parameters, see goog.memoize.

    Parameters
    fn: !function(): T
    A function to lazily evaluate.
    Returns
    A wrapped version the function.
    code »<T> goog.functions.compose ( fn, var_args )function(?): T

    Creates the composition of the functions passed in. + For example, (goog.functions.compose(f, g))(a) is equivalent to f(g(a)).

    Parameters
    fn: function(?): T
    The final function.
    var_args: ...Function
    A list of functions.
    Returns
    The composition of all inputs.
    code »<T> goog.functions.constant ( retValue )function(): T

    Creates a function that always returns the same value.

    Parameters
    retValue: T
    The value to return.
    Returns
    The new function.
    code »goog.functions.create ( constructor, var_args )!Object

    Generic factory function to construct an object given the constructor + and the arguments. Intended to be bound to create object factories. + + Callers should cast the result to the appropriate type for proper type + checking by the compiler.

    Parameters
    constructor: !Function
    The constructor for the Object.
    var_args: ...*
    The arguments to be passed to the constructor.
    Returns
    A new instance of the class given in constructor.

    Creates a function that always throws an error with the given message.

    Parameters
    message: string
    The error message.
    Returns
    The error-throwing function.

    Creates a function that throws the given object.

    Parameters
    err: *
    An object to be thrown.
    Returns
    The error-throwing function.
    code »<T> goog.functions.identity ( opt_returnValue, var_args )T

    A simple function that returns the first argument of whatever is passed + into it.

    Parameters
    opt_returnValue: T=
    The single value that will be returned.
    var_args: ...*
    Optional trailing arguments. These are ignored.
    Returns
    The first argument passed in, or undefined if nothing was passed.
    code »goog.functions.lock ( f, opt_numArgs )!Function

    Given a function, create a function that keeps opt_numArgs arguments and + silently discards all additional arguments.

    Parameters
    f: Function
    The original function.
    opt_numArgs: number=
    The number of arguments to keep. Defaults to 0.
    Returns
    A version of f that only keeps the first opt_numArgs + arguments.
    code »goog.functions.not ( f )function(?): boolean

    Creates a function that returns the Boolean opposite of a provided function. + For example, (goog.functions.not(f))(x) is equivalent to !f(x).

    Parameters
    f: !Function
    The original function.
    Returns
    A function that delegates to f and returns + opposite.

    Creates a function that returns its nth argument.

    Parameters
    n: number
    The position of the return argument.
    Returns
    A new function.
    code »goog.functions.or ( var_args )function(?): boolean

    Creates a function that returns true if any of its components evaluates + to true. The components are evaluated in order, and the evaluation will be + short-circuited as soon as a function returns true. + For example, (goog.functions.or(f, g))(x) is equivalent to f(x) || g(x).

    Parameters
    var_args: ...Function
    A list of functions.
    Returns
    A function that ORs its component + functions.

    Creates a function that calls the functions passed in in sequence, and + returns the value of the last function. For example, + (goog.functions.sequence(f, g))(x) is equivalent to f(x),g(x).

    Parameters
    var_args: ...Function
    A list of functions.
    Returns
    A function that calls all inputs in sequence.
    code »<T> goog.functions.withReturnValue ( f, retValue )function(?): T

    Given a function, create a new function that swallows its return value + and replaces it with a new one.

    Parameters
    f: Function
    A function.
    retValue: T
    A new return value.
    Returns
    A new function.

    Compiler Constants

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_iter.html b/node_modules/selenium-webdriver/docs/namespace_goog_iter.html new file mode 100644 index 0000000..d2c1cc4 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_iter.html @@ -0,0 +1,189 @@ +goog.iter

    Namespace goog.iter

    code »

    Classes

    goog.iter.GroupByIterator_
    Implements the goog.iter.groupBy iterator.
    goog.iter.Iterator
    Class/interface for iterators.
    Show:

    Type Definitions

    code »goog.iter.Iterable : (goog.iter.Iterator|{length: number}|{__iterator__: ?})
    No description.

    Global Functions

    Creates an iterator that returns running totals from the numbers in + iterable. For example, the array [1, 2, 3, 4, 5] yields + 1 -> 3 -> 6 -> 10 -> 15.

    Parameters
    iterable: !goog.iter.Iterable.<number>
    The iterable of numbers to + accumulate.
    Returns
    A new iterator that returns the + numbers in the series.
    code »<VALUE> goog.iter.chain ( var_args )!goog.iter.Iterator.<VALUE>

    Takes zero or more iterables and returns one iterator that will iterate over + them in the order chained.

    Parameters
    var_args: ...(!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    Any + number of iterable objects.
    Returns
    Returns a new iterator that will + iterate over all the given iterables' contents.
    code »<VALUE> goog.iter.chainFromIterable ( iterable )!goog.iter.Iterator.<VALUE>

    Takes a single iterable containing zero or more iterables and returns one + iterator that will iterate over each one in the order given.

    Parameters
    iterable: goog.iter.Iterable
    The iterable of iterables to chain.
    Returns
    Returns a new iterator that will + iterate over all the contents of the iterables contained within + iterable.
    code »<VALUE> goog.iter.combinations ( iterable, length )!goog.iter.Iterator

    Creates an iterator that returns combinations of elements from + iterable. + + Combinations are obtained by taking the goog.iter#permutations of + iterable and filtering those whose elements appear in the order they + are encountered in iterable. For example, the 3-length combinations + of [0,1,2,3] are [[0,1,2], [0,1,3], [0,2,3], [1,2,3]].

    Parameters
    iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The + iterable from which to generate combinations.
    length: number
    The length of each combination.
    Returns
    A new iterator containing + combinations from the iterable.

    Creates an iterator that returns combinations of elements from + iterable, with repeated elements possible. + + Combinations are obtained by taking the Cartesian product of length + iterables and filtering those whose elements appear in the order they are + encountered in iterable. For example, the 2-length combinations of + [1,2,3] are [[1,1], [1,2], [1,3], [2,2], [2,3], [3,3]].

    Parameters
    iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The + iterable to combine.
    length: number
    The length of each combination.
    Returns
    A new iterator containing + combinations from the iterable.
    code »<VALUE> goog.iter.compress ( iterable, selectors )!goog.iter.Iterator.<VALUE>

    Creates an iterator that filters iterable based on a series of + selectors. On each call to next(), one item is taken from + both the iterable and selectors iterators. If the item from + selectors evaluates to true, the item from iterable is given. + Otherwise, it is skipped. Once either iterable or selectors + is exhausted, subsequent calls to next() will throw + goog.iter.StopIteration.

    Parameters
    iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The + iterable to filter.
    selectors: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    An + iterable of items to be evaluated in a boolean context to determine if + the corresponding element in iterable should be included in the + result.
    Returns
    A new iterator that returns the + filtered values.
    code »<VALUE> goog.iter.consume ( iterable, count )!goog.iter.Iterator.<VALUE>

    Creates an iterator that is advanced count steps ahead. Consumed + values are silently discarded. If count is greater than the number + of elements in iterable, an empty iterator is returned. Subsequent + calls to next() will throw goog.iter.StopIteration.

    Parameters
    iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The + iterable to consume.
    count: number
    The number of elements to consume from the iterator.
    Returns
    An iterator advanced zero or more steps + ahead.
    code »goog.iter.count ( opt_start, opt_step )!goog.iter.Iterator.<number>

    Creates an iterator that counts indefinitely from a starting value.

    Parameters
    opt_start: number=
    The starting value. Default is 0.
    opt_step: number=
    The number to increment with between each call to + next. Negative and floating point numbers are allowed. Default is 1.
    Returns
    A new iterator that returns the values + in the series.
    code »<VALUE> goog.iter.cycle ( iterable )!goog.iter.Iterator.<VALUE>

    Create an iterator to cycle over the iterable's elements indefinitely. + For example, ([1, 2, 3]) would return : 1, 2, 3, 1, 2, 3, ...

    Parameters
    iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The + iterable object.
    Returns
    An iterator that iterates indefinitely + over the values in iterable.
    code »<THIS, VALUE> goog.iter.dropWhile ( iterable, f, opt_obj )!goog.iter.Iterator.<VALUE>

    Builds a new iterator that iterates over the original, but skips elements as + long as a supplied function returns true.

    Parameters
    iterable: (goog.iter.Iterator.<VALUE>|goog.iter.Iterable)
    The iterator + object.
    f: function(this: THIS, VALUE, undefined, goog.iter.Iterator.<VALUE>): boolean
    The function to call for every value. This function takes 3 arguments + (the value, undefined, and the iterator) and should return a boolean.
    opt_obj: THIS=
    The object to be used as the value of 'this' within + f.
    Returns
    A new iterator that drops elements from + the original iterator as long as f is true.
    code »<VALUE> goog.iter.enumerate ( iterable, opt_start )!goog.iter.Iterator

    Creates an iterator that returns arrays containing a count and an element + obtained from the given iterable.

    Parameters
    iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The + iterable to enumerate.
    opt_start: number=
    Optional starting value. Default is 0.
    Returns
    A new iterator containing count/item + pairs.
    code »<VALUE> goog.iter.equals ( iterable1, iterable2 )boolean

    Iterates over two iterables and returns true if they contain the same + sequence of elements and have the same length.

    Parameters
    iterable1: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The first + iterable object.
    iterable2: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The second + iterable object.
    Returns
    true if the iterables contain the same sequence of elements + and have the same length.
    code »<THIS, VALUE> goog.iter.every ( iterable, f, opt_obj )boolean

    Goes through the values in the iterator. Calls f for each of these and if any + of them returns false this returns false (without checking the rest). If all + return true this will return true.

    Parameters
    iterable: (goog.iter.Iterator.<VALUE>|goog.iter.Iterable)
    The iterator + object.
    f: function(this: THIS, VALUE, undefined, goog.iter.Iterator.<VALUE>): boolean
    The function to call for every value. This function takes 3 arguments + (the value, undefined, and the iterator) and should return a boolean.
    opt_obj: THIS=
    The object to be used as the value of 'this' within + f.
    Returns
    true if every value passes the test.
    code »<THIS, VALUE> goog.iter.filter ( iterable, f, opt_obj )!goog.iter.Iterator.<VALUE>

    Calls a function for every element in the iterator, and if the function + returns true adds the element to a new iterator.

    Parameters
    iterable: (goog.iter.Iterator.<VALUE>|goog.iter.Iterable)
    The iterator + to iterate over.
    f: function(this: THIS, VALUE, undefined, goog.iter.Iterator.<VALUE>): boolean
    The function to call for every element. This function takes 3 arguments + (the element, undefined, and the iterator) and should return a boolean. + If the return value is true the element will be included in the returned + iterator. If it is false the element is not included.
    opt_obj: THIS=
    The object to be used as the value of 'this' within + f.
    Returns
    A new iterator in which only elements + that passed the test are present.
    code »<THIS, VALUE> goog.iter.filterFalse ( iterable, f, opt_obj )!goog.iter.Iterator.<VALUE>

    Calls a function for every element in the iterator, and if the function + returns false adds the element to a new iterator.

    Parameters
    iterable: (goog.iter.Iterator.<VALUE>|goog.iter.Iterable)
    The iterator + to iterate over.
    f: function(this: THIS, VALUE, undefined, goog.iter.Iterator.<VALUE>): boolean
    The function to call for every element. This function takes 3 arguments + (the element, undefined, and the iterator) and should return a boolean. + If the return value is false the element will be included in the returned + iterator. If it is true the element is not included.
    opt_obj: THIS=
    The object to be used as the value of 'this' within + f.
    Returns
    A new iterator in which only elements + that did not pass the test are present.
    code »<THIS, VALUE> goog.iter.forEach ( iterable, f, opt_obj )

    Calls a function for each element in the iterator with the element of the + iterator passed as argument.

    Parameters
    iterable: (goog.iter.Iterator.<VALUE>|goog.iter.Iterable)
    The iterator + to iterate over. If the iterable is an object toIterator will be + called on it.
    f: (function(this: THIS, VALUE, undefined, goog.iter.Iterator.<VALUE>)|function(this: THIS, number, undefined, goog.iter.Iterator.<VALUE>))
    The function to call for every element. This function takes 3 arguments + (the element, undefined, and the iterator) and the return value is + irrelevant. The reason for passing undefined as the second argument is + so that the same function can be used in goog.array#forEach as + well as others.
    opt_obj: THIS=
    The object to be used as the value of 'this' within + f.
    code »<KEY, VALUE> goog.iter.groupBy ( iterable, opt_keyFunc )!goog.iter.Iterator

    Creates an iterator that returns arrays containing elements from the + iterable grouped by a key value. For iterables with repeated + elements (i.e. sorted according to a particular key function), this function + has a uniq-like effect. For example, grouping the array: + [A, B, B, C, C, A] produces + [A, [A]], [B, [B, B]], [C, [C, C]], [A, [A]].

    Parameters
    iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The + iterable to group.
    opt_keyFunc: function(VALUE): KEY=
    Optional function for + determining the key value for each group in the iterable. Default + is the identity function.
    Returns
    A new iterator that returns arrays of + consecutive key and groups.

    Checks an array for duplicate elements.

    Parameters
    arr: (Array.<VALUE>|goog.array.ArrayLike)
    The array to check for + duplicates.
    Returns
    True, if the array contains duplicates, false otherwise.
    code »<VALUE> goog.iter.join ( iterable, deliminator )string

    Joins the values in a iterator with a delimiter.

    Parameters
    iterable: (goog.iter.Iterator.<VALUE>|goog.iter.Iterable)
    The iterator + to get the values from.
    deliminator: string
    The text to put between the values.
    Returns
    The joined value string.
    code »<VALUE> goog.iter.limit ( iterable, limitSize )!goog.iter.Iterator.<VALUE>

    Creates an iterator that returns the first limitSize elements from an + iterable. If this number is greater than the number of elements in the + iterable, all the elements are returned.

    Parameters
    iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The + iterable to limit.
    limitSize: number
    The maximum number of elements to return.
    Returns
    A new iterator containing + limitSize elements.
    code »<THIS, VALUE, RESULT> goog.iter.map ( iterable, f, opt_obj )!goog.iter.Iterator.<RESULT>

    For every element in the iterator call a function and return a new iterator + with that value.

    Parameters
    iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The + iterator to iterate over.
    f: function(this: THIS, VALUE, undefined, !goog.iter.Iterator.<VALUE>): RESULT
    The function to call for every element. This function takes 3 arguments + (the element, undefined, and the iterator) and should return a new value.
    opt_obj: THIS=
    The object to be used as the value of 'this' within + f.
    Returns
    A new iterator that returns the + results of applying the function to each element in the original + iterator.
    code »<VALUE> goog.iter.nextOrValue ( iterable, defaultValue )VALUE

    Advances the iterator to the next position, returning the given default value + instead of throwing an exception if the iterator has no more entries.

    Parameters
    iterable: (goog.iter.Iterator.<VALUE>|goog.iter.Iterable)
    The iterable + object.
    defaultValue: VALUE
    The value to return if the iterator is empty.
    Returns
    The next item in the iteration, or defaultValue if the + iterator was empty.
    code »<VALUE> goog.iter.permutations ( iterable, opt_length )!goog.iter.Iterator

    Creates an iterator that returns permutations of elements in + iterable. + + Permutations are obtained by taking the Cartesian product of + opt_length iterables and filtering out those with repeated + elements. For example, the permutations of [1,2,3] are + [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]].

    Parameters
    iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The + iterable from which to generate permutations.
    opt_length: number=
    Length of each permutation. If omitted, defaults + to the length of iterable.
    Returns
    A new iterator containing the + permutations of iterable.

    Cartesian product of zero or more sets. Gives an iterator that gives every + combination of one element chosen from each set. For example, + ([1, 2], [3, 4]) gives ([1, 3], [1, 4], [2, 3], [2, 4]).

    Parameters
    var_args: ...!goog.array.ArrayLike.<VALUE>
    Zero or more sets, as + arrays.
    Returns
    An iterator that gives each + n-tuple (as an array).
    code »goog.iter.range ( startOrStop, opt_stop, opt_step )!goog.iter.Iterator.<number>

    Creates a new iterator that returns the values in a range. This function + can take 1, 2 or 3 arguments: +

    + range(5) same as range(0, 5, 1)
    + range(2, 5) same as range(2, 5, 1)
    + 
    Parameters
    startOrStop: number
    The stop value if only one argument is provided. + The start value if 2 or more arguments are provided. If only one + argument is used the start value is 0.
    opt_stop: number=
    The stop value. If left out then the first + argument is used as the stop value.
    opt_step: number=
    The number to increment with between each call to + next. This can be negative.
    Returns
    A new iterator that returns the values + in the range.
    code »<THIS, VALUE> goog.iter.reduce ( iterable, f, val, opt_obj )VALUE

    Passes every element of an iterator into a function and accumulates the + result.

    Parameters
    iterable: (goog.iter.Iterator.<VALUE>|goog.iter.Iterable)
    The iterator + to iterate over.
    f: function(this: THIS, VALUE, VALUE): VALUE
    The function to call for + every element. This function takes 2 arguments (the function's previous + result or the initial value, and the value of the current element). + function(previousValue, currentElement) : newValue.
    val: VALUE
    The initial value to pass into the function on the first + call.
    opt_obj: THIS=
    The object to be used as the value of 'this' within + f.
    Returns
    Result of evaluating f repeatedly across the values of + the iterator.
    code »<VALUE> goog.iter.repeat ( value )!goog.iter.Iterator.<VALUE>

    Creates an iterator that returns the same object or value repeatedly.

    Parameters
    value: VALUE
    Any object or value to repeat.
    Returns
    A new iterator that returns the + repeated value.
    code »<VALUE> goog.iter.slice ( iterable, start, opt_end )!goog.iter.Iterator.<VALUE>

    Creates an iterator that returns a range of elements from an iterable. + Similar to goog.array#slice but does not support negative indexes.

    Parameters
    iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The + iterable to slice.
    start: number
    The index of the first element to return.
    opt_end: number=
    The index after the last element to return. If + defined, must be greater than or equal to start.
    Returns
    A new iterator containing a slice of + the original.
    code »<THIS, VALUE> goog.iter.some ( iterable, f, opt_obj )boolean

    Goes through the values in the iterator. Calls f for each of these, and if + any of them returns true, this returns true (without checking the rest). If + all return false this will return false.

    Parameters
    iterable: (goog.iter.Iterator.<VALUE>|goog.iter.Iterable)
    The iterator + object.
    f: function(this: THIS, VALUE, undefined, goog.iter.Iterator.<VALUE>): boolean
    The function to call for every value. This function takes 3 arguments + (the value, undefined, and the iterator) and should return a boolean.
    opt_obj: THIS=
    The object to be used as the value of 'this' within + f.
    Returns
    true if any value passes the test.
    code »<THIS, RESULT> goog.iter.starMap ( iterable, f, opt_obj )!goog.iter.Iterator.<RESULT>

    Gives an iterator that gives the result of calling the given function + f with the arguments taken from the next element from + iterable (the elements are expected to also be iterables). + + Similar to goog.iter#map but allows the function to accept multiple + arguments from the iterable.

    Parameters
    iterable: !goog.iter.Iterable
    The iterable of + iterables to iterate over.
    f: function(this: THIS, *): RESULT
    The function to call for every + element. This function takes N+2 arguments, where N represents the + number of items from the next element of the iterable. The two + additional arguments passed to the function are undefined and the + iterator itself. The function should return a new value.
    opt_obj: THIS=
    The object to be used as the value of 'this' within + f.
    Returns
    A new iterator that returns the + results of applying the function to each element in the original + iterator.
    code »<THIS, VALUE> goog.iter.takeWhile ( iterable, f, opt_obj )!goog.iter.Iterator.<VALUE>

    Builds a new iterator that iterates over the original, but only as long as a + supplied function returns true.

    Parameters
    iterable: (goog.iter.Iterator.<VALUE>|goog.iter.Iterable)
    The iterator + object.
    f: function(this: THIS, VALUE, undefined, goog.iter.Iterator.<VALUE>): boolean
    The function to call for every value. This function takes 3 arguments + (the value, undefined, and the iterator) and should return a boolean.
    opt_obj: THIS=
    This is used as the 'this' object in f when called.
    Returns
    A new iterator that keeps elements in + the original iterator as long as the function is true.
    code »<VALUE> goog.iter.tee ( iterable, opt_num )!Array.<goog.iter.Iterator>

    Returns an array of iterators each of which can iterate over the values in + iterable without advancing the others.

    Parameters
    iterable: (!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    The + iterable to tee.
    opt_num: number=
    The number of iterators to create. Default is 2.
    Returns
    An array of iterators.
    code »<VALUE> goog.iter.toArray ( iterable )!Array.<VALUE>

    Converts the iterator to an array

    Parameters
    iterable: (goog.iter.Iterator.<VALUE>|goog.iter.Iterable)
    The iterator + to convert to an array.
    Returns
    An array of the elements the iterator iterates over.
    code »<VALUE> goog.iter.toIterator ( iterable )!goog.iter.Iterator.<VALUE>

    Returns an iterator that knows how to iterate over the values in the object.

    Parameters
    iterable: (goog.iter.Iterator.<VALUE>|goog.iter.Iterable)
    If the + object is an iterator it will be returned as is. If the object has an + __iterator__ method that will be called to get the value + iterator. If the object is an array-like object we create an iterator + for that.
    Returns
    An iterator that knows how to iterate + over the values in iterable.
    code »<VALUE> goog.iter.zip ( var_args )!goog.iter.Iterator

    Creates an iterator that returns arrays containing the ith elements from the + provided iterables. The returned arrays will be the same size as the number + of iterables given in var_args. Once the shortest iterable is + exhausted, subsequent calls to next() will throw + goog.iter.StopIteration.

    Parameters
    var_args: ...(!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    Any + number of iterable objects.
    Returns
    A new iterator that returns + arrays of elements from the provided iterables.
    code »<VALUE> goog.iter.zipLongest ( fillValue, var_args )!goog.iter.Iterator

    Creates an iterator that returns arrays containing the ith elements from the + provided iterables. The returned arrays will be the same size as the number + of iterables given in var_args. Shorter iterables will be extended + with fillValue. Once the longest iterable is exhausted, subsequent + calls to next() will throw goog.iter.StopIteration.

    Parameters
    fillValue: VALUE
    The object or value used to fill shorter iterables.
    var_args: ...(!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable)
    Any + number of iterable objects.
    Returns
    A new iterator that returns + arrays of elements from the provided iterables.

    Global Properties

    Singleton Error object that is used to terminate iterations.

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_json.html b/node_modules/selenium-webdriver/docs/namespace_goog_json.html new file mode 100644 index 0000000..401618f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_json.html @@ -0,0 +1,10 @@ +goog.json

    Namespace goog.json

    code »

    Classes

    goog.json.Serializer
    Class that is used to serialize JSON objects to a string.
    Show:

    Type Definitions

    code »goog.json.Replacer : function(this: Object, string, *): *
    JSON replacer, as defined in Section 15.12.3 of the ES5 spec.
    code »goog.json.Reviver : function(this: Object, string, *): *
    JSON reviver, as defined in Section 15.12.2 of the ES5 spec.

    Global Functions

    Tests if a string is an invalid JSON string. This only ensures that we are + not using any invalid characters

    Parameters
    s: string
    The string to test.
    Returns
    True if the input is a valid JSON string.

    Parses a JSON string and returns the result. This throws an exception if + the string is an invalid JSON string. + + Note that this is very slow on large strings. If you trust the source of + the string then you should use unsafeParse instead.

    Parameters
    s: *
    The JSON string to parse.
    Returns
    The object generated from the JSON string, or null.
    Throws
    if s is invalid JSON.
    code »goog.json.serialize ( object, opt_replacer )string

    Serializes an object or a value to a JSON string.

    Parameters
    object: *
    The object to serialize.
    opt_replacer: ?goog.json.Replacer=
    A replacer function + called for each (key, value) pair that determines how the value + should be serialized. By defult, this just returns the value + and allows default serialization to kick in.
    Returns
    A JSON string representation of the input.
    Throws
    if there are loops in the object graph.

    Parses a JSON string and returns the result. This uses eval so it is open + to security issues and it should only be used if you trust the source.

    Parameters
    s: string
    The JSON string to parse.
    Returns
    The object generated from the JSON string.

    Compiler Constants

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_labs.html b/node_modules/selenium-webdriver/docs/namespace_goog_labs.html new file mode 100644 index 0000000..275cd54 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_labs.html @@ -0,0 +1 @@ +goog.labs

    Namespace goog.labs

    code »
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_labs_testing.html b/node_modules/selenium-webdriver/docs/namespace_goog_labs_testing.html new file mode 100644 index 0000000..2d4df99 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_labs_testing.html @@ -0,0 +1 @@ +goog.labs.testing

    Namespace goog.labs.testing

    code »

    Interfaces

    goog.labs.testing.Matcher
    A matcher object to be used in assertThat statements.

    Classes

    goog.labs.testing.AllOfMatcher
    The AllOf matcher.
    goog.labs.testing.AnyOfMatcher
    The AnyOf matcher.
    goog.labs.testing.CloseToMatcher
    The CloseTo matcher.
    goog.labs.testing.ContainsStringMatcher
    The ContainsString matcher.
    goog.labs.testing.EndsWithMatcher
    The EndsWith matcher.
    goog.labs.testing.EqualToIgnoringWhitespaceMatcher
    The EqualToIgnoringWhitespace matcher.
    goog.labs.testing.EqualToMatcher
    The EqualTo matcher.
    goog.labs.testing.EqualsMatcher
    The Equals matcher.
    goog.labs.testing.GreaterThanEqualToMatcher
    The GreaterThanEqualTo matcher.
    goog.labs.testing.GreaterThanMatcher
    The GreaterThan matcher.
    goog.labs.testing.HasPropertyMatcher
    The HasProperty matcher.
    goog.labs.testing.InstanceOfMatcher
    The InstanceOf matcher.
    goog.labs.testing.IsNotMatcher
    The IsNot matcher.
    goog.labs.testing.IsNullMatcher
    The IsNull matcher.
    goog.labs.testing.IsNullOrUndefinedMatcher
    The IsNullOrUndefined matcher.
    goog.labs.testing.IsUndefinedMatcher
    The IsUndefined matcher.
    goog.labs.testing.LessThanEqualToMatcher
    The LessThanEqualTo matcher.
    goog.labs.testing.LessThanMatcher
    The lessThan matcher.
    goog.labs.testing.MatcherError
    Error thrown when a Matcher fails to match the input value.
    goog.labs.testing.ObjectEqualsMatcher
    The Equals matcher.
    goog.labs.testing.RegexMatcher
    The MatchesRegex matcher.
    goog.labs.testing.StartsWithMatcher
    The StartsWith matcher.
    goog.labs.testing.StringContainsInOrderMatcher
    The StringContainsInOrdermatcher.
    Show:

    Global Functions

    code »goog.labs.testing.assertThat ( actual, matcher, opt_reason )

    Asserts that the actual value evaluated by the matcher is true.

    Parameters
    actual: *
    The object to assert by the matcher.
    matcher: !goog.labs.testing.Matcher
    A matcher to verify values.
    opt_reason: string=
    Description of what is asserted.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent.html b/node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent.html new file mode 100644 index 0000000..1108d07 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent.html @@ -0,0 +1 @@ +goog.labs.userAgent

    Namespace goog.labs.userAgent

    code »
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent_browser.html b/node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent_browser.html new file mode 100644 index 0000000..306bf26 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent_browser.html @@ -0,0 +1,15 @@ +goog.labs.userAgent.browser

    Namespace goog.labs.userAgent.browser

    code »
    Show:

    Global Functions

    Determines IE version. More information: + http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx#uaString + http://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx + http://blogs.msdn.com/b/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx + http://blogs.msdn.com/b/ie/archive/2009/01/09/the-internet-explorer-8-user-agent-string-updated-edition.aspx

    Parameters
    userAgent: string
    the User-Agent.

    Determines Opera version. More information: + http://my.opera.com/ODIN/blog/2013/07/15/opera-user-agent-strings-opera-15-and-beyond

    Parameters
    userAgent: string
    The User-Agent.
    Returns
    The browser version or empty string if version cannot be + determined. Note that for Internet Explorer, this returns the version of + the browser, not the version of the rendering engine. (IE 8 in + compatibility mode will return 8.0 rather than 7.0. To determine the + rendering engine version, look at document.documentMode instead. See + http://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx for more + details.)

    Nearly all User-Agents start with Mozilla/N.0. This looks at the second tuple + for the actual browser version number.

    Parameters
    versionTuples
    Returns
    The version or empty string if it cannot be determined.
    Returns
    Whether the user's browser is the Android browser.
    Returns
    Whether the user's browser is Chrome.
    Returns
    Whether the user's browser is Firefox.
    Returns
    Whether the user's browser is IE.
    Returns
    Whether the user's browser is Opera.
    Returns
    Whether the user's browser is Safari.

    For more information, see: + http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html

    Returns
    Whether the user's browser is Silk.
    Parameters
    version: (string|number)
    The version to check.
    Returns
    Whether the browser version is higher or the same as the + given version.
    Returns
    Whether the user's browser is the Android browser.
    Returns
    Whether the user's browser is Chrome.
    Returns
    Whether the user's browser is Firefox.
    Returns
    Whether the user's browser is IE.
    Returns
    Whether the user's browser is Opera.
    Returns
    Whether the user's browser is Safari.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent_engine.html b/node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent_engine.html new file mode 100644 index 0000000..90ed19b --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent_engine.html @@ -0,0 +1,4 @@ +goog.labs.userAgent.engine

    Namespace goog.labs.userAgent.engine

    code »
    Show:

    Global Functions

    Returns
    The rendering engine's version or empty string if version + can't be determined.
    Parameters
    tuples: !Array
    Version tuples.
    key: string
    The key to look for.
    Returns
    The version string of the given key, if present. + Otherwise, the empty string.
    Returns
    Whether the rendering engine is Gecko.
    Returns
    Whether the rendering engine is Presto.
    Returns
    Whether the rendering engine is Trident.
    Parameters
    version: (string|number)
    The version to check.
    Returns
    Whether the rendering engine version is higher or the same + as the given version.
    Returns
    Whether the rendering engine is WebKit.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent_util.html b/node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent_util.html new file mode 100644 index 0000000..b84a141 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_labs_userAgent_util.html @@ -0,0 +1,9 @@ +goog.labs.userAgent.util

    Namespace goog.labs.userAgent.util

    code »
    Show:

    Global Functions

    Parses the user agent into tuples for each section.

    Parameters
    userAgent
    Returns
    Tuples of key, version, and the contents + of the parenthetical.

    Gets the native userAgent string from navigator if it exists. + If navigator or navigator.userAgent string is missing, returns an empty + string.

    Getter for the native navigator. + This is a separate function so it can be stubbed out in testing.

    Returns
    The user agent string.
    Parameters
    str
    Returns
    Whether the user agent contains the given string, ignoring + case.
    Parameters
    str
    Returns
    Whether the user agent contains the given string.

    Applications may override browser detection on the built in + navigator.userAgent object by setting this string. Set to null to use the + browser object instead.

    Parameters
    opt_userAgent: ?string=
    The User-Agent override.

    Global Properties

    A possible override for applications which wish to not check + navigator.userAgent but use a specified value for detection instead.

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_math.html b/node_modules/selenium-webdriver/docs/namespace_goog_math.html new file mode 100644 index 0000000..7ba748a --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_math.html @@ -0,0 +1,61 @@ +goog.math

    Namespace goog.math

    code »
    Show:

    Global Functions

    code »goog.math.angle ( x1, y1, x2, y2 )number

    Computes the angle between two points (x1,y1) and (x2,y2). + Angle zero points in the +X direction, 90 degrees points in the +Y + direction (down) and from there we grow clockwise towards 360 degrees.

    Parameters
    x1: number
    x of first point.
    y1: number
    y of first point.
    x2: number
    x of second point.
    y2: number
    y of second point.
    Returns
    Standardized angle in degrees of the vector from + x1,y1 to x2,y2.
    code »goog.math.angleDifference ( startAngle, endAngle )number

    Computes the difference between startAngle and endAngle (angles in degrees).

    Parameters
    startAngle: number
    Start angle in degrees.
    endAngle: number
    End angle in degrees.
    Returns
    The number of degrees that when added to + startAngle will result in endAngle. Positive numbers mean that the + direction is clockwise. Negative numbers indicate a counter-clockwise + direction. + The shortest route (clockwise vs counter-clockwise) between the angles + is used. + When the difference is 180 degrees, the function returns 180 (not -180) + angleDifference(30, 40) is 10, and angleDifference(40, 30) is -10. + angleDifference(350, 10) is 20, and angleDifference(10, 350) is -20.
    code »goog.math.angleDx ( degrees, radius )number

    For a given angle and radius, finds the X portion of the offset.

    Parameters
    degrees: number
    Angle in degrees (zero points in +X direction).
    radius: number
    Radius.
    Returns
    The x-distance for the angle and radius.
    code »goog.math.angleDy ( degrees, radius )number

    For a given angle and radius, finds the Y portion of the offset.

    Parameters
    degrees: number
    Angle in degrees (zero points in +X direction).
    radius: number
    Radius.
    Returns
    The y-distance for the angle and radius.

    Returns the arithmetic mean of the arguments.

    Parameters
    var_args: ...number
    Numbers to average.
    Returns
    The average of the arguments (NaN if no arguments + were provided or any of the arguments is not a valid number).
    code »goog.math.clamp ( value, min, max )number

    Takes a number and clamps it to within the provided bounds.

    Parameters
    value: number
    The input number.
    min: number
    The minimum value to return.
    max: number
    The maximum value to return.
    Returns
    The input number if it is within bounds, or the nearest + number within the bounds.

    Returns whether the supplied number is finite and not NaN.

    Parameters
    num: number
    The number to test.
    Returns
    Whether num is a finite number.

    Returns whether the supplied number represents an integer, i.e. that is has + no fractional component. No range-checking is performed on the number.

    Parameters
    num: number
    The number to test.
    Returns
    Whether num is an integer.

    Performs linear interpolation between values a and b. Returns the value + between a and b proportional to x (when x is between 0 and 1. When x is + outside this range, the return value is a linear extrapolation).

    Parameters
    a: number
    A number.
    b: number
    A number.
    x: number
    The proportion between a and b.
    Returns
    The interpolated value between a and b.

    Returns the precise value of floor(log10(num)). + Simpler implementations didn't work because of floating point rounding + errors. For example +

      +
    • Math.floor(Math.log(num) / Math.LN10) is off by one for num == 1e+3. +
    • Math.floor(Math.log(num) * Math.LOG10E) is off by one for num == 1e+15. +
    • Math.floor(Math.log10(num)) is off by one for num == 1e+15 - 1. +
    Parameters
    num: number
    A floating point number.
    Returns
    Its logarithm to base 10 rounded down to the nearest + integer if num > 0. -Infinity if num == 0. NaN if num < 0.
    code »goog.math.longestCommonSubsequence ( array1, array2, opt_compareFn, opt_collectorFn )!Array.<Object>

    JavaScript implementation of Longest Common Subsequence problem. + http://en.wikipedia.org/wiki/Longest_common_subsequence + + Returns the longest possible array that is subarray of both of given arrays.

    Parameters
    array1: Array.<Object>
    First array of objects.
    array2: Array.<Object>
    Second array of objects.
    opt_compareFn: Function=
    Function that acts as a custom comparator + for the array ojects. Function should return true if objects are equal, + otherwise false.
    opt_collectorFn: Function=
    Function used to decide what to return + as a result subsequence. It accepts 2 arguments: index of common element + in the first array and index in the second. The default function returns + element from the first array.
    Returns
    A list of objects that are common to both arrays + such that there is no common subsequence with size greater than the + length of the list.

    The % operator in JavaScript returns the remainder of a / b, but differs from + some other languages in that the result will have the same sign as the + dividend. For example, -1 % 8 == -1, whereas in some other languages + (such as Python) the result would be 7. This function emulates the more + correct modulo behavior, which is useful for certain applications such as + calculating an offset index in a circular list.

    Parameters
    a: number
    The dividend.
    b: number
    The divisor.
    Returns
    a % b where the result is between 0 and b (either 0 <= x < b + or b < x <= 0, depending on the sign of b).
    code »goog.math.nearlyEquals ( a, b, opt_tolerance )boolean

    Tests whether the two values are equal to each other, within a certain + tolerance to adjust for floating point errors.

    Parameters
    a: number
    A number.
    b: number
    A number.
    opt_tolerance: number=
    Optional tolerance range. Defaults + to 0.000001. If specified, should be greater than 0.
    Returns
    Whether a and b are nearly equal.

    Returns a random integer greater than or equal to 0 and less than a.

    Parameters
    a: number
    The upper bound for the random integer (exclusive).
    Returns
    A random integer N such that 0 <= N < a.
    code »goog.math.safeCeil ( num, opt_epsilon )number

    A tweaked variant of Math.ceil. See goog.math.safeFloor for + details.

    Parameters
    num: number
    A number.
    opt_epsilon: number=
    An infinitesimally small positive number, the + rounding error to tolerate.
    Returns
    The smallest integer greater than or equal to num.
    code »goog.math.safeFloor ( num, opt_epsilon )number

    A tweaked variant of Math.floor which tolerates if the passed number + is infinitesimally smaller than the closest integer. It often happens with + the results of floating point calculations because of the finite precision + of the intermediate results. For example Math.floor(Math.log(1000) / + Math.LN10) == 2, not 3 as one would expect.

    Parameters
    num: number
    A number.
    opt_epsilon: number=
    An infinitesimally small positive number, the + rounding error to tolerate.
    Returns
    The largest integer less than or equal to num.

    Returns the unbiased sample variance of the arguments. For a definition, + see e.g. http://en.wikipedia.org/wiki/Variance

    Parameters
    var_args: ...number
    Number samples to analyze.
    Returns
    The unbiased sample variance of the arguments (0 if fewer + than two samples were provided, or NaN if any of the samples is + not a valid number).

    Returns the sign of a number as per the "sign" or "signum" function.

    Parameters
    x: number
    The number to take the sign of.
    Returns
    -1 when negative, 1 when positive, 0 when 0.

    Normalizes an angle to be in range [0-360). Angles outside this range will + be normalized to be the equivalent angle with that range.

    Parameters
    angle: number
    Angle in degrees.
    Returns
    Standardized angle.

    Normalizes an angle to be in range [0-2*PI). Angles outside this range will + be normalized to be the equivalent angle with that range.

    Parameters
    angle: number
    Angle in radians.
    Returns
    Standardized angle.

    Returns the sample standard deviation of the arguments. For a definition of + sample standard deviation, see e.g. + http://en.wikipedia.org/wiki/Standard_deviation

    Parameters
    var_args: ...number
    Number samples to analyze.
    Returns
    The sample standard deviation of the arguments (0 if fewer + than two samples were provided, or NaN if any of the samples is + not a valid number).
    code »goog.math.sum ( var_args )number

    Returns the sum of the arguments.

    Parameters
    var_args: ...number
    Numbers to add.
    Returns
    The sum of the arguments (0 if no arguments were provided, + NaN if any of the arguments is not a valid number).
    code »goog.math.toDegrees ( angleRadians )number

    Converts radians to degrees.

    Parameters
    angleRadians: number
    Angle in radians.
    Returns
    Angle in degrees.
    code »goog.math.toRadians ( angleDegrees )number

    Converts degrees to radians.

    Parameters
    angleDegrees: number
    Angle in degrees.
    Returns
    Angle in radians.

    Returns a random number greater than or equal to a and less than + b.

    Parameters
    a: number
    The lower bound for the random number (inclusive).
    b: number
    The upper bound for the random number (exclusive).
    Returns
    A random number N such that a <= N < b.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_net.html b/node_modules/selenium-webdriver/docs/namespace_goog_net.html new file mode 100644 index 0000000..a8e5b1d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_net.html @@ -0,0 +1 @@ +goog.net

    Namespace goog.net

    code »

    Interfaces

    goog.net.XhrLike
    Interface for the common parts of XMLHttpRequest.

    Classes

    goog.net.DefaultXmlHttpFactory
    Default factory to use when creating xhr objects.
    goog.net.WrapperXmlHttpFactory
    An xhr factory subclass which can be constructed using two factory methods.
    goog.net.XmlHttpFactory
    Abstract base class for an XmlHttpRequest factory.
    Show:

    Global Functions

    Static class for creating XMLHttpRequest objects.

    Returns
    A new XMLHttpRequest object.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_net_XmlHttp.html b/node_modules/selenium-webdriver/docs/namespace_goog_net_XmlHttp.html new file mode 100644 index 0000000..e116d89 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_net_XmlHttp.html @@ -0,0 +1,4 @@ +goog.net.XmlHttp

    Namespace goog.net.XmlHttp

    code »

    Static class for creating XMLHttpRequest objects.

    Main

    XmlHttp ( )!goog.net.XhrLike.OrNative
    Returns
    A new XMLHttpRequest object.

    Enumerations

    goog.net.XmlHttp.OptionType
    Type of options that an XmlHttp object can have.
    goog.net.XmlHttp.ReadyState
    Status constants for XMLHTTP, matches: + http://msdn.microsoft.com/library/default.asp?url=/library/ + en-us/xmlsdk/html/0e6a34e4-f90c-489d-acff-cb44242fafc6.asp
    Show:

    Global Functions

    Gets the options to use with the XMLHttpRequest objects obtained using + the static methods.

    Returns
    The options.
    code »goog.net.XmlHttp.setFactory ( factory, optionsFactory )
    Deprecated: Use setGlobalFactory instead.

    Sets the factories for creating XMLHttpRequest objects and their options.

    Parameters
    factory: Function
    The factory for XMLHttpRequest objects.
    optionsFactory: Function
    The factory for options.

    Sets the global factory object.

    Parameters
    factory: !goog.net.XmlHttpFactory
    New global factory object.

    Global Properties

    The global factory instance for creating XMLHttpRequest objects.

    Compiler Constants

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_net_XmlHttpDefines.html b/node_modules/selenium-webdriver/docs/namespace_goog_net_XmlHttpDefines.html new file mode 100644 index 0000000..eaedceb --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_net_XmlHttpDefines.html @@ -0,0 +1 @@ +goog.net.XmlHttpDefines

    Namespace goog.net.XmlHttpDefines

    code »
    Show:

    Compiler Constants

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_object.html b/node_modules/selenium-webdriver/docs/namespace_goog_object.html new file mode 100644 index 0000000..11a0649 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_object.html @@ -0,0 +1,77 @@ +goog.object

    Namespace goog.object

    code »
    Show:

    Global Functions

    code »<K, V> goog.object.add ( obj, key, val )

    Adds a key-value pair to the object. Throws an exception if the key is + already in use. Use set if you want to change an existing pair.

    Parameters
    obj: Object.<K, V>
    The object to which to add the key-value pair.
    key: string
    The key to add.
    val: V
    The value to add.

    Removes all key value pairs from the object/map/hash.

    Parameters
    obj: Object
    The object to clear.
    code »<K, V> goog.object.clone ( obj )!Object.<K, V>

    Does a flat clone of the object.

    Parameters
    obj: Object.<K, V>
    Object to clone.
    Returns
    Clone of the input object.
    code »<K, V> goog.object.contains ( obj, val )boolean

    Whether the object/hash/map contains the given object as a value. + An alias for goog.object.containsValue(obj, val).

    Parameters
    obj: Object.<K, V>
    The object in which to look for val.
    val: V
    The object for which to check.
    Returns
    true if val is present.

    Whether the object/map/hash contains the given key.

    Parameters
    obj: Object
    The object in which to look for key.
    key: *
    The key for which to check.
    Returns
    true If the map contains the key.

    Whether the object/map/hash contains the given value. This is O(n).

    Parameters
    obj: Object.<K, V>
    The object in which to look for val.
    val: V
    The value for which to check.
    Returns
    true If the map contains the value.

    Creates a new object built from the key-value pairs provided as arguments.

    Parameters
    var_args: ...*
    If only one argument is provided and it is an array + then this is used as the arguments, otherwise even arguments are used as + the property names and odd arguments are used as the property values.
    Returns
    The new object.
    Throws
    Error
    If there are uneven number of arguments or there is only one + non array argument.

    Creates an immutable view of the underlying object, if the browser + supports immutable objects. + + In default mode, writes to this view will fail silently. In strict mode, + they will throw an error.

    Parameters
    obj: !Object.<K, V>
    An object.
    Returns
    An immutable view of that object, or the + original object if this browser does not support immutables.

    Creates a new object where the property names come from the arguments but + the value is always set to true

    Parameters
    var_args: ...*
    If only one argument is provided and it is an array + then this is used as the arguments, otherwise the arguments are used + as the property names.
    Returns
    The new object.
    code »<T, K, V> goog.object.every ( obj, f, opt_obj )boolean

    Calls a function for each element in an object/map/hash. If + all calls return true, returns true. If any call returns false, returns + false at this point and does not continue to check the remaining elements.

    Parameters
    obj: Object.<K, V>
    The object to check.
    f: ?function(this: T, V, ?, Object.<K, V>): boolean
    The function to + call for every element. This function + takes 3 arguments (the element, the index and the object) and should + return a boolean.
    opt_obj: T=
    This is used as the 'this' object within f.
    Returns
    false if any element fails the test.
    code »goog.object.extend ( target, var_args )

    Extends an object with another object. + This operates 'in-place'; it does not create a new Object. + + Example: + var o = {}; + goog.object.extend(o, {a: 0, b: 1}); + o; // {a: 0, b: 1} + goog.object.extend(o, {b: 2, c: 3}); + o; // {a: 0, b: 2, c: 3}

    Parameters
    target: Object
    The object to modify. Existing properties will be + overwritten if they are also present in one of the objects in + var_args.
    var_args: ...Object
    The objects from which values will be copied.
    code »<T, K, V> goog.object.filter ( obj, f, opt_obj )!Object.<K, V>

    Calls a function for each element in an object/map/hash. If that call returns + true, adds the element to a new object.

    Parameters
    obj: Object.<K, V>
    The object over which to iterate.
    f: function(this: T, V, ?, Object.<K, V>): boolean
    The function to call + for every element. This + function takes 3 arguments (the element, the index and the object) + and should return a boolean. If the return value is true the + element is added to the result object. If it is false the + element is not included.
    opt_obj: T=
    This is used as the 'this' object within f.
    Returns
    a new object in which only elements that passed the + test are present.
    code »<T, K, V> goog.object.findKey ( obj, f, opt_this )(string|undefined)

    Searches an object for an element that satisfies the given condition and + returns its key.

    Parameters
    obj: Object.<K, V>
    The object to search in.
    f: function(this: T, V, string, Object.<K, V>): boolean
    The + function to call for every element. Takes 3 arguments (the value, + the key and the object) and should return a boolean.
    opt_this: T=
    An optional "this" context for the function.
    Returns
    The key of an element for which the function + returns true or undefined if no such element is found.
    code »<T, K, V> goog.object.findValue ( obj, f, opt_this )V

    Searches an object for an element that satisfies the given condition and + returns its value.

    Parameters
    obj: Object.<K, V>
    The object to search in.
    f: function(this: T, V, string, Object.<K, V>): boolean
    The function + to call for every element. Takes 3 arguments (the value, the key + and the object) and should return a boolean.
    opt_this: T=
    An optional "this" context for the function.
    Returns
    The value of an element for which the function returns true or + undefined if no such element is found.
    code »<T, K, V> goog.object.forEach ( obj, f, opt_obj )

    Calls a function for each element in an object/map/hash.

    Parameters
    obj: Object.<K, V>
    The object over which to iterate.
    f: function(this: T, V, ?, Object.<K, V>): ?
    The function to call + for every element. This function takes 3 arguments (the element, the + index and the object) and the return value is ignored.
    opt_obj: T=
    This is used as the 'this' object within f.
    code »<K, V, R> goog.object.get ( obj, key, opt_val )(V|R|undefined)

    Returns the value for the given key.

    Parameters
    obj: Object.<K, V>
    The object from which to get the value.
    key: string
    The key for which to get the value.
    opt_val: R=
    The value to return if no item is found for the given + key (default is undefined).
    Returns
    The value for the given key.

    Returns one key from the object map, if any exists. + For map literals the returned key will be the first one in most of the + browsers (a know exception is Konqueror).

    Parameters
    obj: Object
    The object to pick a key from.
    Returns
    The key or undefined if the object is empty.

    Returns one value from the object map, if any exists. + For map literals the returned value will be the first one in most of the + browsers (a know exception is Konqueror).

    Parameters
    obj: Object.<K, V>
    The object to pick a value from.
    Returns
    The value or undefined if the object is empty.

    Returns the number of key-value pairs in the object map.

    Parameters
    obj: Object
    The object for which to get the number of key-value + pairs.
    Returns
    The number of key-value pairs in the object map.

    Returns the keys of the object/map/hash.

    Parameters
    obj: Object
    The object from which to get the keys.
    Returns
    Array of property keys.
    code »goog.object.getValueByKeys ( obj, var_args )*

    Get a value from an object multiple levels deep. This is useful for + pulling values from deeply nested objects, such as JSON responses. + Example usage: getValueByKeys(jsonObj, 'foo', 'entries', 3)

    Parameters
    obj: !Object
    An object to get the value from. Can be array-like.
    var_args: ...(string|number|!Array)
    A number of keys + (as strings, or numbers, for array-like objects). Can also be + specified as a single array of keys.
    Returns
    The resulting value. If, at any point, the value for a key + is undefined, returns undefined.
    code »<K, V> goog.object.getValues ( obj )!Array.<V>

    Returns the values of the object/map/hash.

    Parameters
    obj: Object.<K, V>
    The object from which to get the values.
    Returns
    The values in the object/map/hash.

    Whether the object/map/hash is empty.

    Parameters
    obj: Object
    The object to test.
    Returns
    true if obj is empty.
    Parameters
    obj: !Object
    An object.
    Returns
    Whether this is an immutable view of the object.
    code »<T, K, V, R> goog.object.map ( obj, f, opt_obj )!Object.<K, R>

    For every element in an object/map/hash calls a function and inserts the + result into a new object.

    Parameters
    obj: Object.<K, V>
    The object over which to iterate.
    f: function(this: T, V, ?, Object.<K, V>): R
    The function to call + for every element. This function + takes 3 arguments (the element, the index and the object) + and should return something. The result will be inserted + into a new object.
    opt_obj: T=
    This is used as the 'this' object within f.
    Returns
    a new object with the results from f.

    Removes a key-value pair based on the key.

    Parameters
    obj: Object
    The object from which to remove the key.
    key: *
    The key to remove.
    Returns
    Whether an element was removed.
    code »<K, V> goog.object.set ( obj, key, value )

    Adds a key-value pair to the object/map/hash.

    Parameters
    obj: Object.<K, V>
    The object to which to add the key-value pair.
    key: string
    The key to add.
    value: V
    The value to add.
    code »<K, V> goog.object.setIfUndefined ( obj, key, value )V

    Adds a key-value pair to the object/map/hash if it doesn't exist yet.

    Parameters
    obj: Object.<K, V>
    The object to which to add the key-value pair.
    key: string
    The key to add.
    value: V
    The value to add if the key wasn't present.
    Returns
    The value of the entry at the end of the function.
    code »<T, K, V> goog.object.some ( obj, f, opt_obj )boolean

    Calls a function for each element in an object/map/hash. If any + call returns true, returns true (without checking the rest). If + all calls return false, returns false.

    Parameters
    obj: Object.<K, V>
    The object to check.
    f: function(this: T, V, ?, Object.<K, V>): boolean
    The function to + call for every element. This function + takes 3 arguments (the element, the index and the object) and should + return a boolean.
    opt_obj: T=
    This is used as the 'this' object within f.
    Returns
    true if any element passes the test.

    Returns a new object in which all the keys and values are interchanged + (keys become values and values become keys). If multiple keys map to the + same value, the chosen transposed value is implementation-dependent.

    Parameters
    obj: Object
    The object to transpose.
    Returns
    The transposed object.

    Clones a value. The input may be an Object, Array, or basic type. Objects and + arrays will be cloned recursively. + + WARNINGS: + goog.object.unsafeClone does not detect reference loops. Objects + that refer to themselves will cause infinite recursion. + + goog.object.unsafeClone is unaware of unique identifiers, and + copies UIDs created by getUid into cloned results.

    Parameters
    obj: *
    The value to clone.
    Returns
    A clone of the input value.

    Global Properties

    The names of the fields that are defined on Object.prototype.

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_string.html b/node_modules/selenium-webdriver/docs/namespace_goog_string.html new file mode 100644 index 0000000..3ccce5b --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_string.html @@ -0,0 +1,188 @@ +goog.string

    Namespace goog.string

    code »

    Enumerations

    goog.string.Unicode
    Common Unicode string characters.
    Show:

    Global Functions

    Concatenates string expressions. This is useful + since some browsers are very inefficient when it comes to using plus to + concat strings. Be careful when using null and undefined here since + these will not be included in the result. If you need to represent these + be sure to cast the argument to a String first. + For example: +

    buildString('a', 'b', 'c', 'd') -> 'abcd'
    + buildString(null, undefined) -> ''
    + 
    Parameters
    var_args: ...*
    A list of strings to concatenate. If not a string, + it will be casted to one.
    Returns
    The concatenation of var_args.

    Replaces Windows and Mac new lines with unix style: \r or \r\n with \n.

    Parameters
    str: string
    The string to in which to canonicalize newlines.
    Returns
    str A copy of {@code} with canonicalized newlines.

    A string comparator that ignores case. + -1 = str1 less than str2 + 0 = str1 equals str2 + 1 = str1 greater than str2

    Parameters
    str1: string
    The string to compare.
    str2: string
    The string to compare str1 to.
    Returns
    The comparator result, as described above.

    Determines whether a string contains a substring, ignoring case.

    Parameters
    str: string
    The string to search.
    subString: string
    The substring to search for.
    Returns
    Whether str contains subString.

    Case-insensitive suffix-checker.

    Parameters
    str: string
    The string to check.
    suffix: string
    A string to look for at the end of str.
    Returns
    True if str ends with suffix (ignoring + case).

    Case-insensitive equality checker.

    Parameters
    str1: string
    First string to check.
    str2: string
    Second string to check.
    Returns
    True if str1 and str2 are the same string, + ignoring case.

    Case-insensitive prefix-checker.

    Parameters
    str: string
    The string to check.
    prefix: string
    A string to look for at the end of str.
    Returns
    True if str begins with prefix (ignoring + case).

    Removes the breaking spaces from the left and right of the string and + collapses the sequences of breaking spaces in the middle into single spaces. + The original and the result strings render the same way in HTML.

    Parameters
    str: string
    A string in which to collapse spaces.
    Returns
    Copy of the string with normalized breaking spaces.

    Converts multiple whitespace chars (spaces, non-breaking-spaces, new lines + and tabs) to a single space, and strips leading and trailing whitespace.

    Parameters
    str: string
    Input string.
    Returns
    A copy of str with collapsed whitespace.

    Compares elements of a version number.

    Parameters
    left: (string|number|boolean)
    An element from a version number.
    right: (string|number|boolean)
    An element from a version number.
    Returns
    1 if left is higher. + 0 if arguments are equal. + -1 if right is higher.
    code »goog.string.compareVersions ( version1, version2 )number

    Compares two version numbers.

    Parameters
    version1: (string|number)
    Version of first item.
    version2: (string|number)
    Version of second item.
    Returns
    1 if version1 is higher. + 0 if arguments are equal. + -1 if version2 is higher.
    code »goog.string.contains ( str, subString )boolean

    Determines whether a string contains a substring.

    Parameters
    str: string
    The string to search.
    subString: string
    The substring to search for.
    Returns
    Whether str contains subString.

    Returns the non-overlapping occurrences of ss in s. + If either s or ss evalutes to false, then returns zero.

    Parameters
    s: string
    The string to look in.
    ss: string
    The string to look for.
    Returns
    Number of occurrences of ss in s.

    Generates and returns a string which is unique in the current document. + This is useful, for example, to create unique IDs for DOM elements.

    Returns
    A unique id.

    Fast suffix-checker.

    Parameters
    str: string
    The string to check.
    suffix: string
    A string to look for at the end of str.
    Returns
    True if str ends with suffix.

    Takes a character and returns the escaped string for that character. For + example escapeChar(String.fromCharCode(15)) -> "\\x0E".

    Parameters
    c: string
    The character to escape.
    Returns
    An escaped string representing c.

    Takes a string and returns the escaped string for that character.

    Parameters
    str: string
    The string to escape.
    Returns
    An escaped string representing str.

    Returns a string with at least 64-bits of randomness. + + Doesn't trust Javascript's random function entirely. Uses a combination of + random and current timestamp, and then encodes the string in base-36 to + make it shorter.

    Returns
    A random string, e.g. sn1s7vb4gcic.

    String hash function similar to java.lang.String.hashCode(). + The hash code for a string is computed as + s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1], + where s[i] is the ith character of the string and n is the length of + the string. We mod the result to make it between 0 (inclusive) and 2^32 + (exclusive).

    Parameters
    str: string
    A string.
    Returns
    Hash value for str, between 0 (inclusive) and 2^32 + (exclusive). The empty string returns 0.
    code »goog.string.htmlEscape ( str, opt_isLikelyToContainHtmlChars )string

    Escapes double quote '"' and single quote '\'' characters in addition to + '&', '<', and '>' so that a string can be included in an HTML tag attribute + value within double or single quotes. + + It should be noted that > doesn't need to be escaped for the HTML or XML to + be valid, but it has been decided to escape it for consistency with other + implementations. + + With goog.string.DETECT_DOUBLE_ESCAPING, this function escapes also the + lowercase letter "e". + + NOTE(user): + HtmlEscape is often called during the generation of large blocks of HTML. + Using statics for the regular expressions and strings is an optimization + that can more than half the amount of time IE spends in this function for + large apps, since strings and regexes both contribute to GC allocations. + + Testing for the presence of a character before escaping increases the number + of function calls, but actually provides a speed increase for the average + case -- since the average case often doesn't require the escaping of all 4 + characters and indexOf() is much cheaper than replace(). + The worst case does suffer slightly from the additional calls, therefore the + opt_isLikelyToContainHtmlChars option has been included for situations + where all 4 HTML entities are very likely to be present and need escaping. + + Some benchmarks (times tended to fluctuate +-0.05ms): + FireFox IE6 + (no chars / average (mix of cases) / all 4 chars) + no checks 0.13 / 0.22 / 0.22 0.23 / 0.53 / 0.80 + indexOf 0.08 / 0.17 / 0.26 0.22 / 0.54 / 0.84 + indexOf + re test 0.07 / 0.17 / 0.28 0.19 / 0.50 / 0.85 + + An additional advantage of checking if replace actually needs to be called + is a reduction in the number of object allocations, so as the size of the + application grows the difference between the various methods would increase.

    Parameters
    str: string
    string to be escaped.
    opt_isLikelyToContainHtmlChars: boolean=
    Don't perform a check to see + if the character needs replacing - use this option if you expect each of + the characters to appear often. Leave false if you expect few html + characters to occur in your strings, such as if you are escaping HTML.
    Returns
    An escaped copy of str.

    Checks if a string contains all letters.

    Parameters
    str: string
    string to check.
    Returns
    True if str consists entirely of letters.

    Checks if a string contains only numbers or letters.

    Parameters
    str: string
    string to check.
    Returns
    True if str is alphanumeric.

    Checks if a string is all breaking whitespace.

    Parameters
    str: string
    The string to check.
    Returns
    Whether the string is all breaking whitespace.

    Checks if a string is empty or contains only whitespaces.

    Parameters
    str: string
    The string to check.
    Returns
    True if str is empty or whitespace only.

    Checks if a string is null, undefined, empty or contains only whitespaces.

    Parameters
    str: *
    The string to check.
    Returns
    True ifstr is null, undefined, empty, or + whitespace only.

    Returns whether the given string is lower camel case (e.g. "isFooBar"). + + Note that this assumes the string is entirely letters.

    Parameters
    str: string
    String to test.
    Returns
    Whether the string is lower camel case.

    Checks if a string contains only numbers.

    Parameters
    str: *
    string to check. If not a string, it will be + casted to one.
    Returns
    True if str is numeric.

    Checks if a character is a space character.

    Parameters
    ch: string
    Character to check.
    Returns
    True if {code ch} is a space.

    Checks if a character is a valid unicode character.

    Parameters
    ch: string
    Character to check.
    Returns
    True if {code ch} is a valid unicode character.

    Returns whether the given string is upper camel case (e.g. "FooBarBaz"). + + Note that this assumes the string is entirely letters.

    Parameters
    str: string
    String to test.
    Returns
    Whether the string is upper camel case.

    Returns a string representation of the given object, with + null and undefined being returned as the empty string.

    Parameters
    obj: *
    The object to convert.
    Returns
    A string representation of the obj.

    Converts \n to
    s or
    s.

    Parameters
    str: string
    The string in which to convert newlines.
    opt_xml: boolean=
    Whether to use XML compatible tags.
    Returns
    A copy of str with converted newlines.

    Normalizes spaces in a string, replacing all consecutive spaces and tabs + with a single space. Replaces non-breaking space with a space.

    Parameters
    str: string
    The string in which to normalize spaces.
    Returns
    A copy of str with all consecutive spaces and tabs + replaced with a single space.

    Normalizes whitespace in a string, replacing all whitespace chars with + a space.

    Parameters
    str: string
    The string in which to normalize whitespace.
    Returns
    A copy of str with all whitespace normalized.

    String comparison function that handles numbers in a way humans might expect. + Using this function, the string "File 2.jpg" sorts before "File 10.jpg". The + comparison is mostly case-insensitive, though strings that are identical + except for case are sorted with the upper-case strings before lower-case. + + This comparison function is significantly slower (about 500x) than either + the default or the case-insensitive compare. It should not be used in + time-critical code, but should be fast enough to sort several hundred short + strings (like filenames) with a reasonable delay.

    Parameters
    str1: string
    The string to compare in a numerically sensitive way.
    str2: string
    The string to compare str1 to.
    Returns
    less than 0 if str1 < str2, 0 if str1 == str2, greater than + 0 if str1 > str2.
    code »goog.string.padNumber ( num, length, opt_precision )string

    Pads number to given length and optionally rounds it to a given precision. + For example: +

    padNumber(1.25, 2, 3) -> '01.250'
    + padNumber(1.25, 2) -> '01.25'
    + padNumber(1.25, 2, 1) -> '01.3'
    + padNumber(1.25, 0) -> '1.25'
    Parameters
    num: number
    The number to pad.
    length: number
    The desired length.
    opt_precision: number=
    The desired precision.
    Returns
    num as a string with the given options.

    Parse a string in decimal or hexidecimal ('0xFFFF') form. + + To parse a particular radix, please use parseInt(string, radix) directly. See + https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/parseInt + + This is a wrapper for the built-in parseInt function that will only parse + numbers as base 10 or base 16. Some JS implementations assume strings + starting with "0" are intended to be octal. ES3 allowed but discouraged + this behavior. ES5 forbids it. This function emulates the ES5 behavior. + + For more information, see Mozilla JS Reference: http://goo.gl/8RiFj

    Parameters
    value: (string|number|null|undefined)
    The value to be parsed.
    Returns
    The number, parsed. If the string failed to parse, this + will be NaN.

    Preserve spaces that would be otherwise collapsed in HTML by replacing them + with non-breaking space Unicode characters.

    Parameters
    str: string
    The string in which to preserve whitespace.
    Returns
    A copy of str with preserved whitespace.

    Encloses a string in double quotes and escapes characters so that the + string is a valid JS string.

    Parameters
    s: string
    The string to quote.
    Returns
    A copy of s surrounded by double quotes.

    Escapes characters in the string that are not safe to use in a RegExp.

    Parameters
    s: *
    The string to escape. If not a string, it will be casted + to one.
    Returns
    A RegExp safe, escaped copy of s.

    Removes the first occurrence of a substring from a string.

    Parameters
    s: string
    The base string from which to remove.
    ss: string
    The string to remove.
    Returns
    A copy of s with ss removed or the full + string if nothing is removed.

    Removes all occurrences of a substring from a string.

    Parameters
    s: string
    The base string from which to remove.
    ss: string
    The string to remove.
    Returns
    A copy of s with ss removed or the full + string if nothing is removed.
    code »goog.string.removeAt ( s, index, stringLength )string

    Removes a substring of a specified length at a specific + index in a string.

    Parameters
    s: string
    The base string from which to remove.
    index: number
    The index at which to remove the substring.
    stringLength: number
    The length of the substring to remove.
    Returns
    A copy of s with the substring removed or the full + string if nothing is removed or the input is invalid.
    code »goog.string.repeat ( string, length )string

    Repeats a string n times.

    Parameters
    string: string
    The string to repeat.
    length: number
    The number of times to repeat.
    Returns
    A string containing length repetitions of + string.
    code »goog.string.splitLimit ( str, separator, limit )!Array.<string>

    Splits a string on a separator a limited number of times. + + This implementation is more similar to Python or Java, where the limit + parameter specifies the maximum number of splits rather than truncating + the number of results. + + See http://docs.python.org/2/library/stdtypes.html#str.split + See JavaDoc: http://goo.gl/F2AsY + See Mozilla reference: http://goo.gl/dZdZs

    Parameters
    str: string
    String to split.
    separator: string
    The separator.
    limit: number
    The limit to the number of splits. The resulting array + will have a maximum length of limit+1. Negative numbers are the same + as zero.
    Returns
    The string, split.

    Fast prefix-checker.

    Parameters
    str: string
    The string to check.
    prefix: string
    A string to look for at the start of str.
    Returns
    True if str begins with prefix.

    Takes a string and replaces newlines with a space. Multiple lines are + replaced with a single space.

    Parameters
    str: string
    The string from which to strip newlines.
    Returns
    A copy of str stripped of newlines.
    code »goog.string.stripQuotes ( str, quoteChars )string

    Strip quote characters around a string. The second argument is a string of + characters to treat as quotes. This can be a single character or a string of + multiple character and in that case each of those are treated as possible + quote characters. For example: + +

    + goog.string.stripQuotes('"abc"', '"`') --> 'abc'
    + goog.string.stripQuotes('`abc`', '"`') --> 'abc'
    + 
    Parameters
    str: string
    The string to strip.
    quoteChars: string
    The quote characters to strip.
    Returns
    A copy of str without the quotes.
    code »goog.string.subs ( str, var_args )string

    Does simple python-style string substitution. + subs("foo%s hot%s", "bar", "dog") becomes "foobar hotdog".

    Parameters
    str: string
    The string containing the pattern.
    var_args: ...*
    The items to substitute into the pattern.
    Returns
    A copy of str in which each occurrence of + %s has been replaced an argument from var_args.

    Converts a string from selector-case to camelCase (e.g. from + "multi-part-string" to "multiPartString"), useful for converting + CSS selectors and HTML dataset keys to their equivalent JS properties.

    Parameters
    str: string
    The string in selector-case form.
    Returns
    The string in camelCase form.

    Takes a string and creates a map (Object) in which the keys are the + characters in the string. The value for the key is set to true. You can + then use goog.object.map or goog.array.map to change the values.

    Parameters
    s: string
    The string to build the map from.
    Returns
    The map of characters used.

    Converts the supplied string to a number, which may be Infinity or NaN. + This function strips whitespace: (toNumber(' 123') === 123) + This function accepts scientific notation: (toNumber('1e1') === 10) + + This is better than Javascript's built-in conversions because, sadly: + (Number(' ') === 0) and (parseFloat('123a') === 123)

    Parameters
    str: string
    The string to convert.
    Returns
    The number the supplied string represents, or NaN.

    Converts a string from camelCase to selector-case (e.g. from + "multiPartString" to "multi-part-string"), useful for converting JS + style and dataset properties to equivalent CSS selectors and HTML keys.

    Parameters
    str: string
    The string in camelCase form.
    Returns
    The string in selector-case form.
    code »goog.string.toTitleCase ( str, opt_delimiters )string

    Converts a string into TitleCase. First character of the string is always + capitalized in addition to the first letter of every subsequent word. + Words are delimited by one or more whitespaces by default. Custom delimiters + can optionally be specified to replace the default, which doesn't preserve + whitespace delimiters and instead must be explicitly included if needed. + + Default delimiter => " ": + goog.string.toTitleCase('oneTwoThree') => 'OneTwoThree' + goog.string.toTitleCase('one two three') => 'One Two Three' + goog.string.toTitleCase(' one two ') => ' One Two ' + goog.string.toTitleCase('one_two_three') => 'One_two_three' + goog.string.toTitleCase('one-two-three') => 'One-two-three' + + Custom delimiter => "_-.": + goog.string.toTitleCase('oneTwoThree', '_-.') => 'OneTwoThree' + goog.string.toTitleCase('one two three', '_-.') => 'One two three' + goog.string.toTitleCase(' one two ', '_-.') => ' one two ' + goog.string.toTitleCase('one_two_three', '_-.') => 'One_Two_Three' + goog.string.toTitleCase('one-two-three', '_-.') => 'One-Two-Three' + goog.string.toTitleCase('one...two...three', '_-.') => 'One...Two...Three' + goog.string.toTitleCase('one. two. three', '_-.') => 'One. two. three' + goog.string.toTitleCase('one-two.three', '_-.') => 'One-Two.Three'

    Parameters
    str: string
    String value in camelCase form.
    opt_delimiters: string=
    Custom delimiter character set used to + distinguish words in the string value. Each character represents a + single delimiter. When provided, default whitespace delimiter is + overridden and must be explicitly included if needed.
    Returns
    String value in TitleCase form.

    Trims white spaces to the left and right of a string.

    Parameters
    str: string
    The string to trim.
    Returns
    A trimmed copy of str.

    Trims whitespaces at the left end of a string.

    Parameters
    str: string
    The string to left trim.
    Returns
    A trimmed copy of str.

    Trims whitespaces at the right end of a string.

    Parameters
    str: string
    The string to right trim.
    Returns
    A trimmed copy of str.
    code »goog.string.truncate ( str, chars, opt_protectEscapedCharacters )string

    Truncates a string to a certain length and adds '...' if necessary. The + length also accounts for the ellipsis, so a maximum length of 10 and a string + 'Hello World!' produces 'Hello W...'.

    Parameters
    str: string
    The string to truncate.
    chars: number
    Max number of characters.
    opt_protectEscapedCharacters: boolean=
    Whether to protect escaped + characters from being cut off in the middle.
    Returns
    The truncated str string.
    code »goog.string.truncateMiddle ( str, chars, opt_protectEscapedCharacters, opt_trailingChars )string

    Truncate a string in the middle, adding "..." if necessary, + and favoring the beginning of the string.

    Parameters
    str: string
    The string to truncate the middle of.
    chars: number
    Max number of characters.
    opt_protectEscapedCharacters: boolean=
    Whether to protect escaped + characters from being cutoff in the middle.
    opt_trailingChars: number=
    Optional number of trailing characters to + leave at the end of the string, instead of truncating as close to the + middle as possible.
    Returns
    A truncated copy of str.

    Unescapes an HTML string.

    Parameters
    str: string
    The string to unescape.
    Returns
    An unescaped copy of str.

    Unescapes an HTML string using a DOM to resolve non-XML, non-numeric + entities. This function is XSS-safe and whitespace-preserving.

    Parameters
    str: string
    The string to unescape.
    opt_document: Document=
    An optional document to use for creating + elements. If this is not specified then the default window.document + will be used.
    Returns
    The unescaped str string.

    Unescapes a HTML string using the provided document.

    Parameters
    str: string
    The string to unescape.
    document: !Document
    A document to use in escaping the string.
    Returns
    An unescaped copy of str.

    Unescapes XML entities.

    Parameters
    str: string
    The string to unescape.
    Returns
    An unescaped copy of str.

    URL-decodes the string. We need to specially handle '+'s because + the javascript library doesn't convert them to spaces.

    Parameters
    str: string
    The string to url decode.
    Returns
    The decoded str.

    URL-encodes a string

    Parameters
    str: *
    The string to url-encode.
    Returns
    An encoded copy of str that is safe for urls. + Note that '#', ':', and other characters used to delimit portions + of URLs *will* be encoded.

    Do escaping of whitespace to preserve spatial formatting. We use character + entity #160 to make it safer for xml.

    Parameters
    str: string
    The string in which to escape whitespace.
    opt_xml: boolean=
    Whether to use XML compatible tags.
    Returns
    An escaped copy of str.

    Global Properties

    Regular expression that matches any character that needs to be escaped.

    Regular expression that matches an ampersand, for use in escaping.

    Regular expression that matches a lowercase letter "e", for use in escaping.

    Regular expression that matches a greater than sign, for use in escaping.

    Maximum value of #goog.string.hashCode, exclusive. 2^32.

    Regular expression that matches an HTML entity. + See also HTML5: Tokenization / Tokenizing character references.

    Regular expression that matches a less than sign, for use in escaping.

    Regular expression that matches null character, for use in escaping.

    Regular expression that matches a double quote, for use in escaping.

    Regular expression that matches a single quote, for use in escaping.

    Character mappings used internally for goog.string.escapeChar.

    Regular expression used for splitting a string into substrings of fractional + numbers, integers, and non-numeric characters.

    Special chars that need to be escaped for goog.string.quote.

    The most recent unique ID. |0 is equivalent to Math.floor in this case.

    Compiler Constants

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_structs.html b/node_modules/selenium-webdriver/docs/namespace_goog_structs.html new file mode 100644 index 0000000..d80ee82 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_structs.html @@ -0,0 +1,38 @@ +goog.structs

    Namespace goog.structs

    code »

    Classes

    goog.structs.Map
    Class for Hash Map datastructure.
    Show:

    Global Functions

    Removes all the elements from the collection.

    Parameters
    col: Object
    The collection-like object.

    Whether the collection contains the given value. This is O(n) and uses + equals (==) to test the existence.

    Parameters
    col: Object
    The collection-like object.
    val: *
    The value to check for.
    Returns
    True if the map contains the value.
    code »<T, S> goog.structs.every ( col, f, opt_obj )boolean

    Calls f for each value in a collection. If all calls return true this return + true this returns true. If any returns false this returns false at this point + and does not continue to check the remaining values.

    Parameters
    col: S
    The collection-like object.
    f: function(this: T, ?, ?, S): boolean
    The function to call for every + value. This function takes 3 arguments (the value, the key or + undefined if the collection has no notion of keys, and the collection) + and should return a boolean.
    opt_obj: T=
    The object to be used as the value of 'this' + within f.
    Returns
    True if all key-value pairs pass the test.
    code »<T, S> goog.structs.filter ( col, f, opt_obj )(!Object|!Array)

    Calls a function for every value in the collection. When a call returns true, + adds the value to a new collection (Array is returned by default).

    Parameters
    col: S
    The collection-like object.
    f: function(this: T, ?, ?, S): boolean
    The function to call for every + value. This function takes + 3 arguments (the value, the key or undefined if the collection has no + notion of keys, and the collection) and should return a Boolean. If the + return value is true the value is added to the result collection. If it + is false the value is not included.
    opt_obj: T=
    The object to be used as the value of 'this' + within f.
    Returns
    A new collection where the passed values are + present. If col is a key-less collection an array is returned. If col + has keys and values a plain old JS object is returned.
    code »<T, S> goog.structs.forEach ( col, f, opt_obj )

    Calls a function for each value in a collection. The function takes + three arguments; the value, the key and the collection. + + NOTE: This will be deprecated soon! Please use a more specific method if + possible, e.g. goog.array.forEach, goog.object.forEach, etc.

    Parameters
    col: S
    The collection-like object.
    f: function(this: T, ?, ?, S): ?
    The function to call for every value. + This function takes + 3 arguments (the value, the key or undefined if the collection has no + notion of keys, and the collection) and the return value is irrelevant.
    opt_obj: T=
    The object to be used as the value of 'this' + within f.

    Returns the number of values in the collection-like object.

    Parameters
    col: Object
    The collection-like object.
    Returns
    The number of values in the collection-like object.

    Returns the keys of the collection. Some collections have no notion of + keys/indexes and this function will return undefined in those cases.

    Parameters
    col: Object
    The collection-like object.
    Returns
    The keys in the collection.

    Returns the values of the collection-like object.

    Parameters
    col: Object
    The collection-like object.
    Returns
    The values in the collection-like object.

    Whether the collection is empty.

    Parameters
    col: Object
    The collection-like object.
    Returns
    True if empty.
    code »<T, S, V> goog.structs.map ( col, f, opt_obj )(!Object.<V>|!Array.<V>)

    Calls a function for every value in the collection and adds the result into a + new collection (defaults to creating a new Array).

    Parameters
    col: S
    The collection-like object.
    f: function(this: T, ?, ?, S): V
    The function to call for every value. + This function takes 3 arguments (the value, the key or undefined if the + collection has no notion of keys, and the collection) and should return + something. The result will be used as the value in the new collection.
    opt_obj: T=
    The object to be used as the value of 'this' + within f.
    Returns
    A new collection with the new values. If + col is a key-less collection an array is returned. If col has keys and + values a plain old JS object is returned.
    code »<T, S> goog.structs.some ( col, f, opt_obj )boolean

    Calls f for each value in a collection. If any call returns true this returns + true (without checking the rest). If all returns false this returns false.

    Parameters
    col: S
    The collection-like object.
    f: function(this: T, ?, ?, S): boolean
    The function to call for every + value. This function takes 3 arguments (the value, the key or undefined + if the collection has no notion of keys, and the collection) and should + return a boolean.
    opt_obj: T=
    The object to be used as the value of 'this' + within f.
    Returns
    True if any value passes the test.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_uri.html b/node_modules/selenium-webdriver/docs/namespace_goog_uri.html new file mode 100644 index 0000000..2bf8bb8 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_uri.html @@ -0,0 +1 @@ +goog.uri

    Namespace goog.uri

    code »
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_uri_utils.html b/node_modules/selenium-webdriver/docs/namespace_goog_uri_utils.html new file mode 100644 index 0000000..be49e7b --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_uri_utils.html @@ -0,0 +1,192 @@ +goog.uri.utils

    Namespace goog.uri.utils

    code »

    Enumerations

    goog.uri.utils.CharCode_
    Character codes inlined to avoid object allocations due to charCode.
    goog.uri.utils.ComponentIndex
    The index of each URI component in the return value of goog.uri.utils.split.
    goog.uri.utils.StandardQueryParam
    Standard supported query parameters.
    Show:

    Type Definitions

    An array representing a set of query parameters with alternating keys + and values. + + Keys are assumed to be URI encoded already and live at even indices. See + goog.uri.utils.QueryValue for details on how parameter values are encoded. + + Example: +
    + var data = [
    +   // Simple param: ?name=BobBarker
    +   'name', 'BobBarker',
    +   // Conditional param -- may be omitted entirely.
    +   'specialDietaryNeeds', hasDietaryNeeds() ? getDietaryNeeds() : null,
    +   // Multi-valued param: &house=LosAngeles&house=NewYork&house=null
    +   'house', ['LosAngeles', 'NewYork', null]
    + ];
    + 
    Supported query parameter values by the parameter serializing utilities. + + If a value is null or undefined, the key-value pair is skipped, as an easy + way to omit parameters conditionally. Non-array parameters are converted + to a string and URI encoded. Array values are expanded into multiple + &key=value pairs, with each element stringized and URI-encoded.

    Global Functions

    Appends key=value pairs to an array, supporting multi-valued objects.

    Parameters
    key: string
    The key prefix.
    value: goog.uri.utils.QueryValue
    The value to serialize.
    pairs: !Array.<string>
    The array to which the 'key=value' strings + should be appended.
    code »goog.uri.utils.appendParam ( uri, key, opt_value )string

    Appends a single URI parameter. + + Repeated calls to this can exhibit quadratic behavior in IE6 due to the + way string append works, though it should be limited given the 2kb limit.

    Parameters
    uri: string
    The original URI, which may already have query data.
    key: string
    The key, which must already be URI encoded.
    opt_value: *=
    The value, which will be stringized and encoded + (assumed not already to be encoded). If omitted, undefined, or null, the + key will be added as a valueless parameter.
    Returns
    The URI with the query parameter added.

    Appends URI parameters to an existing URI. + + The variable arguments may contain alternating keys and values. Keys are + assumed to be already URI encoded. The values should not be URI-encoded, + and will instead be encoded by this function. +

    + appendParams('http://www.foo.com?existing=true',
    +     'key1', 'value1',
    +     'key2', 'value?willBeEncoded',
    +     'key3', ['valueA', 'valueB', 'valueC'],
    +     'key4', null);
    + result: 'http://www.foo.com?existing=true&' +
    +     'key1=value1&' +
    +     'key2=value%3FwillBeEncoded&' +
    +     'key3=valueA&key3=valueB&key3=valueC'
    + 
    + + A single call to this function will not exhibit quadratic behavior in IE, + whereas multiple repeated calls may, although the effect is limited by + fact that URL's generally can't exceed 2kb.
    Parameters
    uri: string
    The original URI, which may already have query data.
    var_args: ...(goog.uri.utils.QueryArray|string|goog.uri.utils.QueryValue)
    An array or argument list conforming to goog.uri.utils.QueryArray.
    Returns
    The URI with all query parameters added.

    Appends query parameters from a map.

    Parameters
    uri: string
    The original URI, which may already have query data.
    map: Object
    An object where keys are URI-encoded parameter keys, + and the values are arbitrary types or arrays. Keys with a null value + are dropped.
    Returns
    The new parameters.

    Generates a URI path using a given URI and a path with checks to + prevent consecutive "//". The baseUri passed in must not contain + query or fragment identifiers. The path to append may not contain query or + fragment identifiers.

    Parameters
    baseUri: string
    URI to use as the base.
    path: string
    Path to append.
    Returns
    Updated URI.

    Appends a URI and query data in a string buffer with special preconditions. + + Internal implementation utility, performing very few object allocations.

    Parameters
    buffer: !Array
    A string buffer. The first element + must be the base URI, and may have a fragment identifier. If the array + contains more than one element, the second element must be an ampersand, + and may be overwritten, depending on the base URI. Undefined elements + are treated as empty-string.
    Returns
    The concatenated URI and query data.

    Asserts that there are no fragment or query identifiers, only in uncompiled + mode.

    Parameters
    uri: string
    The URI to examine.
    code »goog.uri.utils.buildFromEncodedParts ( opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_queryData, opt_fragment )string

    Builds a URI string from already-encoded parts. + + No encoding is performed. Any component may be omitted as either null or + undefined.

    Parameters
    opt_scheme: ?string=
    The scheme such as 'http'.
    opt_userInfo: ?string=
    The user name before the '@'.
    opt_domain: ?string=
    The domain such as 'www.google.com', already + URI-encoded.
    opt_port: (string|number|null)=
    The port number.
    opt_path: ?string=
    The path, already URI-encoded. If it is not + empty, it must begin with a slash.
    opt_queryData: ?string=
    The URI-encoded query data.
    opt_fragment: ?string=
    The URI-encoded fragment identifier.
    Returns
    The fully combined URI.
    code »goog.uri.utils.buildQueryData ( keysAndValues, opt_startIndex )string

    Builds a query data string from a sequence of alternating keys and values. + Currently generates "&key&" for empty args.

    Parameters
    keysAndValues: goog.uri.utils.QueryArray
    Alternating keys and + values. See the typedef.
    opt_startIndex: number=
    A start offset into the arary, defaults to 0.
    Returns
    The encoded query string, in the form 'a=1&b=2'.

    Builds a buffer of query data from a map.

    Parameters
    buffer: !Array
    A string buffer to append to. The + first element appended will be an '&', and may be replaced by the caller.
    map: Object.<goog.uri.utils.QueryValue>
    An object where keys are + URI-encoded parameter keys, and the values conform to the contract + specified in the goog.uri.utils.QueryValue typedef.
    Returns
    The buffer argument.
    code »goog.uri.utils.buildQueryDataBuffer_ ( buffer, keysAndValues, opt_startIndex )!Array

    Builds a buffer of query data from a sequence of alternating keys and values.

    Parameters
    buffer: !Array
    A string buffer to append to. The + first element appended will be an '&', and may be replaced by the caller.
    keysAndValues: (goog.uri.utils.QueryArray|Arguments)
    An array with + alternating keys and values -- see the typedef.
    opt_startIndex: number=
    A start offset into the arary, defaults to 0.
    Returns
    The buffer argument.

    Builds a query data string from a map. + Currently generates "&key&" for empty args.

    Parameters
    map: Object
    An object where keys are URI-encoded parameter keys, + and the values are arbitrary types or arrays. Keys with a null value + are dropped.
    Returns
    The encoded query string, in the form 'a=1&b=2'.
    Parameters
    uri: ?string
    A possibly null string.
    Returns
    The string URI-decoded, or null if uri is null.
    code »goog.uri.utils.findParam_ ( uri, startIndex, keyEncoded, hashOrEndIndex )number

    Finds the next instance of a query parameter with the specified name. + + Does not instantiate any objects.

    Parameters
    uri: string
    The URI to search. May contain a fragment identifier + if opt_hashIndex is specified.
    startIndex: number
    The index to begin searching for the key at. A + match may be found even if this is one character after the ampersand.
    keyEncoded: string
    The URI-encoded key.
    hashOrEndIndex: number
    Index to stop looking at. If a hash + mark is present, it should be its index, otherwise it should be the + length of the string.
    Returns
    The position of the first character in the key's name, + immediately after either a question mark or a dot.

    Gets a URI component by index. + + It is preferred to use the getPathEncoded() variety of functions ahead, + since they are more readable.

    Parameters
    componentIndex: goog.uri.utils.ComponentIndex
    The component index.
    uri: string
    The URI to examine.
    Returns
    The still-encoded component, or null if the component + is not present.
    Parameters
    uri: string
    The URI to examine.
    Returns
    The decoded domain, or null if none.
    Parameters
    uri: string
    The URI to examine.
    Returns
    The domain name still encoded, or null if none.

    Gets the effective scheme for the URL. If the URL is relative then the + scheme is derived from the page's location.

    Parameters
    uri: string
    The URI to examine.
    Returns
    The protocol or scheme, always lower case.
    Parameters
    uri: string
    The URI to examine.
    Returns
    The decoded fragment identifier, or null if none. Does + not include the hash mark.
    Parameters
    uri: string
    The URI to examine.
    Returns
    The fragment identifier, or null if none. Does not + include the hash mark itself.

    Extracts everything up to the port of the URI.

    Parameters
    uri: string
    The URI string.
    Returns
    Everything up to and including the port.

    Gets the first value of a query parameter.

    Parameters
    uri: string
    The URI to process. May contain a fragment.
    keyEncoded: string
    The URI-encoded key. Case-sensitive.
    Returns
    The first value of the parameter (URI-decoded), or null + if the parameter is not found.

    Gets all values of a query parameter.

    Parameters
    uri: string
    The URI to process. May contain a framgnet.
    keyEncoded: string
    The URI-encoded key. Case-snsitive.
    Returns
    All URI-decoded values with the given key. + If the key is not found, this will have length 0, but never be null.
    Parameters
    uri: string
    The URI to examine.
    Returns
    The decoded path, or null if none. Includes the leading + slash, if any.

    Extracts the path of the URL and everything after.

    Parameters
    uri: string
    The URI string.
    Returns
    The URI, starting at the path and including the query + parameters and fragment identifier.
    Parameters
    uri: string
    The URI to examine.
    Returns
    The path still encoded, or null if none. Includes the + leading slash, if any.
    Parameters
    uri: string
    The URI to examine.
    Returns
    The port number, or null if none.
    Parameters
    uri: string
    The URI to examine.
    Returns
    The query data still encoded, or null if none. Does not + include the question mark itself.
    Parameters
    uri: string
    The URI to examine.
    Returns
    The protocol or scheme, or null if none. Does not + include trailing colons or slashes.
    Parameters
    uri: string
    The URI to examine.
    Returns
    The decoded user info, or null if none.
    Parameters
    uri: string
    The URI to examine.
    Returns
    The user name still encoded, or null if none.
    code »goog.uri.utils.hasParam ( uri, keyEncoded )boolean

    Determines if the URI contains a specific key. + + Performs no object instantiations.

    Parameters
    uri: string
    The URI to process. May contain a fragment + identifier.
    keyEncoded: string
    The URI-encoded key. Case-sensitive.
    Returns
    Whether the key is present.

    Ensures that two URI's have the exact same domain, scheme, and port. + + Unlike the version in goog.Uri, this checks protocol, and therefore is + suitable for checking against the browser's same-origin policy.

    Parameters
    uri1: string
    The first URI.
    uri2: string
    The second URI.
    Returns
    Whether they have the same domain and port.

    Sets the zx parameter of a URI to a random value.

    Parameters
    uri: string
    Any URI.
    Returns
    That URI with the "zx" parameter added or replaced to + contain a random string.

    Check to see if the user is being phished.

    Gets the URI with the fragment identifier removed.

    Parameters
    uri: string
    The URI to examine.
    Returns
    Everything preceding the hash mark.

    Removes all instances of a query parameter.

    Parameters
    uri: string
    The URI to process. Must not contain a fragment.
    keyEncoded: string
    The URI-encoded key.
    Returns
    The URI with all instances of the parameter removed.
    Parameters
    uri: string
    The URI to examine.
    fragment: ?string
    The encoded fragment identifier, or null if none. + Does not include the hash mark itself.
    Returns
    The URI with the fragment set.
    code »goog.uri.utils.setParam ( uri, keyEncoded, value )string

    Replaces all existing definitions of a parameter with a single definition. + + Repeated calls to this can exhibit quadratic behavior due to the need to + find existing instances and reconstruct the string, though it should be + limited given the 2kb limit. Consider using appendParams to append multiple + parameters in bulk.

    Parameters
    uri: string
    The original URI, which may already have query data.
    keyEncoded: string
    The key, which must already be URI encoded.
    value: *
    The value, which will be stringized and encoded (assumed + not already to be encoded).
    Returns
    The URI with the query parameter added.

    Replaces the path.

    Parameters
    uri: string
    URI to use as the base.
    path: string
    New path.
    Returns
    Updated URI.

    Splits a URI into its component parts. + + Each component can be accessed via the component indices; for example: +

    + goog.uri.utils.split(someStr)[goog.uri.utils.CompontentIndex.QUERY_DATA];
    + 
    Parameters
    uri: string
    The URI string to examine.
    Returns
    Each component still URI-encoded. + Each component that is present will contain the encoded value, whereas + components that are not present will be undefined or empty, depending + on the browser's regular expression implementation. Never null, since + arbitrary strings may still look like path names.

    Global Properties

    Regular expression for finding a hash mark or end of string.

    Safari has a nasty bug where if you have an http URL with a username, e.g., + http://evil.com%2F@google.com/ + Safari will report that window.location.href is + http://evil.com/google.com/ + so that anyone who tries to parse the domain of that URL will get + the wrong domain. We've seen exploits where people use this to trick + Safari into loading resources from evil domains. + + To work around this, we run a little "Safari phishing check", and throw + an exception if we see this happening. + + There is no convenient place to put this check. We apply it to + anyone doing URI parsing on Webkit. We're not happy about this, but + it fixes the problem. + + This should be removed once Safari fixes their bug. + + Exploit reported by Masato Kinugawa.

    A regular expression for breaking a URI into its component parts. + + http://www.ietf.org/rfc/rfc3986.txt says in Appendix B + As the "first-match-wins" algorithm is identical to the "greedy" + disambiguation method used by POSIX regular expressions, it is natural and + commonplace to use a regular expression for parsing the potential five + components of a URI reference. + + The following line is the regular expression for breaking-down a + well-formed URI reference into its components. + +

    + ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
    +  12            3  4          5       6  7        8 9
    + 
    + + The numbers in the second line above are only to assist readability; they + indicate the reference points for each subexpression (i.e., each paired + parenthesis). We refer to the value matched for subexpression as $. + For example, matching the above expression to +
    +     http://www.ics.uci.edu/pub/ietf/uri/#Related
    + 
    + results in the following subexpression matches: +
    +    $1 = http:
    +    $2 = http
    +    $3 = //www.ics.uci.edu
    +    $4 = www.ics.uci.edu
    +    $5 = /pub/ietf/uri/
    +    $6 = 
    +    $7 = 
    +    $8 = #Related
    +    $9 = Related
    + 
    + where indicates that the component is not present, as is the + case for the query component in the above example. Therefore, we can + determine the value of the five components as +
    +    scheme    = $2
    +    authority = $4
    +    path      = $5
    +    query     = $7
    +    fragment  = $9
    + 
    + + The regular expression has been modified slightly to expose the + userInfo, domain, and port separately from the authority. + The modified version yields +
    +    $1 = http              scheme
    +    $2 =        userInfo -\
    +    $3 = www.ics.uci.edu   domain     | authority
    +    $4 =        port     -/
    +    $5 = /pub/ietf/uri/    path
    +    $6 =        query without ?
    +    $7 = Related           fragment without #
    + 

    Regexp to find trailing question marks and ampersands.

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_userAgent.html b/node_modules/selenium-webdriver/docs/namespace_goog_userAgent.html new file mode 100644 index 0000000..5b2e3a4 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_userAgent.html @@ -0,0 +1,35 @@ +goog.userAgent

    Namespace goog.userAgent

    code »
    Show:

    Global Functions

    Deprecated: Use goog.string.compareVersions.

    Compares two version numbers.

    Parameters
    v1: string
    Version of first item.
    v2: string
    Version of second item.
    Returns
    1 if first argument is higher + 0 if arguments are equal + -1 if second argument is higher.
    Returns
    the platform (operating system) the user agent is running + on. Default to empty string because navigator.platform may not be defined + (on Rhino, for example).
    Returns
    The string that describes the version number of the user + agent.
    Returns
    Returns the document mode (for testing).

    TODO(nnaze): Change type to "Navigator" and update compilation targets.

    Returns
    The native navigator object.

    Returns the userAgent string for the current browser.

    Returns
    The userAgent string.

    Initialize the goog.userAgent constants that define which platform the user + agent is running on.

    Deprecated: Use goog.userAgent.isDocumentModeOrHigher().

    Deprecated alias to goog.userAgent.isDocumentModeOrHigher.

    Parameters
    version: number
    The version to check.
    Returns
    Whether the IE effective document mode is higher or the + same as the given version.

    Whether the IE effective document mode is higher or the same as the given + document mode version. + NOTE: Only for IE, return false for another browser.

    Parameters
    documentMode: number
    The document mode version to check.
    Returns
    Whether the IE effective document mode is higher or the + same as the given version.

    Whether the user agent is running on a mobile device. + + This is a separate function so that the logic can be tested. + + TODO(nnaze): Investigate swapping in goog.labs.userAgent.device.isMobile().

    Returns
    Whether the user agent is running on a mobile device.
    Deprecated: Use goog.userAgent.isVersionOrHigher().

    Deprecated alias to goog.userAgent.isVersionOrHigher.

    Parameters
    version: (string|number)
    The version to check.
    Returns
    Whether the user agent version is higher or the same as + the given version.

    Whether the user agent version is higher or the same as the given version. + NOTE: When checking the version numbers for Firefox and Safari, be sure to + use the engine's version, not the browser's version number. For example, + Firefox 3.0 corresponds to Gecko 1.9 and Safari 3.0 to Webkit 522.11. + Opera and Internet Explorer versions match the product release number.

    Parameters
    version: (string|number)
    The version to check.
    Returns
    Whether the user agent version is higher or the same as + the given version.

    Global Properties

    Whether the user agent is running on Android.

    Whether we know the browser engine at compile-time.

    For IE version < 7, documentMode is undefined, so attempt to use the + CSS1Compat property to see if we are in standards mode. If we are in + standards mode, treat the browser version as the document mode. Otherwise, + IE is emulating version 5.

    Whether the user agent is Gecko. Gecko is the rendering engine used by + Mozilla, Firefox, and others.

    Whether the user agent is Internet Explorer.

    Whether the user agent is running on an iPad.

    Whether the user agent is running on an iPhone.

    Whether the user agent is running on a Linux operating system.

    Whether the user agent is running on a Macintosh operating system.

    Whether the user agent is running on a mobile device. + + TODO(nnaze): Consider deprecating MOBILE when labs.userAgent + is promoted as the gecko/webkit logic is likely inaccurate.

    Whether the user agent is Opera.

    The platform (operating system) the user agent is running on. Default to + empty string because navigator.platform may not be defined (on Rhino, for + example).

    Deprecated: Use goog.userAgent.product.SAFARI instead. + TODO(nicksantos): Delete this from goog.userAgent.

    Used while transitioning code to use WEBKIT instead.

    The version of the user agent. This is a string because it might contain + 'b' (as in beta) as well as multiple dots.

    Whether the user agent is WebKit. WebKit is the rendering engine that + Safari, Android and others use.

    Whether the user agent is running on a Windows operating system.

    Whether the user agent is running on a X11 windowing system.

    Whether the user agent is running on Android.

    Whether the user agent is running on an iPad.

    Whether the user agent is running on an iPhone.

    Whether the user agent is running on a Linux operating system.

    Whether the user agent is running on a Macintosh operating system.

    Whether the user agent is running on a Windows operating system.

    Whether the user agent is running on a X11 windowing system.

    Cache for goog.userAgent.isVersionOrHigher. + Calls to compareVersions are surprisingly expensive and, as a browser's + version number is unlikely to change during a session, we cache the results.

    Compiler Constants

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_goog_userAgent_product.html b/node_modules/selenium-webdriver/docs/namespace_goog_userAgent_product.html new file mode 100644 index 0000000..f06d154 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_goog_userAgent_product.html @@ -0,0 +1,9 @@ +goog.userAgent.product

    Namespace goog.userAgent.product

    code »
    Show:

    Global Functions

    Returns
    The string that describes the version number of the user + agent product. This is a string rather than a number because it may + contain 'b', 'a', and so on.

    Run regexp's exec() on the userAgent string.

    Parameters
    re: !RegExp
    Regular expression.
    Returns
    A result array, or null for no match.

    Return the first group of the given regex.

    Parameters
    re: !RegExp
    Regular expression with at least one group.
    Returns
    Contents of the first group or an empty string if no match.

    Right now we just focus on Tier 1-3 browsers at: + http://wiki/Nonconf/ProductPlatformGuidelines + As well as the YUI grade A browsers at: + http://developer.yahoo.com/yui/articles/gbs/

    Whether the user agent product version is higher or the same as the given + version.

    Parameters
    version: (string|number)
    The version to check.
    Returns
    Whether the user agent product version is higher or the + same as the given version.

    Global Properties

    Whether the code is running on the default browser on an Android phone.

    Whether the code is running on the Camino web browser.

    Whether the code is running on the Chrome web browser.

    Whether the code is running on the Firefox web browser.

    Whether the code is running on an IE web browser.

    Whether the code is running on an iPad.

    Whether the code is running on an iPhone or iPod touch.

    Whether the code is running on the Opera web browser.

    Whether we know the product type at compile-time.

    Whether the code is running on the Safari web browser.

    The version of the user agent. This is a string because it might contain + 'b' (as in beta) as well as multiple dots.

    Whether the code is running on the default browser on an Android phone.

    Whether the code is running on the Camino web browser.

    Whether the code is running on the Chrome web browser.

    Whether the code is running on the Firefox web browser.

    Whether the code is running on an iPad

    Whether the code is running on an iPhone or iPod touch.

    Whether the code is running on the Safari web browser.

    Compiler Constants

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_webdriver.html b/node_modules/selenium-webdriver/docs/namespace_webdriver.html new file mode 100644 index 0000000..dc25a7d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_webdriver.html @@ -0,0 +1,4 @@ +webdriver

    Namespace webdriver

    code »

    Interfaces

    webdriver.CommandExecutor
    Handles the execution of webdriver.Command objects.

    Classes

    webdriver.AbstractBuilder
    Creates new webdriver.WebDriver clients.
    webdriver.ActionSequence
    Class for defining sequences of complex user interactions.
    webdriver.Alert
    Represents a modal dialog such as alert, confirm, or + prompt.
    webdriver.Builder
    No Description.
    webdriver.Capabilities
    No Description.
    webdriver.Command
    Describes a command to be executed by the WebDriverJS framework.
    webdriver.EventEmitter
    Object that can emit events for others to listen for.
    webdriver.FirefoxDomExecutor
    No Description.
    webdriver.Locator
    An element locator.
    webdriver.Session
    Contains information about a WebDriver session.
    webdriver.UnhandledAlertError
    An error returned to indicate that there is an unhandled modal dialog on the + current page.
    webdriver.WebDriver
    Creates a new WebDriver client, which provides control over a browser.
    webdriver.WebElement
    Represents a DOM element.

    Enumerations

    webdriver.Browser
    Recognized browser names.
    webdriver.Button
    Enumeration of the buttons used in the advanced interactions API.
    webdriver.Capability
    Common webdriver capability keys.
    webdriver.CommandName
    Enumeration of predefined names command names that all command processors + will support.
    webdriver.Key
    Representations of pressable keys that aren't text.
    Show:
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_webdriver_By.html b/node_modules/selenium-webdriver/docs/namespace_webdriver_By.html new file mode 100644 index 0000000..342af00 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_webdriver_By.html @@ -0,0 +1,26 @@ +webdriver.By

    Namespace webdriver.By

    code »

    A collection of factory functions for creating webdriver.Locator + instances.

    Show:

    Type Definitions

    code »webdriver.By.Hash : ({className: string}|{css: string}|{id: string}|{js: string}|{linkText: string}|{name: string}|{partialLinkText: string}|{tagName: string}|{xpath: string})
    Short-hand expressions for the primary element locator strategies. + For example the following two statements are equivalent: +
    + var e1 = driver.findElement(webdriver.By.id('foo'));
    + var e2 = driver.findElement({id: 'foo'});
    + 
    + +

    Care should be taken when using JavaScript minifiers (such as the + Closure compiler), as locator hashes will always be parsed using + the un-obfuscated properties listed below.

    Global Functions

    Locates elements that have a specific class name. The returned locator + is equivalent to searching for elements with the CSS selector ".clazz".

    Parameters
    className: string
    The class name to search for.
    Returns
    The new locator.

    Locates elements using a CSS selector. For browsers that do not support + CSS selectors, WebDriver implementations may return an + invalid selector error. An + implementation may, however, emulate the CSS selector API.

    Parameters
    selector: string
    The CSS selector to use.
    Returns
    The new locator.

    Locates an element by its ID.

    Parameters
    id: string
    The ID to search for.
    Returns
    The new locator.

    Locates an elements by evaluating a + JavaScript expression. + The result of this expression must be an element or list of elements.

    Parameters
    script: !(string|Function)
    The script to execute.
    var_args: ...*
    The arguments to pass to the script.
    Returns
    A new, + JavaScript-based locator function.

    Locates link elements whose visible + text matches the given string.

    Parameters
    text: string
    The link text to search for.
    Returns
    The new locator.

    Locates elements whose name attribute has the given value.

    Parameters
    name: string
    The name attribute to search for.
    Returns
    The new locator.

    Locates link elements whose visible + text contains the given substring.

    Parameters
    text: string
    The substring to check for in a link's visible text.
    Returns
    The new locator.

    Locates elements with a given tag name. The returned locator is + equivalent to using the getElementsByTagName DOM function.

    Parameters
    text: string
    The substring to check for in a link's visible text.
    Returns
    The new locator.

    Locates elements matching a XPath selector. Care should be taken when + using an XPath selector with a webdriver.WebElement as WebDriver + will respect the context in the specified in the selector. For example, + given the selector "//div", WebDriver will search from the + document root regardless of whether the locator was used with a + WebElement.

    Parameters
    xpath: string
    The XPath selector to use.
    Returns
    The new locator.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_webdriver_http.html b/node_modules/selenium-webdriver/docs/namespace_webdriver_http.html new file mode 100644 index 0000000..19bb8c3 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_webdriver_http.html @@ -0,0 +1,4 @@ +webdriver.http

    Namespace webdriver.http

    code »

    Interfaces

    webdriver.http.Client
    Interface used for sending individual HTTP requests to the server.

    Classes

    webdriver.http.CorsClient
    Communicates with a WebDriver server, which may be on a different domain, + using the cross-origin resource sharing + (CORS) extension to WebDriver's JSON wire protocol.
    webdriver.http.Executor
    A command executor that communicates with a server using the WebDriver + command protocol.
    webdriver.http.Request
    Describes a partial HTTP request.
    webdriver.http.Response
    Represents a HTTP response.
    webdriver.http.XhrClient
    A HTTP client that sends requests using XMLHttpRequests.
    Show:

    Global Functions

    Converts a headers object to a HTTP header block string.

    Parameters
    headers: !Object.<string>
    The headers object to convert.
    Returns
    The headers as a string.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_webdriver_logging.html b/node_modules/selenium-webdriver/docs/namespace_webdriver_logging.html new file mode 100644 index 0000000..2cd469f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_webdriver_logging.html @@ -0,0 +1,4 @@ +webdriver.logging

    Namespace webdriver.logging

    code »

    Classes

    webdriver.logging.Entry
    A single log entry.

    Enumerations

    webdriver.logging.Level
    Logging levels.
    webdriver.logging.LevelName
    Log level names from WebDriver's JSON wire protocol.
    webdriver.logging.Type
    Common log types.
    Show:

    Type Definitions

    Global Functions

    Converts a level name or value to a webdriver.logging.Level value. + If the name/value is not recognized, webdriver.logging.Level.ALL + will be returned.

    Parameters
    nameOrValue: (number|string)
    The log level name, or value, to + convert .
    Returns
    The converted level.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_webdriver_process.html b/node_modules/selenium-webdriver/docs/namespace_webdriver_process.html new file mode 100644 index 0000000..eafcd04 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_webdriver_process.html @@ -0,0 +1,8 @@ +webdriver.process

    Namespace webdriver.process

    code »
    Show:

    Global Functions

    code »webdriver.process.getEnv ( name, opt_default )string

    Queries for a named environment variable.

    Parameters
    name: string
    The name of the environment variable to look up.
    opt_default: string=
    The default value if the named variable is not + defined.
    Returns
    The queried environment variable.

    Initializes a process object for use in a browser window.

    Parameters
    opt_window: !Window=
    The window object to initialize the process + from; if not specified, will default to the current window. Should only + be set for unit testing.
    Returns
    The new process object.
    Returns
    Whether the current process is Node's native process + object.

    Sets an environment value. If the new value is either null or undefined, the + environment variable will be cleared.

    Parameters
    name: string
    The value to set.
    value: *
    The new value; will be coerced to a string.

    Global Properties

    Whether the current environment is using Node's native process object.

    The global process object to use. Will either be Node's global + process object, or an approximation of it for use in a browser + environment.

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_webdriver_promise.html b/node_modules/selenium-webdriver/docs/namespace_webdriver_promise.html new file mode 100644 index 0000000..230c60a --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_webdriver_promise.html @@ -0,0 +1,79 @@ +webdriver.promise

    Namespace webdriver.promise

    code »

    Classes

    webdriver.promise.CanceledTaskError_
    Special error used to signal when a task is canceled because a previous + task in the same frame failed.
    webdriver.promise.ControlFlow
    Handles the execution of scheduled tasks, each of which may be an + asynchronous operation.
    webdriver.promise.Deferred
    Represents a value that will be resolved at some point in the future.
    webdriver.promise.Frame_
    An execution frame within a webdriver.promise.ControlFlow.
    webdriver.promise.Node_
    A single node in an webdriver.promise.ControlFlow's task tree.
    webdriver.promise.Promise
    Represents the eventual value of a completed operation.
    webdriver.promise.Task_
    A task to be executed by a webdriver.promise.ControlFlow.
    Show:

    Global Functions

    Given an array of promises, will return a promise that will be fulfilled + with the fulfillment values of the input array's values. If any of the + input array's promises are rejected, the returned promise will be rejected + with the same reason.

    Parameters
    arr: !Array
    An array of + promises to wait on.
    Returns
    A promise that is + fulfilled with an array containing the fulfilled values of the + input array, or rejected with the same reason as the first + rejected value.
    code »webdriver.promise.asap ( value, callback, opt_errback )

    Invokes the appropriate callback function as soon as a promised + value is resolved. This function is similar to + webdriver.promise.when, except it does not return a new promise.

    Parameters
    value: *
    The value to observe.
    callback: Function
    The function to call when the value is + resolved successfully.
    opt_errback: Function=
    The function to call when the value is + rejected.

    Wraps a function that is assumed to be a node-style callback as its final + argument. This callback takes two arguments: an error value (which will be + null if the call succeeded), and the success value as the second argument. + If the call fails, the returned promise will be rejected, otherwise it will + be resolved with the result.

    Parameters
    fn: !Function
    The function to wrap.
    Returns
    A promise that will be resolved with the + result of the provided function's callback.
    Returns
    The currently active control flow.

    Creates a new control flow. The provided callback will be invoked as the + first task within the new flow, with the flow as its sole argument. Returns + a promise that resolves to the callback result.

    Parameters
    callback: function(!webdriver.promise.ControlFlow)
    The entry point + to the newly created flow.
    Returns
    A promise that resolves to the callback + result.

    Creates a new deferred object.

    Parameters
    opt_canceller: Function=
    Function to call when cancelling the + computation of this instance's value.
    Returns
    The new deferred object.

    Creates a promise that will be resolved at a set time in the future.

    Parameters
    ms: number
    The amount of time, in milliseconds, to wait before + resolving the promise.
    Returns
    The promise.
    code »<TYPE, SELF> webdriver.promise.filter ( arr, fn, opt_self )

    Calls a function for each element in an array, and if the function returns + true adds the element to a new array. + +

    If the return value of the filter function is a promise, this function + will wait for it to be fulfilled before determining whether to insert the + element into the new array. + +

    If the filter function throws or returns a rejected promise, the promise + returned by this function will be rejected with the same reason. Only the + first failure will be reported; all subsequent errors will be silently + ignored.

    Parameters
    arr: !(Array.<TYPE>|webdriver.promise.Promise)
    The + array to iterator over, or a promise that will resolve to said array.
    fn: function(this: SELF, TYPE, number, !Array.<TYPE>): (boolean|webdriver.promise.Promise.<boolean>)
    The function + to call for each element in the array.
    opt_self: SELF=
    The object to be used as the value of 'this' within + fn.

    Creates a promise that has been resolved with the given value.

    Parameters
    opt_value: T=
    The resolved value.
    Returns
    The resolved promise.
    Parameters
    obj: !(Array|Object)
    the object to resolve.
    Returns
    A promise that will be resolved with the + input object once all of its values have been fully resolved.
    Parameters
    value: *
    The value to fully resolve. If a promise, assumed to + already be resolved.
    Returns
    A promise for a fully resolved version + of the input value.

    Returns a promise that will be resolved with the input value in a + fully-resolved state. If the value is an array, each element will be fully + resolved. Likewise, if the value is an object, all keys will be fully + resolved. In both cases, all nested arrays and objects will also be + fully resolved. All fields are resolved in place; the returned promise will + resolve on value and not a copy. + + Warning: This function makes no checks against objects that contain + cyclical references: +

    
    +   var value = {};
    +   value['self'] = value;
    +   webdriver.promise.fullyResolved(value);  // Stack overflow.
    + 
    Parameters
    value: *
    The value to fully resolve.
    Returns
    A promise for a fully resolved version + of the input value.

    Tests if a value is an Error-like object. This is more than an straight + instanceof check since the value may originate from another context.

    Parameters
    value: *
    The value to test.
    Returns
    Whether the value is an error.

    Determines whether a value should be treated as a promise. + Any object whose "then" property is a function will be considered a promise.

    Parameters
    value: *
    The value to test.
    Returns
    Whether the value is a promise.
    code »<TYPE, SELF> webdriver.promise.map ( arr, fn, opt_self )

    Calls a function for each element in an array and inserts the result into a + new array, which is used as the fulfillment value of the promise returned + by this function. + +

    If the return value of the mapping function is a promise, this function + will wait for it to be fulfilled before inserting it into the new array. + +

    If the mapping function throws or returns a rejected promise, the + promise returned by this function will be rejected with the same reason. + Only the first failure will be reported; all subsequent errors will be + silently ignored.

    Parameters
    arr: !(Array.<TYPE>|webdriver.promise.Promise)
    The + array to iterator over, or a promise that will resolve to said array.
    fn: function(this: SELF, TYPE, number, !Array.<TYPE>): ?
    The + function to call for each element in the array. This function should + expect three arguments (the element, the index, and the array itself.
    opt_self: SELF=
    The object to be used as the value of 'this' within + fn.

    Creates a promise that has been rejected with the given reason.

    Parameters
    opt_reason: *=
    The rejection reason; may be any value, but is + usually an Error or a string.
    Returns
    The rejected promise.

    Changes the default flow to use when no others are active.

    Parameters
    flow: !webdriver.promise.ControlFlow
    The new default flow.
    Throws
    Error
    If the default flow is not currently active.
    code »webdriver.promise.when ( value, opt_callback, opt_errback )!webdriver.promise.Promise

    Registers an observer on a promised value, returning a new promise + that will be resolved when the value is. If value is not a promise, + then the return promise will be immediately resolved.

    Parameters
    value: *
    The value to observe.
    opt_callback: Function=
    The function to call when the value is + resolved successfully.
    opt_errback: Function=
    The function to call when the value is + rejected.
    Returns
    A new promise.

    Global Properties

    A stack of active control flows, with the top of the stack used to schedule + commands. When there are multiple flows on the stack, the flow at index N + represents a callback triggered within a task owned by the flow at index + N-1.

    The default flow to use if no others are active.

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_webdriver_stacktrace.html b/node_modules/selenium-webdriver/docs/namespace_webdriver_stacktrace.html new file mode 100644 index 0000000..f94d7b7 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_webdriver_stacktrace.html @@ -0,0 +1,39 @@ +webdriver.stacktrace

    Namespace webdriver.stacktrace

    code »

    Classes

    webdriver.stacktrace.Frame
    Class representing one stack frame.
    webdriver.stacktrace.Snapshot
    Stores a snapshot of the stack trace at the time this instance was created.
    Show:

    Global Functions

    code »webdriver.stacktrace.format ( error )!(Error|goog.testing.JsUnitException)

    Formats an error's stack trace.

    Parameters
    error: !(Error|goog.testing.JsUnitException)
    The error to format.
    Returns
    The formatted error.

    Gets the native stack trace if available otherwise follows the call chain. + The generated trace will exclude all frames up to and including the call to + this function.

    Returns
    The frames of the stack trace.

    Get an error's stack trace with the error string trimmed. + V8 prepends the string representation of an error to its stack trace. + This function trims the string so that the stack trace can be parsed + consistently with the other JS engines.

    Parameters
    error: (Error|goog.testing.JsUnitException)
    The error.
    Returns
    The stack trace string.

    Parses a long firefox stack frame.

    Parameters
    frameStr: string
    The stack frame as string.
    Returns
    Stack frame object.

    Parses one stack frame.

    Parameters
    frameStr: string
    The stack frame as string.
    Returns
    Stack frame object or null if the + parsing failed.

    Parses an Error object's stack trace.

    Parameters
    stack: string
    The stack trace.
    Returns
    Stack frames. The + unrecognized frames will be nulled out.

    Global Properties

    Representation of an anonymous frame in a stack trace generated by + goog.testing.stacktrace.

    Whether the current browser supports stack traces.

    Whether the current environment supports the Error.captureStackTrace + function (as of 10/17/2012, only V8).

    RegExp pattern for function call in a Chakra (IE) stack trace. This + expression allows for identifiers like 'Anonymous function', 'eval code', + and 'Global code'.

    Regular expression for parsing on stack frame in Chakra (IE).

    Pattern for a function call in a Closure stack trace. Creates three optional + submatches: the context, function name, and alias.

    Regular expression for parsing a stack frame generated by Closure's + goog.testing.stacktrace.

    Pattern for a matching the type on a fully-qualified name. Forms an + optional sub-match on the type. For example, in "foo.bar.baz", will match on + "foo.bar".

    RegExp pattern for function call in the Firefox stack trace. + Creates a submatch for the function name.

    RegExp pattern for function names in the Firefox stack trace. + Firefox has extended identifiers to deal with inner functions and anonymous + functions: https://bugzilla.mozilla.org/show_bug.cgi?id=433529#c9

    Regular expression for parsing one stack frame in Firefox.

    RegExp pattern for JavaScript identifiers. We don't support Unicode + identifiers defined in ECMAScript v3.

    Maximum length of a string that can be matched with a RegExp on + Firefox 3x. Exceeding this approximate length will cause string.match + to exceed Firefox's stack quota. This situation can be encountered + when goog.globalEval is invoked with a long argument; such as + when loading a module.

    RegExp pattern for an anonymous function call in an Opera stack frame. + Creates 2 (optional) submatches: the context object and function name.

    RegExp pattern for a function call in an Opera stack frame. + Creates 3 (optional) submatches: the function name (if not anonymous), + the aliased context object and the function name (if anonymous).

    Regular expression for parsing on stack frame in Opera 11.68+

    Pattern for matching a fully qualified name. Will create two sub-matches: + the type (optional), and the name. For example, in "foo.bar.baz", will + match on ["foo.bar", "baz"].

    Placeholder for an unparsable frame in a stack trace generated by + goog.testing.stacktrace.

    RegExp pattern for an URL + position inside the file.

    RegExp pattern for function name alias in the V8 stack trace.

    RegExp pattern for the context of a function call in V8. Creates two + submatches, only one of which will ever match: either the namespace + identifier (with optional "new" keyword in the case of a constructor call), + or just the "new " phrase for a top level constructor call.

    RegExp pattern for function call in the V8 stack trace. + Creates 3 submatches with context object (optional), function name and + function alias (optional).

    RegExp pattern for function names and constructor calls in the V8 stack + trace.

    RegExp pattern for a location string in a V8 stack frame. Creates two + submatches for the location, one for enclosed in parentheticals and on + where the location appears alone (which will only occur if the location is + the only information in the frame).

    Regular expression for parsing one stack frame in V8.

    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_webdriver_testing.html b/node_modules/selenium-webdriver/docs/namespace_webdriver_testing.html new file mode 100644 index 0000000..e077f7b --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_webdriver_testing.html @@ -0,0 +1 @@ +webdriver.testing

    Namespace webdriver.testing

    code »

    Classes

    webdriver.testing.Assertion
    Utility for performing assertions against a given value.
    webdriver.testing.ContainsMatcher
    Accepts strins or array-like structures that contain value.
    webdriver.testing.NegatedAssertion
    An assertion that negates any applied matchers.
    Show:

    Global Functions

    Creates a new assertion.

    Parameters
    value: *
    The value to perform an assertion on.
    Returns
    The new assertion.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_webdriver_testing_assert.html b/node_modules/selenium-webdriver/docs/namespace_webdriver_testing_assert.html new file mode 100644 index 0000000..91e04b6 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_webdriver_testing_assert.html @@ -0,0 +1,3 @@ +webdriver.testing.assert

    Namespace webdriver.testing.assert

    code »

    Creates a new assertion.

    Main

    assert ( value )!webdriver.testing.Assertion
    Parameters
    value: *
    The value to perform an assertion on.
    Returns
    The new assertion.
    Show:

    Global Functions

    Registers a new assertion to expose from the + webdriver.testing.Assertion prototype.

    Parameters
    name: string
    The assertion name.
    matcherTemplate: (function(new: goog.labs.testing.Matcher, *)|{matches: function(*): boolean, describe: function(): string})
    Either the + matcher constructor to use, or an object literal defining a matcher.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/namespace_webdriver_testing_asserts.html b/node_modules/selenium-webdriver/docs/namespace_webdriver_testing_asserts.html new file mode 100644 index 0000000..1050173 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/namespace_webdriver_testing_asserts.html @@ -0,0 +1,10 @@ +webdriver.testing.asserts

    Namespace webdriver.testing.asserts

    code »
    Show:

    Global Functions

    code »webdriver.testing.asserts.assertThat ( failureMessageOrActualValue, actualValueOrMatcher, opt_matcher )!webdriver.promise.Promise
    Deprecated: Use webdriver.testing.asserts.assert instead.

    Asserts that a matcher accepts a given value. This function has two + signatures based on the number of arguments: + + Two arguments: + assertThat(actualValue, matcher) + Three arguments: + assertThat(failureMessage, actualValue, matcher)

    Parameters
    failureMessageOrActualValue: *
    Either a failure message or the value + to apply to the given matcher.
    actualValueOrMatcher: *
    Either the value to apply to the given + matcher, or the matcher itself.
    opt_matcher: goog.labs.testing.Matcher=
    The matcher to use; + ignored unless this function is invoked with three arguments.
    Returns
    The assertion result.

    Creates an equality matcher.

    Parameters
    expected: *
    The expected value.
    Returns
    The new matcher.
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/_base.js.src.html b/node_modules/selenium-webdriver/docs/source/_base.js.src.html new file mode 100644 index 0000000..a8ca370 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/_base.js.src.html @@ -0,0 +1 @@ +_base.js

    _base.js

    1// Copyright 2012 Selenium committers
    2// Copyright 2012 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16/**
    17 * @fileoverview The base module responsible for bootstrapping the Closure
    18 * library and providing a means of loading Closure-based modules.
    19 *
    20 * <p>Each script loaded by this module will be granted access to this module's
    21 * {@code require} function; all required non-native modules must be specified
    22 * relative to <em>this</em> module.
    23 *
    24 * <p>This module will load all scripts from the "lib" subdirectory, unless the
    25 * SELENIUM_DEV_MODE environment variable has been set to 1, in which case all
    26 * scripts will be loaded from the Selenium client containing this script.
    27 */
    28
    29'use strict';
    30
    31var fs = require('fs'),
    32 path = require('path'),
    33 vm = require('vm');
    34
    35
    36/**
    37 * If this script was loaded from the Selenium project repo, it will operate in
    38 * development mode, adjusting how it loads Closure-based dependencies.
    39 * @type {boolean}
    40 */
    41var devMode = (function() {
    42 var buildDescFile = path.join(__dirname, '..', 'build.desc');
    43 return fs.existsSync(buildDescFile);
    44})();
    45
    46
    47/** @return {boolean} Whether this script was loaded in dev mode. */
    48function isDevMode() {
    49 return devMode;
    50}
    51
    52
    53/**
    54 * @type {string} Path to Closure's base file, relative to this module.
    55 * @const
    56 */
    57var CLOSURE_BASE_FILE_PATH = (function() {
    58 var relativePath = isDevMode() ?
    59 '../../../third_party/closure/goog/base.js' :
    60 './lib/goog/base.js';
    61 return path.join(__dirname, relativePath);
    62})();
    63
    64
    65/**
    66 * @type {string} Path to Closure's base file, relative to this module.
    67 * @const
    68 */
    69var DEPS_FILE_PATH = (function() {
    70 var relativePath = isDevMode() ?
    71 '../../../javascript/deps.js' :
    72 './lib/goog/deps.js';
    73 return path.join(__dirname, relativePath);
    74})();
    75
    76
    77
    78/**
    79 * Synchronously loads a script into the protected Closure context.
    80 * @param {string} src Path to the file to load.
    81 */
    82function loadScript(src) {
    83 src = path.normalize(src);
    84 var contents = fs.readFileSync(src, 'utf8');
    85 vm.runInContext(contents, closure, src);
    86}
    87
    88
    89/**
    90 * The protected context to host the Closure library.
    91 * @type {!Object}
    92 * @const
    93 */
    94var closure = vm.createContext({
    95 console: console,
    96 setTimeout: setTimeout,
    97 setInterval: setInterval,
    98 clearTimeout: clearTimeout,
    99 clearInterval: clearInterval,
    100 process: process,
    101 require: require,
    102 Buffer: Buffer,
    103 Error: Error,
    104 CLOSURE_BASE_PATH: path.dirname(CLOSURE_BASE_FILE_PATH) + '/',
    105 CLOSURE_IMPORT_SCRIPT: function(src) {
    106 loadScript(src);
    107 return true;
    108 },
    109 CLOSURE_NO_DEPS: !isDevMode(),
    110 goog: {}
    111});
    112closure.window = closure;
    113
    114
    115loadScript(CLOSURE_BASE_FILE_PATH);
    116loadScript(DEPS_FILE_PATH);
    117
    118
    119/**
    120 * Loads a symbol by name from the protected Closure context.
    121 * @param {string} symbol The symbol to load.
    122 * @return {?} The loaded symbol, or {@code null} if not found.
    123 * @throws {Error} If the symbol has not been defined.
    124 */
    125function closureRequire(symbol) {
    126 closure.goog.require(symbol);
    127 return closure.goog.getObjectByName(symbol);
    128}
    129
    130
    131// PUBLIC API
    132
    133
    134/**
    135 * Loads a symbol by name from the protected Closure context and exports its
    136 * public API to the provided object. This function relies on Closure code
    137 * conventions to define the public API of an object as those properties whose
    138 * name does not end with "_".
    139 * @param {string} symbol The symbol to load. This must resolve to an object.
    140 * @return {!Object} An object with the exported API.
    141 * @throws {Error} If the symbol has not been defined or does not resolve to
    142 * an object.
    143 */
    144exports.exportPublicApi = function(symbol) {
    145 var src = closureRequire(symbol);
    146 if (typeof src != 'object' || src === null) {
    147 throw Error('"' + symbol + '" must resolve to an object');
    148 }
    149
    150 var dest = {};
    151 Object.keys(src).forEach(function(key) {
    152 if (key[key.length - 1] != '_') {
    153 dest[key] = src[key];
    154 }
    155 });
    156
    157 return dest;
    158};
    159
    160
    161if (isDevMode()) {
    162 exports.closure = closure;
    163}
    164exports.isDevMode = isDevMode;
    165exports.require = closureRequire;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/builder.js.src.html b/node_modules/selenium-webdriver/docs/source/builder.js.src.html new file mode 100644 index 0000000..4ab2772 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/builder.js.src.html @@ -0,0 +1 @@ +builder.js

    builder.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15var base = require('./_base'),
    16 executors = require('./executors');
    17
    18var goog = base.require('goog'),
    19 AbstractBuilder = base.require('webdriver.AbstractBuilder'),
    20 Browser = base.require('webdriver.Browser'),
    21 Capability = base.require('webdriver.Capability'),
    22 WebDriver = base.require('webdriver.WebDriver'),
    23 promise = base.require('webdriver.promise');
    24
    25
    26/**
    27 * @param {!webdriver.Capabilities} capabilities The desired capabilities.
    28 * @return {webdriver.WebDriver} A new WebDriver instance or {@code null}
    29 * if the requested browser is not natively supported in Node.
    30 */
    31function createNativeDriver(capabilities) {
    32 switch (capabilities.get(Capability.BROWSER_NAME)) {
    33 case Browser.CHROME:
    34 // Requiring 'chrome' above would create a cycle:
    35 // index -> builder -> chrome -> index
    36 var chrome = require('./chrome');
    37 return chrome.createDriver(capabilities);
    38
    39 case Browser.PHANTOM_JS:
    40 // Requiring 'phantomjs' would create a cycle:
    41 // index -> builder -> phantomjs -> index
    42 var phantomjs = require('./phantomjs');
    43 return phantomjs.createDriver(capabilities);
    44
    45 default:
    46 return null;
    47 }
    48}
    49
    50
    51
    52/**
    53 * Creates new {@link webdriver.WebDriver WebDriver} instances.
    54 * @constructor
    55 * @extends {webdriver.AbstractBuilder}
    56 */
    57var Builder = function() {
    58 goog.base(this);
    59};
    60goog.inherits(Builder, AbstractBuilder);
    61
    62
    63/**
    64 * Sets the proxy configuration to use for WebDriver clients created by this
    65 * builder. Any calls to {@link #withCapabilities} after this function will
    66 * overwrite these settings.
    67 * @param {!proxy.ProxyConfig} config The configuration to use.
    68 * @return {!Builder} A self reference.
    69 */
    70Builder.prototype.setProxy = function(config) {
    71 this.getCapabilities().set(Capability.PROXY, config);
    72 return this;
    73};
    74
    75
    76/**
    77 * Sets Chrome-specific options for drivers created by this builder.
    78 * @param {!chrome.Options} options The ChromeDriver options to use.
    79 * @return {!Builder} A self reference.
    80 */
    81Builder.prototype.setChromeOptions = function(options) {
    82 var newCapabilities = options.toCapabilities(this.getCapabilities());
    83 return /** @type {!Builder} */(this.withCapabilities(newCapabilities));
    84};
    85
    86
    87/**
    88 * @override
    89 */
    90Builder.prototype.build = function() {
    91 var url = this.getServerUrl();
    92
    93 // If a remote server wasn't specified, check for browsers we support
    94 // natively in node before falling back to using the java Selenium server.
    95 if (!url) {
    96 var driver = createNativeDriver(this.getCapabilities());
    97 if (driver) {
    98 return driver;
    99 }
    100
    101 // Nope, fall-back to using the default java server.
    102 url = AbstractBuilder.DEFAULT_SERVER_URL;
    103 }
    104
    105 var executor = executors.createExecutor(url);
    106 return WebDriver.createSession(executor, this.getCapabilities());
    107};
    108
    109
    110// PUBLIC API
    111
    112
    113exports.Builder = Builder;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/chrome.js.src.html b/node_modules/selenium-webdriver/docs/source/chrome.js.src.html new file mode 100644 index 0000000..910463f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/chrome.js.src.html @@ -0,0 +1 @@ +chrome.js

    chrome.js

    1// Copyright 2013 Selenium committers
    2// Copyright 2013 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16'use strict';
    17
    18var fs = require('fs'),
    19 util = require('util');
    20
    21var webdriver = require('./index'),
    22 executors = require('./executors'),
    23 io = require('./io'),
    24 portprober = require('./net/portprober'),
    25 remote = require('./remote');
    26
    27
    28/**
    29 * Name of the ChromeDriver executable.
    30 * @type {string}
    31 * @const
    32 */
    33var CHROMEDRIVER_EXE =
    34 process.platform === 'win32' ? 'chromedriver.exe' : 'chromedriver';
    35
    36
    37/**
    38 * Creates {@link remote.DriverService} instances that manage a ChromeDriver
    39 * server.
    40 * @param {string=} opt_exe Path to the server executable to use. If omitted,
    41 * the builder will attempt to locate the chromedriver on the current
    42 * PATH.
    43 * @throws {Error} If provided executable does not exist, or the chromedriver
    44 * cannot be found on the PATH.
    45 * @constructor
    46 */
    47var ServiceBuilder = function(opt_exe) {
    48 /** @private {string} */
    49 this.exe_ = opt_exe || io.findInPath(CHROMEDRIVER_EXE, true);
    50 if (!this.exe_) {
    51 throw Error(
    52 'The ChromeDriver could not be found on the current PATH. Please ' +
    53 'download the latest version of the ChromeDriver from ' +
    54 'http://chromedriver.storage.googleapis.com/index.html and ensure ' +
    55 'it can be found on your PATH.');
    56 }
    57
    58 if (!fs.existsSync(this.exe_)) {
    59 throw Error('File does not exist: ' + this.exe_);
    60 }
    61
    62 /** @private {!Array.<string>} */
    63 this.args_ = [];
    64 this.stdio_ = 'ignore';
    65};
    66
    67
    68/** @private {number} */
    69ServiceBuilder.prototype.port_ = 0;
    70
    71
    72/** @private {(string|!Array.<string|number|!Stream|null|undefined>)} */
    73ServiceBuilder.prototype.stdio_ = 'ignore';
    74
    75
    76/** @private {Object.<string, string>} */
    77ServiceBuilder.prototype.env_ = null;
    78
    79
    80/**
    81 * Sets the port to start the ChromeDriver on.
    82 * @param {number} port The port to use, or 0 for any free port.
    83 * @return {!ServiceBuilder} A self reference.
    84 * @throws {Error} If the port is invalid.
    85 */
    86ServiceBuilder.prototype.usingPort = function(port) {
    87 if (port < 0) {
    88 throw Error('port must be >= 0: ' + port);
    89 }
    90 this.port_ = port;
    91 return this;
    92};
    93
    94
    95/**
    96 * Sets the path of the log file the driver should log to. If a log file is
    97 * not specified, the driver will log to stderr.
    98 * @param {string} path Path of the log file to use.
    99 * @return {!ServiceBuilder} A self reference.
    100 */
    101ServiceBuilder.prototype.loggingTo = function(path) {
    102 this.args_.push('--log-path=' + path);
    103 return this;
    104};
    105
    106
    107/**
    108 * Enables verbose logging.
    109 * @return {!ServiceBuilder} A self reference.
    110 */
    111ServiceBuilder.prototype.enableVerboseLogging = function() {
    112 this.args_.push('--verbose');
    113 return this;
    114};
    115
    116
    117/**
    118 * Sets the number of threads the driver should use to manage HTTP requests.
    119 * By default, the driver will use 4 threads.
    120 * @param {number} n The number of threads to use.
    121 * @return {!ServiceBuilder} A self reference.
    122 */
    123ServiceBuilder.prototype.setNumHttpThreads = function(n) {
    124 this.args_.push('--http-threads=' + n);
    125 return this;
    126};
    127
    128
    129/**
    130 * Sets the base path for WebDriver REST commands (e.g. "/wd/hub").
    131 * By default, the driver will accept commands relative to "/".
    132 * @param {string} path The base path to use.
    133 * @return {!ServiceBuilder} A self reference.
    134 */
    135ServiceBuilder.prototype.setUrlBasePath = function(path) {
    136 this.args_.push('--url-base=' + path);
    137 return this;
    138};
    139
    140
    141/**
    142 * Defines the stdio configuration for the driver service. See
    143 * {@code child_process.spawn} for more information.
    144 * @param {(string|!Array.<string|number|!Stream|null|undefined>)} config The
    145 * configuration to use.
    146 * @return {!ServiceBuilder} A self reference.
    147 */
    148ServiceBuilder.prototype.setStdio = function(config) {
    149 this.stdio_ = config;
    150 return this;
    151};
    152
    153
    154/**
    155 * Defines the environment to start the server under. This settings will be
    156 * inherited by every browser session started by the server.
    157 * @param {!Object.<string, string>} env The environment to use.
    158 * @return {!ServiceBuilder} A self reference.
    159 */
    160ServiceBuilder.prototype.withEnvironment = function(env) {
    161 this.env_ = env;
    162 return this;
    163};
    164
    165
    166/**
    167 * Creates a new DriverService using this instance's current configuration.
    168 * @return {remote.DriverService} A new driver service using this instance's
    169 * current configuration.
    170 * @throws {Error} If the driver exectuable was not specified and a default
    171 * could not be found on the current PATH.
    172 */
    173ServiceBuilder.prototype.build = function() {
    174 var port = this.port_ || portprober.findFreePort();
    175 var args = this.args_.concat(); // Defensive copy.
    176
    177 return new remote.DriverService(this.exe_, {
    178 loopback: true,
    179 port: port,
    180 args: webdriver.promise.when(port, function(port) {
    181 return args.concat('--port=' + port);
    182 }),
    183 env: this.env_,
    184 stdio: this.stdio_
    185 });
    186};
    187
    188
    189/** @type {remote.DriverService} */
    190var defaultService = null;
    191
    192
    193/**
    194 * Sets the default service to use for new ChromeDriver instances.
    195 * @param {!remote.DriverService} service The service to use.
    196 * @throws {Error} If the default service is currently running.
    197 */
    198function setDefaultService(service) {
    199 if (defaultService && defaultService.isRunning()) {
    200 throw Error(
    201 'The previously configured ChromeDriver service is still running. ' +
    202 'You must shut it down before you may adjust its configuration.');
    203 }
    204 defaultService = service;
    205}
    206
    207
    208/**
    209 * Returns the default ChromeDriver service. If such a service has not been
    210 * configured, one will be constructed using the default configuration for
    211 * a ChromeDriver executable found on the system PATH.
    212 * @return {!remote.DriverService} The default ChromeDriver service.
    213 */
    214function getDefaultService() {
    215 if (!defaultService) {
    216 defaultService = new ServiceBuilder().build();
    217 }
    218 return defaultService;
    219}
    220
    221
    222/**
    223 * @type {string}
    224 * @const
    225 */
    226var OPTIONS_CAPABILITY_KEY = 'chromeOptions';
    227
    228
    229/**
    230 * Class for managing ChromeDriver specific options.
    231 * @constructor
    232 */
    233var Options = function() {
    234 /** @private {!Array.<string>} */
    235 this.args_ = [];
    236
    237 /** @private {!Array.<(string|!Buffer)>} */
    238 this.extensions_ = [];
    239};
    240
    241
    242/**
    243 * Extracts the ChromeDriver specific options from the given capabilities
    244 * object.
    245 * @param {!webdriver.Capabilities} capabilities The capabilities object.
    246 * @return {!Options} The ChromeDriver options.
    247 */
    248Options.fromCapabilities = function(capabilities) {
    249 var options = new Options();
    250
    251 var o = capabilities.get(OPTIONS_CAPABILITY_KEY);
    252 if (o instanceof Options) {
    253 options = o;
    254 } else if (o) {
    255 options.
    256 addArguments(o.args || []).
    257 addExtensions(o.extensions || []).
    258 detachDriver(!!o.detach).
    259 setChromeBinaryPath(o.binary).
    260 setChromeLogFile(o.logFile).
    261 setLocalState(o.localState).
    262 setUserPreferences(o.prefs);
    263 }
    264
    265 if (capabilities.has(webdriver.Capability.PROXY)) {
    266 options.setProxy(capabilities.get(webdriver.Capability.PROXY));
    267 }
    268
    269 if (capabilities.has(webdriver.Capability.LOGGING_PREFS)) {
    270 options.setLoggingPreferences(
    271 capabilities.get(webdriver.Capability.LOGGING_PREFS));
    272 }
    273
    274 return options;
    275};
    276
    277
    278/**
    279 * Add additional command line arguments to use when launching the Chrome
    280 * browser. Each argument may be specified with or without the "--" prefix
    281 * (e.g. "--foo" and "foo"). Arguments with an associated value should be
    282 * delimited by an "=": "foo=bar".
    283 * @param {...(string|!Array.<string>)} var_args The arguments to add.
    284 * @return {!Options} A self reference.
    285 */
    286Options.prototype.addArguments = function(var_args) {
    287 this.args_ = this.args_.concat.apply(this.args_, arguments);
    288 return this;
    289};
    290
    291
    292/**
    293 * Add additional extensions to install when launching Chrome. Each extension
    294 * should be specified as the path to the packed CRX file, or a Buffer for an
    295 * extension.
    296 * @param {...(string|!Buffer|!Array.<(string|!Buffer)>)} var_args The
    297 * extensions to add.
    298 * @return {!Options} A self reference.
    299 */
    300Options.prototype.addExtensions = function(var_args) {
    301 this.extensions_ = this.extensions_.concat.apply(
    302 this.extensions_, arguments);
    303 return this;
    304};
    305
    306
    307/**
    308 * Sets the path to the Chrome binary to use. On Mac OS X, this path should
    309 * reference the actual Chrome executable, not just the application binary
    310 * (e.g. "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome").
    311 *
    312 * The binary path be absolute or relative to the chromedriver server
    313 * executable, but it must exist on the machine that will launch Chrome.
    314 *
    315 * @param {string} path The path to the Chrome binary to use.
    316 * @return {!Options} A self reference.
    317 */
    318Options.prototype.setChromeBinaryPath = function(path) {
    319 this.binary_ = path;
    320 return this;
    321};
    322
    323
    324/**
    325 * Sets whether to leave the started Chrome browser running if the controlling
    326 * ChromeDriver service is killed before {@link webdriver.WebDriver#quit()} is
    327 * called.
    328 * @param {boolean} detach Whether to leave the browser running if the
    329 * chromedriver service is killed before the session.
    330 * @return {!Options} A self reference.
    331 */
    332Options.prototype.detachDriver = function(detach) {
    333 this.detach_ = detach;
    334 return this;
    335};
    336
    337
    338/**
    339 * Sets the user preferences for Chrome's user profile. See the "Preferences"
    340 * file in Chrome's user data directory for examples.
    341 * @param {!Object} prefs Dictionary of user preferences to use.
    342 * @return {!Options} A self reference.
    343 */
    344Options.prototype.setUserPreferences = function(prefs) {
    345 this.prefs_ = prefs;
    346 return this;
    347};
    348
    349
    350/**
    351 * Sets the logging preferences for the new session.
    352 * @param {!webdriver.logging.Preferences} prefs The logging preferences.
    353 * @return {!Options} A self reference.
    354 */
    355Options.prototype.setLoggingPreferences = function(prefs) {
    356 this.logPrefs_ = prefs;
    357 return this;
    358};
    359
    360
    361/**
    362 * Sets preferences for the "Local State" file in Chrome's user data
    363 * directory.
    364 * @param {!Object} state Dictionary of local state preferences.
    365 * @return {!Options} A self reference.
    366 */
    367Options.prototype.setLocalState = function(state) {
    368 this.localState_ = state;
    369 return this;
    370};
    371
    372
    373/**
    374 * Sets the path to Chrome's log file. This path should exist on the machine
    375 * that will launch Chrome.
    376 * @param {string} path Path to the log file to use.
    377 * @return {!Options} A self reference.
    378 */
    379Options.prototype.setChromeLogFile = function(path) {
    380 this.logFile_ = path;
    381 return this;
    382};
    383
    384
    385/**
    386 * Sets the proxy settings for the new session.
    387 * @param {ProxyConfig} proxy The proxy configuration to use.
    388 * @return {!Options} A self reference.
    389 */
    390Options.prototype.setProxy = function(proxy) {
    391 this.proxy_ = proxy;
    392 return this;
    393};
    394
    395
    396/**
    397 * Converts this options instance to a {@link webdriver.Capabilities} object.
    398 * @param {webdriver.Capabilities=} opt_capabilities The capabilities to merge
    399 * these options into, if any.
    400 * @return {!webdriver.Capabilities} The capabilities.
    401 */
    402Options.prototype.toCapabilities = function(opt_capabilities) {
    403 var capabilities = opt_capabilities || webdriver.Capabilities.chrome();
    404 capabilities.
    405 set(webdriver.Capability.PROXY, this.proxy_).
    406 set(webdriver.Capability.LOGGING_PREFS, this.logPrefs_).
    407 set(OPTIONS_CAPABILITY_KEY, this);
    408 return capabilities;
    409};
    410
    411
    412/**
    413 * Converts this instance to its JSON wire protocol representation. Note this
    414 * function is an implementation not intended for general use.
    415 * @return {{args: !Array.<string>,
    416 * binary: (string|undefined),
    417 * detach: boolean,
    418 * extensions: !Array.<string>,
    419 * localState: (Object|undefined),
    420 * logFile: (string|undefined),
    421 * prefs: (Object|undefined)}} The JSON wire protocol representation
    422 * of this instance.
    423 */
    424Options.prototype.toJSON = function() {
    425 return {
    426 args: this.args_,
    427 binary: this.binary_,
    428 detach: !!this.detach_,
    429 extensions: this.extensions_.map(function(extension) {
    430 if (Buffer.isBuffer(extension)) {
    431 return extension.toString('base64');
    432 }
    433 return fs.readFileSync(extension, 'base64');
    434 }),
    435 localState: this.localState_,
    436 logFile: this.logFile_,
    437 prefs: this.prefs_
    438 };
    439};
    440
    441
    442/**
    443 * Creates a new ChromeDriver session.
    444 * @param {(webdriver.Capabilities|Options)=} opt_options The session options.
    445 * @param {remote.DriverService=} opt_service The session to use; will use
    446 * the {@link getDefaultService default service} by default.
    447 * @return {!webdriver.WebDriver} A new WebDriver instance.
    448 */
    449function createDriver(opt_options, opt_service) {
    450 var service = opt_service || getDefaultService();
    451 var executor = executors.createExecutor(service.start());
    452
    453 var options = opt_options || new Options();
    454 if (opt_options instanceof webdriver.Capabilities) {
    455 // Extract the Chrome-specific options so we do not send unnecessary
    456 // data across the wire.
    457 options = Options.fromCapabilities(options);
    458 }
    459
    460 return webdriver.WebDriver.createSession(
    461 executor, options.toCapabilities());
    462}
    463
    464
    465
    466// PUBLIC API
    467
    468
    469exports.ServiceBuilder = ServiceBuilder;
    470exports.Options = Options;
    471exports.createDriver = createDriver;
    472exports.getDefaultService = getDefaultService;
    473exports.setDefaultService = setDefaultService;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/error.js.src.html b/node_modules/selenium-webdriver/docs/source/error.js.src.html new file mode 100644 index 0000000..a8aa5b0 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/error.js.src.html @@ -0,0 +1 @@ +error.js

    error.js

    1// Copyright 2014 Selenium committers
    2// Copyright 2014 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16'use strict';
    17
    18var base = require('./_base');
    19
    20
    21/** @type {function(new: bot.Error)} */
    22exports.Error = base.require('bot.Error');
    23
    24/** @type {bot.ErrorCode.} */
    25exports.ErrorCode = base.require('bot.ErrorCode');
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/executors.js.src.html b/node_modules/selenium-webdriver/docs/source/executors.js.src.html new file mode 100644 index 0000000..b44c5ad --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/executors.js.src.html @@ -0,0 +1 @@ +executors.js

    executors.js

    1// Copyright 2013 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Various utilities for working with
    17 * {@link webdriver.CommandExecutor} implementations.
    18 */
    19
    20var HttpClient = require('./http').HttpClient,
    21 HttpExecutor = require('./http').Executor,
    22 promise = require('./_base').require('webdriver.promise');
    23
    24
    25
    26/**
    27 * Wraps a promised {@link webdriver.CommandExecutor}, ensuring no commands
    28 * are executed until the wrapped executor has been fully built.
    29 * @param {!webdriver.promise.Promise.<!webdriver.CommandExecutor>} delegate The
    30 * promised delegate.
    31 * @constructor
    32 * @implements {webdriver.CommandExecutor}
    33 */
    34var DeferredExecutor = function(delegate) {
    35
    36 /** @override */
    37 this.execute = function(command, callback) {
    38 delegate.then(function(executor) {
    39 executor.execute(command, callback);
    40 }, callback);
    41 };
    42};
    43
    44
    45// PUBLIC API
    46
    47
    48/**
    49 * Creates a command executor that uses WebDriver's JSON wire protocol.
    50 * @param {(string|!webdriver.promise.Promise.<string>)} url The server's URL,
    51 * or a promise that will resolve to that URL.
    52 * @returns {!webdriver.CommandExecutor} The new command executor.
    53 */
    54exports.createExecutor = function(url) {
    55 return new DeferredExecutor(promise.when(url, function(url) {
    56 var client = new HttpClient(url);
    57 return new HttpExecutor(client);
    58 }));
    59};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/http/index.js.src.html b/node_modules/selenium-webdriver/docs/source/http/index.js.src.html new file mode 100644 index 0000000..7e08abe --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/http/index.js.src.html @@ -0,0 +1 @@ +index.js

    http/index.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Defines a the {@code webdriver.http.Client} for use with
    17 * NodeJS.
    18 */
    19
    20var http = require('http'),
    21 url = require('url');
    22
    23var base = require('../_base'),
    24 HttpResponse = base.require('webdriver.http.Response');
    25
    26
    27/**
    28 * A {@link webdriver.http.Client} implementation using Node's built-in http
    29 * module.
    30 * @param {string} serverUrl URL for the WebDriver server to send commands to.
    31 * @constructor
    32 * @implements {webdriver.http.Client}
    33 */
    34var HttpClient = function(serverUrl) {
    35 var parsedUrl = url.parse(serverUrl);
    36 if (!parsedUrl.hostname) {
    37 throw new Error('Invalid server URL: ' + serverUrl);
    38 }
    39
    40 /**
    41 * Base options for each request.
    42 * @private {!Object}
    43 */
    44 this.options_ = {
    45 host: parsedUrl.hostname,
    46 path: parsedUrl.pathname,
    47 port: parsedUrl.port
    48 };
    49};
    50
    51
    52/** @override */
    53HttpClient.prototype.send = function(httpRequest, callback) {
    54 var data;
    55 httpRequest.headers['Content-Length'] = 0;
    56 if (httpRequest.method == 'POST' || httpRequest.method == 'PUT') {
    57 data = JSON.stringify(httpRequest.data);
    58 httpRequest.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');
    59 httpRequest.headers['Content-Type'] = 'application/json;charset=UTF-8';
    60 }
    61
    62 var path = this.options_.path;
    63 if (path[path.length - 1] === '/' && httpRequest.path[0] === '/') {
    64 path += httpRequest.path.substring(1);
    65 } else {
    66 path += httpRequest.path;
    67 }
    68
    69 sendRequest({
    70 method: httpRequest.method,
    71 host: this.options_.host,
    72 port: this.options_.port,
    73 path: path,
    74 headers: httpRequest.headers
    75 }, callback, data);
    76};
    77
    78
    79/**
    80 * Sends a single HTTP request.
    81 * @param {!Object} options The request options.
    82 * @param {function(Error, !webdriver.http.Response=)} callback The function to
    83 * invoke with the server's response.
    84 * @param {string=} opt_data The data to send with the request.
    85 */
    86var sendRequest = function(options, callback, opt_data) {
    87 var request = http.request(options, function(response) {
    88 if (response.statusCode == 302 || response.statusCode == 303) {
    89 try {
    90 var location = url.parse(response.headers['location']);
    91 } catch (ex) {
    92 callback(Error(
    93 'Failed to parse "Location" header for server redirect: ' +
    94 ex.message + '\nResponse was: \n' +
    95 new HttpResponse(response.statusCode, response.headers, '')));
    96 return;
    97 }
    98
    99 if (!location.hostname) {
    100 location.hostname = options.host;
    101 location.port = options.port;
    102 }
    103
    104 request.abort();
    105 sendRequest({
    106 method: 'GET',
    107 host: location.hostname,
    108 path: location.pathname + (location.search || ''),
    109 port: location.port,
    110 headers: {
    111 'Accept': 'application/json; charset=utf-8'
    112 }
    113 }, callback);
    114 return;
    115 }
    116
    117 var body = [];
    118 response.on('data', body.push.bind(body));
    119 response.on('end', function() {
    120 var resp = new HttpResponse(response.statusCode,
    121 response.headers, body.join('').replace(/\0/g, ''));
    122 callback(null, resp);
    123 });
    124 });
    125
    126 request.on('error', function(e) {
    127 if (e.code === 'ECONNRESET') {
    128 setTimeout(function() {
    129 sendRequest(options, callback, opt_data);
    130 }, 15);
    131 } else {
    132 var message = e.message;
    133 if (e.code) {
    134 message = e.code + ' ' + message;
    135 }
    136 callback(new Error(message));
    137 }
    138 });
    139
    140 if (opt_data) {
    141 request.write(opt_data);
    142 }
    143
    144 request.end();
    145};
    146
    147
    148// PUBLIC API
    149
    150/** @type {webdriver.http.Executor.} */
    151exports.Executor = base.require('webdriver.http.Executor');
    152
    153/** @type {webdriver.http.Request.} */
    154exports.Request = base.require('webdriver.http.Request');
    155
    156/** @type {webdriver.http.Response.} */
    157exports.Response = base.require('webdriver.http.Response');
    158
    159exports.HttpClient = HttpClient;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/http/util.js.src.html b/node_modules/selenium-webdriver/docs/source/http/util.js.src.html new file mode 100644 index 0000000..f4b4915 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/http/util.js.src.html @@ -0,0 +1 @@ +util.js

    http/util.js

    1// Copyright 2013 Selenium committers
    2// Copyright 2013 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16/**
    17 * @fileoverview Various HTTP utilities.
    18 */
    19
    20var base = require('../_base'),
    21 HttpClient = require('./index').HttpClient,
    22 checkResponse = base.require('bot.response').checkResponse,
    23 Executor = base.require('webdriver.http.Executor'),
    24 HttpRequest = base.require('webdriver.http.Request'),
    25 Command = base.require('webdriver.Command'),
    26 CommandName = base.require('webdriver.CommandName'),
    27 promise = base.require('webdriver.promise');
    28
    29
    30
    31/**
    32 * Queries a WebDriver server for its current status.
    33 * @param {string} url Base URL of the server to query.
    34 * @param {function(Error, *=)} callback The function to call with the
    35 * response.
    36 */
    37function getStatus(url, callback) {
    38 var client = new HttpClient(url);
    39 var executor = new Executor(client);
    40 var command = new Command(CommandName.GET_SERVER_STATUS);
    41 executor.execute(command, function(err, responseObj) {
    42 if (err) return callback(err);
    43 try {
    44 checkResponse(responseObj);
    45 } catch (ex) {
    46 return callback(ex);
    47 }
    48 callback(null, responseObj['value']);
    49 });
    50}
    51
    52
    53// PUBLIC API
    54
    55
    56/**
    57 * Queries a WebDriver server for its current status.
    58 * @param {string} url Base URL of the server to query.
    59 * @return {!webdriver.promise.Promise.<!Object>} A promise that resolves with
    60 * a hash of the server status.
    61 */
    62exports.getStatus = function(url) {
    63 return promise.checkedNodeCall(getStatus.bind(null, url));
    64};
    65
    66
    67/**
    68 * Waits for a WebDriver server to be healthy and accepting requests.
    69 * @param {string} url Base URL of the server to query.
    70 * @param {number} timeout How long to wait for the server.
    71 * @return {!webdriver.promise.Promise} A promise that will resolve when the
    72 * server is ready.
    73 */
    74exports.waitForServer = function(url, timeout) {
    75 var ready = promise.defer(),
    76 start = Date.now(),
    77 checkServerStatus = getStatus.bind(null, url, onResponse);
    78 checkServerStatus();
    79 return ready.promise;
    80
    81 function onResponse(err) {
    82 if (!ready.isPending()) return;
    83 if (!err) return ready.fulfill();
    84
    85 if (Date.now() - start > timeout) {
    86 ready.reject(
    87 Error('Timed out waiting for the WebDriver server at ' + url));
    88 } else {
    89 setTimeout(function() {
    90 if (ready.isPending()) {
    91 checkServerStatus();
    92 }
    93 }, 50);
    94 }
    95 }
    96};
    97
    98
    99/**
    100 * Polls a URL with GET requests until it returns a 2xx response or the
    101 * timeout expires.
    102 * @param {string} url The URL to poll.
    103 * @param {number} timeout How long to wait, in milliseconds.
    104 * @return {!webdriver.promise.Promise} A promise that will resolve when the
    105 * URL responds with 2xx.
    106 */
    107exports.waitForUrl = function(url, timeout) {
    108 var client = new HttpClient(url),
    109 request = new HttpRequest('GET', ''),
    110 testUrl = client.send.bind(client, request, onResponse),
    111 ready = promise.defer(),
    112 start = Date.now();
    113 testUrl();
    114 return ready.promise;
    115
    116 function onResponse(err, response) {
    117 if (!ready.isPending()) return;
    118 if (!err && response.status > 199 && response.status < 300) {
    119 return ready.fulfill();
    120 }
    121
    122 if (Date.now() - start > timeout) {
    123 ready.reject(Error(
    124 'Timed out waiting for the URL to return 2xx: ' + url));
    125 } else {
    126 setTimeout(function() {
    127 if (ready.isPending()) {
    128 testUrl();
    129 }
    130 }, 50);
    131 }
    132 }
    133};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/index.js.src.html b/node_modules/selenium-webdriver/docs/source/index.js.src.html new file mode 100644 index 0000000..b4cc5c6 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/index.js.src.html @@ -0,0 +1 @@ +index.js

    index.js

    1// Copyright 2012 Selenium committers
    2// Copyright 2012 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16/**
    17 * @fileoverview The main user facing module. Exports WebDriver's primary
    18 * public API and provides convenience assessors to certain sub-modules.
    19 */
    20
    21var base = require('./_base');
    22var builder = require('./builder');
    23var error = require('./error');
    24
    25
    26// NOTE: the remainder of this file is nasty and verbose, but the annotations
    27// are necessary to guide the Closure Compiler's type analysis. Without them,
    28// we would not be able to extract any meaningful API documentation.
    29
    30
    31/** @type {function(new: webdriver.ActionSequence)} */
    32exports.ActionSequence = base.require('webdriver.ActionSequence');
    33
    34
    35/** @type {function(new: builder.Builder)} */
    36exports.Builder = builder.Builder;
    37
    38
    39/** @type {webdriver.By.} */
    40exports.By = base.require('webdriver.By');
    41
    42
    43/** @type {function(new: webdriver.Capabilities)} */
    44exports.Capabilities = base.require('webdriver.Capabilities');
    45
    46
    47/** @type {function(new: webdriver.Command)} */
    48exports.Command = base.require('webdriver.Command');
    49
    50
    51/** @type {function(new: webdriver.EventEmitter)} */
    52exports.EventEmitter = base.require('webdriver.EventEmitter');
    53
    54
    55/** @type {function(new: webdriver.Session)} */
    56exports.Session = base.require('webdriver.Session');
    57
    58
    59/** @type {function(new: webdriver.WebDriver)} */
    60exports.WebDriver = base.require('webdriver.WebDriver');
    61
    62
    63/** @type {function(new: webdriver.WebElement)} */
    64exports.WebElement = base.require('webdriver.WebElement');
    65
    66
    67// Export the remainder of our API through getters to keep things cleaner
    68// when this module is used in a REPL environment.
    69
    70
    71/** @type {webdriver.Browser.} */
    72(exports.__defineGetter__('Browser', function() {
    73 return base.require('webdriver.Browser');
    74}));
    75
    76
    77/** @type {webdriver.Button.} */
    78(exports.__defineGetter__('Button', function() {
    79 return base.require('webdriver.Button');
    80}));
    81
    82
    83/** @type {webdriver.Capability.} */
    84(exports.__defineGetter__('Capability', function() {
    85 return base.require('webdriver.Capability');
    86}));
    87
    88
    89/** @type {webdriver.CommandName.} */
    90(exports.__defineGetter__('CommandName', function() {
    91 return base.require('webdriver.CommandName');
    92}));
    93
    94
    95/** @type {webdriver.Key.} */
    96(exports.__defineGetter__('Key', function() {
    97 return base.require('webdriver.Key');
    98}));
    99
    100
    101/** @type {error.} */
    102(exports.__defineGetter__('error', function() {
    103 return error;
    104}));
    105
    106
    107/** @type {error.} */
    108(exports.__defineGetter__('error', function() {
    109 return error;
    110}));
    111
    112
    113/** @type {webdriver.logging.} */
    114(exports.__defineGetter__('logging', function() {
    115 return base.exportPublicApi('webdriver.logging');
    116}));
    117
    118
    119/** @type {webdriver.promise.} */
    120(exports.__defineGetter__('promise', function() {
    121 return base.exportPublicApi('webdriver.promise');
    122}));
    123
    124
    125/** @type {webdriver.stacktrace.} */
    126(exports.__defineGetter__('stacktrace', function() {
    127 return base.exportPublicApi('webdriver.stacktrace');
    128}));
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/io/index.js.src.html b/node_modules/selenium-webdriver/docs/source/io/index.js.src.html new file mode 100644 index 0000000..0a18b2b --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/io/index.js.src.html @@ -0,0 +1 @@ +index.js

    io/index.js

    1// Copyright 2013 Selenium committers
    2// Copyright 2013 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16var fs = require('fs'),
    17 path = require('path');
    18
    19
    20var PATH_SEPARATOR = process.platform === 'win32' ? ';' : ':';
    21
    22
    23// PUBLIC API
    24
    25
    26/**
    27 * Searches the {@code PATH} environment variable for the given file.
    28 * @param {string} file The file to locate on the PATH.
    29 * @param {boolean=} opt_checkCwd Whether to always start with the search with
    30 * the current working directory, regardless of whether it is explicitly
    31 * listed on the PATH.
    32 * @return {?string} Path to the located file, or {@code null} if it could
    33 * not be found.
    34 */
    35exports.findInPath = function(file, opt_checkCwd) {
    36 if (opt_checkCwd) {
    37 var tmp = path.join(process.cwd(), file);
    38 if (fs.existsSync(tmp)) {
    39 return tmp;
    40 }
    41 }
    42
    43 var dirs = process.env['PATH'].split(PATH_SEPARATOR);
    44 var found = null;
    45 dirs.forEach(function(dir) {
    46 var tmp = path.join(dir, file);
    47 if (!found && fs.existsSync(tmp)) {
    48 found = tmp;
    49 }
    50 });
    51 return found;
    52};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/atoms/error.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/atoms/error.js.src.html new file mode 100644 index 0000000..b9696c3 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/atoms/error.js.src.html @@ -0,0 +1 @@ +error.js

    lib/atoms/error.js

    1// Copyright 2010 WebDriver committers
    2// Copyright 2010 Google Inc.
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16/**
    17 * @fileoverview Utilities for working with errors as defined by WebDriver's
    18 * wire protocol: http://code.google.com/p/selenium/wiki/JsonWireProtocol.
    19 */
    20
    21goog.provide('bot.Error');
    22goog.provide('bot.ErrorCode');
    23
    24
    25/**
    26 * Error codes from the WebDriver wire protocol:
    27 * http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes
    28 *
    29 * @enum {number}
    30 */
    31bot.ErrorCode = {
    32 SUCCESS: 0, // Included for completeness
    33
    34 NO_SUCH_ELEMENT: 7,
    35 NO_SUCH_FRAME: 8,
    36 UNKNOWN_COMMAND: 9,
    37 UNSUPPORTED_OPERATION: 9, // Alias.
    38 STALE_ELEMENT_REFERENCE: 10,
    39 ELEMENT_NOT_VISIBLE: 11,
    40 INVALID_ELEMENT_STATE: 12,
    41 UNKNOWN_ERROR: 13,
    42 ELEMENT_NOT_SELECTABLE: 15,
    43 JAVASCRIPT_ERROR: 17,
    44 XPATH_LOOKUP_ERROR: 19,
    45 TIMEOUT: 21,
    46 NO_SUCH_WINDOW: 23,
    47 INVALID_COOKIE_DOMAIN: 24,
    48 UNABLE_TO_SET_COOKIE: 25,
    49 MODAL_DIALOG_OPENED: 26,
    50 NO_MODAL_DIALOG_OPEN: 27,
    51 SCRIPT_TIMEOUT: 28,
    52 INVALID_ELEMENT_COORDINATES: 29,
    53 IME_NOT_AVAILABLE: 30,
    54 IME_ENGINE_ACTIVATION_FAILED: 31,
    55 INVALID_SELECTOR_ERROR: 32,
    56 SESSION_NOT_CREATED: 33,
    57 MOVE_TARGET_OUT_OF_BOUNDS: 34,
    58 SQL_DATABASE_ERROR: 35,
    59 INVALID_XPATH_SELECTOR: 51,
    60 INVALID_XPATH_SELECTOR_RETURN_TYPE: 52,
    61 // The following error codes are derived straight from HTTP return codes.
    62 METHOD_NOT_ALLOWED: 405
    63};
    64
    65
    66
    67/**
    68 * Error extension that includes error status codes from the WebDriver wire
    69 * protocol:
    70 * http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes
    71 *
    72 * @param {!bot.ErrorCode} code The error's status code.
    73 * @param {string=} opt_message Optional error message.
    74 * @constructor
    75 * @extends {Error}
    76 */
    77bot.Error = function(code, opt_message) {
    78
    79 /**
    80 * This error's status code.
    81 * @type {!bot.ErrorCode}
    82 */
    83 this.code = code;
    84
    85 /** @type {string} */
    86 this.state =
    87 bot.Error.CODE_TO_STATE_[code] || bot.Error.State.UNKNOWN_ERROR;
    88
    89 /** @override */
    90 this.message = opt_message || '';
    91
    92 var name = this.state.replace(/((?:^|\s+)[a-z])/g, function(str) {
    93 // IE<9 does not support String#trim(). Also, IE does not include 0xa0
    94 // (the non-breaking-space) in the \s character class, so we have to
    95 // explicitly include it.
    96 return str.toUpperCase().replace(/^[\s\xa0]+/g, '');
    97 });
    98
    99 var l = name.length - 'Error'.length;
    100 if (l < 0 || name.indexOf('Error', l) != l) {
    101 name += 'Error';
    102 }
    103
    104 /** @override */
    105 this.name = name;
    106
    107 // Generate a stacktrace for our custom error; ensure the error has our
    108 // custom name and message so the stack prints correctly in all browsers.
    109 var template = new Error(this.message);
    110 template.name = this.name;
    111
    112 /** @override */
    113 this.stack = template.stack || '';
    114};
    115goog.inherits(bot.Error, Error);
    116
    117
    118/**
    119 * Status strings enumerated in the W3C WebDriver working draft.
    120 * @enum {string}
    121 * @see http://www.w3.org/TR/webdriver/#status-codes
    122 */
    123bot.Error.State = {
    124 ELEMENT_NOT_SELECTABLE: 'element not selectable',
    125 ELEMENT_NOT_VISIBLE: 'element not visible',
    126 IME_ENGINE_ACTIVATION_FAILED: 'ime engine activation failed',
    127 IME_NOT_AVAILABLE: 'ime not available',
    128 INVALID_COOKIE_DOMAIN: 'invalid cookie domain',
    129 INVALID_ELEMENT_COORDINATES: 'invalid element coordinates',
    130 INVALID_ELEMENT_STATE: 'invalid element state',
    131 INVALID_SELECTOR: 'invalid selector',
    132 JAVASCRIPT_ERROR: 'javascript error',
    133 MOVE_TARGET_OUT_OF_BOUNDS: 'move target out of bounds',
    134 NO_SUCH_ALERT: 'no such alert',
    135 NO_SUCH_DOM: 'no such dom',
    136 NO_SUCH_ELEMENT: 'no such element',
    137 NO_SUCH_FRAME: 'no such frame',
    138 NO_SUCH_WINDOW: 'no such window',
    139 SCRIPT_TIMEOUT: 'script timeout',
    140 SESSION_NOT_CREATED: 'session not created',
    141 STALE_ELEMENT_REFERENCE: 'stale element reference',
    142 SUCCESS: 'success',
    143 TIMEOUT: 'timeout',
    144 UNABLE_TO_SET_COOKIE: 'unable to set cookie',
    145 UNEXPECTED_ALERT_OPEN: 'unexpected alert open',
    146 UNKNOWN_COMMAND: 'unknown command',
    147 UNKNOWN_ERROR: 'unknown error',
    148 UNSUPPORTED_OPERATION: 'unsupported operation'
    149};
    150
    151
    152/**
    153 * A map of error codes to state string.
    154 * @private {!Object.<bot.ErrorCode, bot.Error.State>}
    155 */
    156bot.Error.CODE_TO_STATE_ = {};
    157goog.scope(function() {
    158 var map = bot.Error.CODE_TO_STATE_;
    159 var code = bot.ErrorCode;
    160 var state = bot.Error.State;
    161
    162 map[code.ELEMENT_NOT_SELECTABLE] = state.ELEMENT_NOT_SELECTABLE;
    163 map[code.ELEMENT_NOT_VISIBLE] = state.ELEMENT_NOT_VISIBLE;
    164 map[code.IME_ENGINE_ACTIVATION_FAILED] = state.IME_ENGINE_ACTIVATION_FAILED;
    165 map[code.IME_NOT_AVAILABLE] = state.IME_NOT_AVAILABLE;
    166 map[code.INVALID_COOKIE_DOMAIN] = state.INVALID_COOKIE_DOMAIN;
    167 map[code.INVALID_ELEMENT_COORDINATES] = state.INVALID_ELEMENT_COORDINATES;
    168 map[code.INVALID_ELEMENT_STATE] = state.INVALID_ELEMENT_STATE;
    169 map[code.INVALID_SELECTOR_ERROR] = state.INVALID_SELECTOR;
    170 map[code.INVALID_XPATH_SELECTOR] = state.INVALID_SELECTOR;
    171 map[code.INVALID_XPATH_SELECTOR_RETURN_TYPE] = state.INVALID_SELECTOR;
    172 map[code.JAVASCRIPT_ERROR] = state.JAVASCRIPT_ERROR;
    173 map[code.METHOD_NOT_ALLOWED] = state.UNSUPPORTED_OPERATION;
    174 map[code.MOVE_TARGET_OUT_OF_BOUNDS] = state.MOVE_TARGET_OUT_OF_BOUNDS;
    175 map[code.NO_MODAL_DIALOG_OPEN] = state.NO_SUCH_ALERT;
    176 map[code.NO_SUCH_ELEMENT] = state.NO_SUCH_ELEMENT;
    177 map[code.NO_SUCH_FRAME] = state.NO_SUCH_FRAME;
    178 map[code.NO_SUCH_WINDOW] = state.NO_SUCH_WINDOW;
    179 map[code.SCRIPT_TIMEOUT] = state.SCRIPT_TIMEOUT;
    180 map[code.SESSION_NOT_CREATED] = state.SESSION_NOT_CREATED;
    181 map[code.STALE_ELEMENT_REFERENCE] = state.STALE_ELEMENT_REFERENCE;
    182 map[code.SUCCESS] = state.SUCCESS;
    183 map[code.TIMEOUT] = state.TIMEOUT;
    184 map[code.UNABLE_TO_SET_COOKIE] = state.UNABLE_TO_SET_COOKIE;
    185 map[code.MODAL_DIALOG_OPENED] = state.UNEXPECTED_ALERT_OPEN;
    186 map[code.UNKNOWN_ERROR] = state.UNKNOWN_ERROR;
    187 map[code.UNSUPPORTED_OPERATION] = state.UNKNOWN_COMMAND;
    188}); // goog.scope
    189
    190
    191/**
    192 * Flag used for duck-typing when this code is embedded in a Firefox extension.
    193 * This is required since an Error thrown in one component and then reported
    194 * to another will fail instanceof checks in the second component.
    195 * @type {boolean}
    196 */
    197bot.Error.prototype.isAutomationError = true;
    198
    199
    200if (goog.DEBUG) {
    201 /** @return {string} The string representation of this error. */
    202 bot.Error.prototype.toString = function() {
    203 return this.name + ': ' + this.message;
    204 };
    205}
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/atoms/json.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/atoms/json.js.src.html new file mode 100644 index 0000000..a585c2f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/atoms/json.js.src.html @@ -0,0 +1 @@ +json.js

    lib/atoms/json.js

    1// Copyright 2012 WebDriver committers
    2// Copyright 2012 Google Inc.
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16/**
    17 * @fileoverview Provides JSON utilities that uses native JSON parsing where
    18 * possible (a feature not currently offered by Closure).
    19 */
    20
    21goog.provide('bot.json');
    22
    23goog.require('bot.userAgent');
    24goog.require('goog.json');
    25goog.require('goog.userAgent');
    26
    27
    28/**
    29 * @define {boolean} NATIVE_JSON indicates whether the code should rely on the
    30 * native {@code JSON} functions, if available.
    31 *
    32 * <p>The JSON functions can be defined by external libraries like Prototype
    33 * and setting this flag to false forces the use of Closure's goog.json
    34 * implementation.
    35 *
    36 * <p>If your JavaScript can be loaded by a third_party site and you are wary
    37 * about relying on the native functions, specify
    38 * "--define bot.json.NATIVE_JSON=false" to the Closure compiler.
    39 */
    40bot.json.NATIVE_JSON = true;
    41
    42
    43/**
    44 * Whether the current browser supports the native JSON interface.
    45 * @const
    46 * @see http://caniuse.com/#search=JSON
    47 * @private {boolean}
    48 */
    49bot.json.SUPPORTS_NATIVE_JSON_ =
    50 // List WebKit and Opera first since every supported version of these
    51 // browsers supports native JSON (and we can compile away large chunks of
    52 // code for individual fragments by setting the appropriate compiler flags).
    53 goog.userAgent.WEBKIT || goog.userAgent.OPERA ||
    54 (goog.userAgent.GECKO && bot.userAgent.isEngineVersion(3.5)) ||
    55 (goog.userAgent.IE && bot.userAgent.isEngineVersion(8));
    56
    57
    58/**
    59 * Converts a JSON object to its string representation.
    60 * @param {*} jsonObj The input object.
    61 * @param {?(function(string, *): *)=} opt_replacer A replacer function called
    62 * for each (key, value) pair that determines how the value should be
    63 * serialized. By default, this just returns the value and allows default
    64 * serialization to kick in.
    65 * @return {string} A JSON string representation of the input object.
    66 */
    67bot.json.stringify = bot.json.NATIVE_JSON && bot.json.SUPPORTS_NATIVE_JSON_ ?
    68 JSON.stringify : goog.json.serialize;
    69
    70
    71/**
    72 * Parses a JSON string and returns the result.
    73 * @param {string} jsonStr The string to parse.
    74 * @return {*} The JSON object.
    75 * @throws {Error} If the input string is an invalid JSON string.
    76 */
    77bot.json.parse = bot.json.NATIVE_JSON && bot.json.SUPPORTS_NATIVE_JSON_ ?
    78 JSON.parse : goog.json.parse;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/atoms/response.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/atoms/response.js.src.html new file mode 100644 index 0000000..4a2bb7c --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/atoms/response.js.src.html @@ -0,0 +1 @@ +response.js

    lib/atoms/response.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Utilities for working with WebDriver response objects.
    17 * @see: http://code.google.com/p/selenium/wiki/JsonWireProtocol#Responses
    18 */
    19
    20goog.provide('bot.response');
    21goog.provide('bot.response.ResponseObject');
    22
    23goog.require('bot.Error');
    24goog.require('bot.ErrorCode');
    25
    26
    27/**
    28 * Type definition for a response object, as defined by the JSON wire protocol.
    29 * @typedef {{status: bot.ErrorCode, value: (*|{message: string})}}
    30 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Responses
    31 */
    32bot.response.ResponseObject;
    33
    34
    35/**
    36 * @param {*} value The value to test.
    37 * @return {boolean} Whether the given value is a response object.
    38 */
    39bot.response.isResponseObject = function(value) {
    40 return goog.isObject(value) && goog.isNumber(value['status']);
    41};
    42
    43
    44/**
    45 * Creates a new success response object with the provided value.
    46 * @param {*} value The response value.
    47 * @return {!bot.response.ResponseObject} The new response object.
    48 */
    49bot.response.createResponse = function(value) {
    50 if (bot.response.isResponseObject(value)) {
    51 return /** @type {!bot.response.ResponseObject} */ (value);
    52 }
    53 return {
    54 'status': bot.ErrorCode.SUCCESS,
    55 'value': value
    56 };
    57};
    58
    59
    60/**
    61 * Converts an error value into its JSON representation as defined by the
    62 * WebDriver wire protocol.
    63 * @param {(bot.Error|Error|*)} error The error value to convert.
    64 * @return {!bot.response.ResponseObject} The new response object.
    65 */
    66bot.response.createErrorResponse = function(error) {
    67 if (bot.response.isResponseObject(error)) {
    68 return /** @type {!bot.response.ResponseObject} */ (error);
    69 }
    70
    71 var statusCode = error && goog.isNumber(error.code) ? error.code :
    72 bot.ErrorCode.UNKNOWN_ERROR;
    73 return {
    74 'status': /** @type {bot.ErrorCode} */ (statusCode),
    75 'value': {
    76 'message': (error && error.message || error) + ''
    77 }
    78 };
    79};
    80
    81
    82/**
    83 * Checks that a response object does not specify an error as defined by the
    84 * WebDriver wire protocol. If the response object defines an error, it will
    85 * be thrown. Otherwise, the response will be returned as is.
    86 * @param {!bot.response.ResponseObject} responseObj The response object to
    87 * check.
    88 * @return {!bot.response.ResponseObject} The checked response object.
    89 * @throws {bot.Error} If the response describes an error.
    90 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Failed_Commands
    91 */
    92bot.response.checkResponse = function(responseObj) {
    93 var status = responseObj['status'];
    94 if (status == bot.ErrorCode.SUCCESS) {
    95 return responseObj;
    96 }
    97
    98 // If status is not defined, assume an unknown error.
    99 status = status || bot.ErrorCode.UNKNOWN_ERROR;
    100
    101 var value = responseObj['value'];
    102 if (!value || !goog.isObject(value)) {
    103 throw new bot.Error(status, value + '');
    104 }
    105
    106 throw new bot.Error(status, value['message'] + '');
    107};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/atoms/userAgent.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/atoms/userAgent.js.src.html new file mode 100644 index 0000000..9eed02c --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/atoms/userAgent.js.src.html @@ -0,0 +1 @@ +userAgent.js

    lib/atoms/userAgent.js

    1// Copyright 2011 WebDriver committers
    2// Copyright 2011 Google Inc.
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16/**
    17 * @fileoverview Similar to goog.userAgent.isVersion, but with support for
    18 * getting the version information when running in a firefox extension.
    19 */
    20goog.provide('bot.userAgent');
    21
    22goog.require('goog.string');
    23goog.require('goog.userAgent');
    24goog.require('goog.userAgent.product');
    25goog.require('goog.userAgent.product.isVersion');
    26
    27
    28/**
    29 * Whether the rendering engine version of the current browser is equal to or
    30 * greater than the given version. This implementation differs from
    31 * goog.userAgent.isVersion in the following ways:
    32 * <ol>
    33 * <li>in a Firefox extension, tests the engine version through the XUL version
    34 * comparator service, because no window.navigator object is available
    35 * <li>in IE, compares the given version to the current documentMode
    36 * </ol>
    37 *
    38 * @param {string|number} version The version number to check.
    39 * @return {boolean} Whether the browser engine version is the same or higher
    40 * than the given version.
    41 */
    42bot.userAgent.isEngineVersion = function(version) {
    43 if (bot.userAgent.FIREFOX_EXTENSION) {
    44 return bot.userAgent.FIREFOX_EXTENSION_IS_ENGINE_VERSION_(version);
    45 } else if (goog.userAgent.IE) {
    46 return goog.string.compareVersions(
    47 /** @type {number} */ (goog.userAgent.DOCUMENT_MODE), version) >= 0;
    48 } else {
    49 return goog.userAgent.isVersionOrHigher(version);
    50 }
    51};
    52
    53
    54/**
    55 * Whether the product version of the current browser is equal to or greater
    56 * than the given version. This implementation differs from
    57 * goog.userAgent.product.isVersion in the following ways:
    58 * <ol>
    59 * <li>in a Firefox extension, tests the product version through the XUL version
    60 * comparator service, because no window.navigator object is available
    61 * <li>on Android, always compares to the version to the OS version
    62 * </ol>
    63 *
    64 * @param {string|number} version The version number to check.
    65 * @return {boolean} Whether the browser product version is the same or higher
    66 * than the given version.
    67 */
    68bot.userAgent.isProductVersion = function(version) {
    69 if (bot.userAgent.FIREFOX_EXTENSION) {
    70 return bot.userAgent.FIREFOX_EXTENSION_IS_PRODUCT_VERSION_(version);
    71 } else if (goog.userAgent.product.ANDROID) {
    72 return goog.string.compareVersions(
    73 bot.userAgent.ANDROID_VERSION_, version) >= 0;
    74 } else {
    75 return goog.userAgent.product.isVersion(version);
    76 }
    77};
    78
    79
    80/**
    81 * When we are in a Firefox extension, this is a function that accepts a version
    82 * and returns whether the version of Gecko we are on is the same or higher
    83 * than the given version. When we are not in a Firefox extension, this is null.
    84 * @private {(undefined|function((string|number)): boolean)}
    85 */
    86bot.userAgent.FIREFOX_EXTENSION_IS_ENGINE_VERSION_;
    87
    88
    89/**
    90 * When we are in a Firefox extension, this is a function that accepts a version
    91 * and returns whether the version of Firefox we are on is the same or higher
    92 * than the given version. When we are not in a Firefox extension, this is null.
    93 * @private {(undefined|function((string|number)): boolean)}
    94 */
    95bot.userAgent.FIREFOX_EXTENSION_IS_PRODUCT_VERSION_;
    96
    97
    98/**
    99 * Whether we are in a Firefox extension.
    100 *
    101 * @const
    102 * @type {boolean}
    103 */
    104bot.userAgent.FIREFOX_EXTENSION = (function() {
    105 // False if this browser is not a Gecko browser.
    106 if (!goog.userAgent.GECKO) {
    107 return false;
    108 }
    109
    110 // False if this code isn't running in an extension.
    111 var Components = goog.global.Components;
    112 if (!Components) {
    113 return false;
    114 }
    115 try {
    116 if (!Components['classes']) {
    117 return false;
    118 }
    119 } catch (e) {
    120 return false;
    121 }
    122
    123 // Populate the version checker functions.
    124 var cc = Components['classes'];
    125 var ci = Components['interfaces'];
    126 var versionComparator = cc['@mozilla.org/xpcom/version-comparator;1'][
    127 'getService'](ci['nsIVersionComparator']);
    128 var appInfo = cc['@mozilla.org/xre/app-info;1']['getService'](
    129 ci['nsIXULAppInfo']);
    130 var geckoVersion = appInfo['platformVersion'];
    131 var firefoxVersion = appInfo['version'];
    132
    133 bot.userAgent.FIREFOX_EXTENSION_IS_ENGINE_VERSION_ = function(version) {
    134 return versionComparator.compare(geckoVersion, '' + version) >= 0;
    135 };
    136 bot.userAgent.FIREFOX_EXTENSION_IS_PRODUCT_VERSION_ = function(version) {
    137 return versionComparator.compare(firefoxVersion, '' + version) >= 0;
    138 };
    139
    140 return true;
    141})();
    142
    143
    144/**
    145 * Whether we are on IOS.
    146 *
    147 * @const
    148 * @type {boolean}
    149 */
    150bot.userAgent.IOS = goog.userAgent.product.IPAD ||
    151 goog.userAgent.product.IPHONE;
    152
    153
    154/**
    155 * Whether we are on a mobile browser.
    156 *
    157 * @const
    158 * @type {boolean}
    159 */
    160bot.userAgent.MOBILE = bot.userAgent.IOS || goog.userAgent.product.ANDROID;
    161
    162
    163/**
    164 * Android Operating System Version.
    165 * @private {string}
    166 * @const
    167 */
    168bot.userAgent.ANDROID_VERSION_ = (function() {
    169 if (goog.userAgent.product.ANDROID) {
    170 var userAgentString = goog.userAgent.getUserAgentString();
    171 var match = /Android\s+([0-9\.]+)/.exec(userAgentString);
    172 return match ? match[1] : '0';
    173 } else {
    174 return '0';
    175 }
    176})();
    177
    178
    179/**
    180 * Whether the current document is IE in a documentMode older than 8.
    181 * @type {boolean}
    182 * @const
    183 */
    184bot.userAgent.IE_DOC_PRE8 = goog.userAgent.IE &&
    185 !goog.userAgent.isDocumentModeOrHigher(8);
    186
    187
    188/**
    189 * Whether the current document is IE in IE9 (or newer) standards mode.
    190 * @type {boolean}
    191 * @const
    192 */
    193bot.userAgent.IE_DOC_9 = goog.userAgent.isDocumentModeOrHigher(9);
    194
    195
    196/**
    197 * Whether the current document is IE in a documentMode older than 9.
    198 * @type {boolean}
    199 * @const
    200 */
    201bot.userAgent.IE_DOC_PRE9 = goog.userAgent.IE &&
    202 !goog.userAgent.isDocumentModeOrHigher(9);
    203
    204
    205/**
    206 * Whether the current document is IE in IE10 (or newer) standards mode.
    207 * @type {boolean}
    208 * @const
    209 */
    210bot.userAgent.IE_DOC_10 = goog.userAgent.isDocumentModeOrHigher(10);
    211
    212
    213/**
    214 * Whether the current document is IE in a documentMode older than 10.
    215 * @type {boolean}
    216 * @const
    217 */
    218bot.userAgent.IE_DOC_PRE10 = goog.userAgent.IE &&
    219 !goog.userAgent.isDocumentModeOrHigher(10);
    220
    221
    222/**
    223 * Whether the current browser is Android pre-gingerbread.
    224 * @type {boolean}
    225 * @const
    226 */
    227bot.userAgent.ANDROID_PRE_GINGERBREAD = goog.userAgent.product.ANDROID &&
    228 !bot.userAgent.isProductVersion(2.3);
    229
    230
    231/**
    232 * Whether the current browser is Android pre-icecreamsandwich
    233 * @type {boolean}
    234 * @const
    235 */
    236bot.userAgent.ANDROID_PRE_ICECREAMSANDWICH = goog.userAgent.product.ANDROID &&
    237 !bot.userAgent.isProductVersion(4);
    238
    239
    240/**
    241 * Whether the current browser is Safari 6.
    242 * @type {boolean}
    243 * @const
    244 */
    245bot.userAgent.SAFARI_6 = goog.userAgent.product.SAFARI &&
    246 bot.userAgent.isProductVersion(6);
    247
    248
    249/**
    250 * Whether the current browser is Windows Phone.
    251 * @type {boolean}
    252 * @const
    253 */
    254bot.userAgent.WINDOWS_PHONE = goog.userAgent.IE &&
    255 goog.userAgent.getUserAgentString().indexOf('IEMobile') != -1;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/array/array.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/array/array.js.src.html new file mode 100644 index 0000000..78af612 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/array/array.js.src.html @@ -0,0 +1 @@ +array.js

    lib/goog/array/array.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Utilities for manipulating arrays.
    17 *
    18 */
    19
    20
    21goog.provide('goog.array');
    22goog.provide('goog.array.ArrayLike');
    23
    24goog.require('goog.asserts');
    25
    26
    27/**
    28 * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should
    29 * rely on Array.prototype functions, if available.
    30 *
    31 * The Array.prototype functions can be defined by external libraries like
    32 * Prototype and setting this flag to false forces closure to use its own
    33 * goog.array implementation.
    34 *
    35 * If your javascript can be loaded by a third party site and you are wary about
    36 * relying on the prototype functions, specify
    37 * "--define goog.NATIVE_ARRAY_PROTOTYPES=false" to the JSCompiler.
    38 *
    39 * Setting goog.TRUSTED_SITE to false will automatically set
    40 * NATIVE_ARRAY_PROTOTYPES to false.
    41 */
    42goog.define('goog.NATIVE_ARRAY_PROTOTYPES', goog.TRUSTED_SITE);
    43
    44
    45/**
    46 * @define {boolean} If true, JSCompiler will use the native implementation of
    47 * array functions where appropriate (e.g., {@code Array#filter}) and remove the
    48 * unused pure JS implementation.
    49 */
    50goog.define('goog.array.ASSUME_NATIVE_FUNCTIONS', false);
    51
    52
    53/**
    54 * @typedef {Array|NodeList|Arguments|{length: number}}
    55 */
    56goog.array.ArrayLike;
    57
    58
    59/**
    60 * Returns the last element in an array without removing it.
    61 * Same as goog.array.last.
    62 * @param {Array.<T>|goog.array.ArrayLike} array The array.
    63 * @return {T} Last item in array.
    64 * @template T
    65 */
    66goog.array.peek = function(array) {
    67 return array[array.length - 1];
    68};
    69
    70
    71/**
    72 * Returns the last element in an array without removing it.
    73 * Same as goog.array.peek.
    74 * @param {Array.<T>|goog.array.ArrayLike} array The array.
    75 * @return {T} Last item in array.
    76 * @template T
    77 */
    78goog.array.last = goog.array.peek;
    79
    80
    81/**
    82 * Reference to the original {@code Array.prototype}.
    83 * @private
    84 */
    85goog.array.ARRAY_PROTOTYPE_ = Array.prototype;
    86
    87
    88// NOTE(arv): Since most of the array functions are generic it allows you to
    89// pass an array-like object. Strings have a length and are considered array-
    90// like. However, the 'in' operator does not work on strings so we cannot just
    91// use the array path even if the browser supports indexing into strings. We
    92// therefore end up splitting the string.
    93
    94
    95/**
    96 * Returns the index of the first element of an array with a specified value, or
    97 * -1 if the element is not present in the array.
    98 *
    99 * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof}
    100 *
    101 * @param {Array.<T>|goog.array.ArrayLike} arr The array to be searched.
    102 * @param {T} obj The object for which we are searching.
    103 * @param {number=} opt_fromIndex The index at which to start the search. If
    104 * omitted the search starts at index 0.
    105 * @return {number} The index of the first matching array element.
    106 * @template T
    107 */
    108goog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES &&
    109 (goog.array.ASSUME_NATIVE_FUNCTIONS ||
    110 goog.array.ARRAY_PROTOTYPE_.indexOf) ?
    111 function(arr, obj, opt_fromIndex) {
    112 goog.asserts.assert(arr.length != null);
    113
    114 return goog.array.ARRAY_PROTOTYPE_.indexOf.call(arr, obj, opt_fromIndex);
    115 } :
    116 function(arr, obj, opt_fromIndex) {
    117 var fromIndex = opt_fromIndex == null ?
    118 0 : (opt_fromIndex < 0 ?
    119 Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex);
    120
    121 if (goog.isString(arr)) {
    122 // Array.prototype.indexOf uses === so only strings should be found.
    123 if (!goog.isString(obj) || obj.length != 1) {
    124 return -1;
    125 }
    126 return arr.indexOf(obj, fromIndex);
    127 }
    128
    129 for (var i = fromIndex; i < arr.length; i++) {
    130 if (i in arr && arr[i] === obj)
    131 return i;
    132 }
    133 return -1;
    134 };
    135
    136
    137/**
    138 * Returns the index of the last element of an array with a specified value, or
    139 * -1 if the element is not present in the array.
    140 *
    141 * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof}
    142 *
    143 * @param {!Array.<T>|!goog.array.ArrayLike} arr The array to be searched.
    144 * @param {T} obj The object for which we are searching.
    145 * @param {?number=} opt_fromIndex The index at which to start the search. If
    146 * omitted the search starts at the end of the array.
    147 * @return {number} The index of the last matching array element.
    148 * @template T
    149 */
    150goog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES &&
    151 (goog.array.ASSUME_NATIVE_FUNCTIONS ||
    152 goog.array.ARRAY_PROTOTYPE_.lastIndexOf) ?
    153 function(arr, obj, opt_fromIndex) {
    154 goog.asserts.assert(arr.length != null);
    155
    156 // Firefox treats undefined and null as 0 in the fromIndex argument which
    157 // leads it to always return -1
    158 var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;
    159 return goog.array.ARRAY_PROTOTYPE_.lastIndexOf.call(arr, obj, fromIndex);
    160 } :
    161 function(arr, obj, opt_fromIndex) {
    162 var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;
    163
    164 if (fromIndex < 0) {
    165 fromIndex = Math.max(0, arr.length + fromIndex);
    166 }
    167
    168 if (goog.isString(arr)) {
    169 // Array.prototype.lastIndexOf uses === so only strings should be found.
    170 if (!goog.isString(obj) || obj.length != 1) {
    171 return -1;
    172 }
    173 return arr.lastIndexOf(obj, fromIndex);
    174 }
    175
    176 for (var i = fromIndex; i >= 0; i--) {
    177 if (i in arr && arr[i] === obj)
    178 return i;
    179 }
    180 return -1;
    181 };
    182
    183
    184/**
    185 * Calls a function for each element in an array. Skips holes in the array.
    186 * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach}
    187 *
    188 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array like object over
    189 * which to iterate.
    190 * @param {?function(this: S, T, number, ?): ?} f The function to call for every
    191 * element. This function takes 3 arguments (the element, the index and the
    192 * array). The return value is ignored.
    193 * @param {S=} opt_obj The object to be used as the value of 'this' within f.
    194 * @template T,S
    195 */
    196goog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES &&
    197 (goog.array.ASSUME_NATIVE_FUNCTIONS ||
    198 goog.array.ARRAY_PROTOTYPE_.forEach) ?
    199 function(arr, f, opt_obj) {
    200 goog.asserts.assert(arr.length != null);
    201
    202 goog.array.ARRAY_PROTOTYPE_.forEach.call(arr, f, opt_obj);
    203 } :
    204 function(arr, f, opt_obj) {
    205 var l = arr.length; // must be fixed during loop... see docs
    206 var arr2 = goog.isString(arr) ? arr.split('') : arr;
    207 for (var i = 0; i < l; i++) {
    208 if (i in arr2) {
    209 f.call(opt_obj, arr2[i], i, arr);
    210 }
    211 }
    212 };
    213
    214
    215/**
    216 * Calls a function for each element in an array, starting from the last
    217 * element rather than the first.
    218 *
    219 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array
    220 * like object over which to iterate.
    221 * @param {?function(this: S, T, number, ?): ?} f The function to call for every
    222 * element. This function
    223 * takes 3 arguments (the element, the index and the array). The return
    224 * value is ignored.
    225 * @param {S=} opt_obj The object to be used as the value of 'this'
    226 * within f.
    227 * @template T,S
    228 */
    229goog.array.forEachRight = function(arr, f, opt_obj) {
    230 var l = arr.length; // must be fixed during loop... see docs
    231 var arr2 = goog.isString(arr) ? arr.split('') : arr;
    232 for (var i = l - 1; i >= 0; --i) {
    233 if (i in arr2) {
    234 f.call(opt_obj, arr2[i], i, arr);
    235 }
    236 }
    237};
    238
    239
    240/**
    241 * Calls a function for each element in an array, and if the function returns
    242 * true adds the element to a new array.
    243 *
    244 * See {@link http://tinyurl.com/developer-mozilla-org-array-filter}
    245 *
    246 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array
    247 * like object over which to iterate.
    248 * @param {?function(this:S, T, number, ?):boolean} f The function to call for
    249 * every element. This function
    250 * takes 3 arguments (the element, the index and the array) and must
    251 * return a Boolean. If the return value is true the element is added to the
    252 * result array. If it is false the element is not included.
    253 * @param {S=} opt_obj The object to be used as the value of 'this'
    254 * within f.
    255 * @return {!Array.<T>} a new array in which only elements that passed the test
    256 * are present.
    257 * @template T,S
    258 */
    259goog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES &&
    260 (goog.array.ASSUME_NATIVE_FUNCTIONS ||
    261 goog.array.ARRAY_PROTOTYPE_.filter) ?
    262 function(arr, f, opt_obj) {
    263 goog.asserts.assert(arr.length != null);
    264
    265 return goog.array.ARRAY_PROTOTYPE_.filter.call(arr, f, opt_obj);
    266 } :
    267 function(arr, f, opt_obj) {
    268 var l = arr.length; // must be fixed during loop... see docs
    269 var res = [];
    270 var resLength = 0;
    271 var arr2 = goog.isString(arr) ? arr.split('') : arr;
    272 for (var i = 0; i < l; i++) {
    273 if (i in arr2) {
    274 var val = arr2[i]; // in case f mutates arr2
    275 if (f.call(opt_obj, val, i, arr)) {
    276 res[resLength++] = val;
    277 }
    278 }
    279 }
    280 return res;
    281 };
    282
    283
    284/**
    285 * Calls a function for each element in an array and inserts the result into a
    286 * new array.
    287 *
    288 * See {@link http://tinyurl.com/developer-mozilla-org-array-map}
    289 *
    290 * @param {Array.<VALUE>|goog.array.ArrayLike} arr Array or array like object
    291 * over which to iterate.
    292 * @param {function(this:THIS, VALUE, number, ?): RESULT} f The function to call
    293 * for every element. This function takes 3 arguments (the element,
    294 * the index and the array) and should return something. The result will be
    295 * inserted into a new array.
    296 * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.
    297 * @return {!Array.<RESULT>} a new array with the results from f.
    298 * @template THIS, VALUE, RESULT
    299 */
    300goog.array.map = goog.NATIVE_ARRAY_PROTOTYPES &&
    301 (goog.array.ASSUME_NATIVE_FUNCTIONS ||
    302 goog.array.ARRAY_PROTOTYPE_.map) ?
    303 function(arr, f, opt_obj) {
    304 goog.asserts.assert(arr.length != null);
    305
    306 return goog.array.ARRAY_PROTOTYPE_.map.call(arr, f, opt_obj);
    307 } :
    308 function(arr, f, opt_obj) {
    309 var l = arr.length; // must be fixed during loop... see docs
    310 var res = new Array(l);
    311 var arr2 = goog.isString(arr) ? arr.split('') : arr;
    312 for (var i = 0; i < l; i++) {
    313 if (i in arr2) {
    314 res[i] = f.call(opt_obj, arr2[i], i, arr);
    315 }
    316 }
    317 return res;
    318 };
    319
    320
    321/**
    322 * Passes every element of an array into a function and accumulates the result.
    323 *
    324 * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce}
    325 *
    326 * For example:
    327 * var a = [1, 2, 3, 4];
    328 * goog.array.reduce(a, function(r, v, i, arr) {return r + v;}, 0);
    329 * returns 10
    330 *
    331 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array
    332 * like object over which to iterate.
    333 * @param {?function(this:S, R, T, number, ?) : R} f The function to call for
    334 * every element. This function
    335 * takes 4 arguments (the function's previous result or the initial value,
    336 * the value of the current array element, the current array index, and the
    337 * array itself)
    338 * function(previousValue, currentValue, index, array).
    339 * @param {?} val The initial value to pass into the function on the first call.
    340 * @param {S=} opt_obj The object to be used as the value of 'this'
    341 * within f.
    342 * @return {R} Result of evaluating f repeatedly across the values of the array.
    343 * @template T,S,R
    344 */
    345goog.array.reduce = goog.NATIVE_ARRAY_PROTOTYPES &&
    346 (goog.array.ASSUME_NATIVE_FUNCTIONS ||
    347 goog.array.ARRAY_PROTOTYPE_.reduce) ?
    348 function(arr, f, val, opt_obj) {
    349 goog.asserts.assert(arr.length != null);
    350 if (opt_obj) {
    351 f = goog.bind(f, opt_obj);
    352 }
    353 return goog.array.ARRAY_PROTOTYPE_.reduce.call(arr, f, val);
    354 } :
    355 function(arr, f, val, opt_obj) {
    356 var rval = val;
    357 goog.array.forEach(arr, function(val, index) {
    358 rval = f.call(opt_obj, rval, val, index, arr);
    359 });
    360 return rval;
    361 };
    362
    363
    364/**
    365 * Passes every element of an array into a function and accumulates the result,
    366 * starting from the last element and working towards the first.
    367 *
    368 * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright}
    369 *
    370 * For example:
    371 * var a = ['a', 'b', 'c'];
    372 * goog.array.reduceRight(a, function(r, v, i, arr) {return r + v;}, '');
    373 * returns 'cba'
    374 *
    375 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array
    376 * like object over which to iterate.
    377 * @param {?function(this:S, R, T, number, ?) : R} f The function to call for
    378 * every element. This function
    379 * takes 4 arguments (the function's previous result or the initial value,
    380 * the value of the current array element, the current array index, and the
    381 * array itself)
    382 * function(previousValue, currentValue, index, array).
    383 * @param {?} val The initial value to pass into the function on the first call.
    384 * @param {S=} opt_obj The object to be used as the value of 'this'
    385 * within f.
    386 * @return {R} Object returned as a result of evaluating f repeatedly across the
    387 * values of the array.
    388 * @template T,S,R
    389 */
    390goog.array.reduceRight = goog.NATIVE_ARRAY_PROTOTYPES &&
    391 (goog.array.ASSUME_NATIVE_FUNCTIONS ||
    392 goog.array.ARRAY_PROTOTYPE_.reduceRight) ?
    393 function(arr, f, val, opt_obj) {
    394 goog.asserts.assert(arr.length != null);
    395 if (opt_obj) {
    396 f = goog.bind(f, opt_obj);
    397 }
    398 return goog.array.ARRAY_PROTOTYPE_.reduceRight.call(arr, f, val);
    399 } :
    400 function(arr, f, val, opt_obj) {
    401 var rval = val;
    402 goog.array.forEachRight(arr, function(val, index) {
    403 rval = f.call(opt_obj, rval, val, index, arr);
    404 });
    405 return rval;
    406 };
    407
    408
    409/**
    410 * Calls f for each element of an array. If any call returns true, some()
    411 * returns true (without checking the remaining elements). If all calls
    412 * return false, some() returns false.
    413 *
    414 * See {@link http://tinyurl.com/developer-mozilla-org-array-some}
    415 *
    416 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array
    417 * like object over which to iterate.
    418 * @param {?function(this:S, T, number, ?) : boolean} f The function to call for
    419 * for every element. This function takes 3 arguments (the element, the
    420 * index and the array) and should return a boolean.
    421 * @param {S=} opt_obj The object to be used as the value of 'this'
    422 * within f.
    423 * @return {boolean} true if any element passes the test.
    424 * @template T,S
    425 */
    426goog.array.some = goog.NATIVE_ARRAY_PROTOTYPES &&
    427 (goog.array.ASSUME_NATIVE_FUNCTIONS ||
    428 goog.array.ARRAY_PROTOTYPE_.some) ?
    429 function(arr, f, opt_obj) {
    430 goog.asserts.assert(arr.length != null);
    431
    432 return goog.array.ARRAY_PROTOTYPE_.some.call(arr, f, opt_obj);
    433 } :
    434 function(arr, f, opt_obj) {
    435 var l = arr.length; // must be fixed during loop... see docs
    436 var arr2 = goog.isString(arr) ? arr.split('') : arr;
    437 for (var i = 0; i < l; i++) {
    438 if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
    439 return true;
    440 }
    441 }
    442 return false;
    443 };
    444
    445
    446/**
    447 * Call f for each element of an array. If all calls return true, every()
    448 * returns true. If any call returns false, every() returns false and
    449 * does not continue to check the remaining elements.
    450 *
    451 * See {@link http://tinyurl.com/developer-mozilla-org-array-every}
    452 *
    453 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array
    454 * like object over which to iterate.
    455 * @param {?function(this:S, T, number, ?) : boolean} f The function to call for
    456 * for every element. This function takes 3 arguments (the element, the
    457 * index and the array) and should return a boolean.
    458 * @param {S=} opt_obj The object to be used as the value of 'this'
    459 * within f.
    460 * @return {boolean} false if any element fails the test.
    461 * @template T,S
    462 */
    463goog.array.every = goog.NATIVE_ARRAY_PROTOTYPES &&
    464 (goog.array.ASSUME_NATIVE_FUNCTIONS ||
    465 goog.array.ARRAY_PROTOTYPE_.every) ?
    466 function(arr, f, opt_obj) {
    467 goog.asserts.assert(arr.length != null);
    468
    469 return goog.array.ARRAY_PROTOTYPE_.every.call(arr, f, opt_obj);
    470 } :
    471 function(arr, f, opt_obj) {
    472 var l = arr.length; // must be fixed during loop... see docs
    473 var arr2 = goog.isString(arr) ? arr.split('') : arr;
    474 for (var i = 0; i < l; i++) {
    475 if (i in arr2 && !f.call(opt_obj, arr2[i], i, arr)) {
    476 return false;
    477 }
    478 }
    479 return true;
    480 };
    481
    482
    483/**
    484 * Counts the array elements that fulfill the predicate, i.e. for which the
    485 * callback function returns true. Skips holes in the array.
    486 *
    487 * @param {!(Array.<T>|goog.array.ArrayLike)} arr Array or array like object
    488 * over which to iterate.
    489 * @param {function(this: S, T, number, ?): boolean} f The function to call for
    490 * every element. Takes 3 arguments (the element, the index and the array).
    491 * @param {S=} opt_obj The object to be used as the value of 'this' within f.
    492 * @return {number} The number of the matching elements.
    493 * @template T,S
    494 */
    495goog.array.count = function(arr, f, opt_obj) {
    496 var count = 0;
    497 goog.array.forEach(arr, function(element, index, arr) {
    498 if (f.call(opt_obj, element, index, arr)) {
    499 ++count;
    500 }
    501 }, opt_obj);
    502 return count;
    503};
    504
    505
    506/**
    507 * Search an array for the first element that satisfies a given condition and
    508 * return that element.
    509 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array
    510 * like object over which to iterate.
    511 * @param {?function(this:S, T, number, ?) : boolean} f The function to call
    512 * for every element. This function takes 3 arguments (the element, the
    513 * index and the array) and should return a boolean.
    514 * @param {S=} opt_obj An optional "this" context for the function.
    515 * @return {?T} The first array element that passes the test, or null if no
    516 * element is found.
    517 * @template T,S
    518 */
    519goog.array.find = function(arr, f, opt_obj) {
    520 var i = goog.array.findIndex(arr, f, opt_obj);
    521 return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];
    522};
    523
    524
    525/**
    526 * Search an array for the first element that satisfies a given condition and
    527 * return its index.
    528 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array
    529 * like object over which to iterate.
    530 * @param {?function(this:S, T, number, ?) : boolean} f The function to call for
    531 * every element. This function
    532 * takes 3 arguments (the element, the index and the array) and should
    533 * return a boolean.
    534 * @param {S=} opt_obj An optional "this" context for the function.
    535 * @return {number} The index of the first array element that passes the test,
    536 * or -1 if no element is found.
    537 * @template T,S
    538 */
    539goog.array.findIndex = function(arr, f, opt_obj) {
    540 var l = arr.length; // must be fixed during loop... see docs
    541 var arr2 = goog.isString(arr) ? arr.split('') : arr;
    542 for (var i = 0; i < l; i++) {
    543 if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
    544 return i;
    545 }
    546 }
    547 return -1;
    548};
    549
    550
    551/**
    552 * Search an array (in reverse order) for the last element that satisfies a
    553 * given condition and return that element.
    554 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array
    555 * like object over which to iterate.
    556 * @param {?function(this:S, T, number, ?) : boolean} f The function to call
    557 * for every element. This function
    558 * takes 3 arguments (the element, the index and the array) and should
    559 * return a boolean.
    560 * @param {S=} opt_obj An optional "this" context for the function.
    561 * @return {?T} The last array element that passes the test, or null if no
    562 * element is found.
    563 * @template T,S
    564 */
    565goog.array.findRight = function(arr, f, opt_obj) {
    566 var i = goog.array.findIndexRight(arr, f, opt_obj);
    567 return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];
    568};
    569
    570
    571/**
    572 * Search an array (in reverse order) for the last element that satisfies a
    573 * given condition and return its index.
    574 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array
    575 * like object over which to iterate.
    576 * @param {?function(this:S, T, number, ?) : boolean} f The function to call
    577 * for every element. This function
    578 * takes 3 arguments (the element, the index and the array) and should
    579 * return a boolean.
    580 * @param {Object=} opt_obj An optional "this" context for the function.
    581 * @return {number} The index of the last array element that passes the test,
    582 * or -1 if no element is found.
    583 * @template T,S
    584 */
    585goog.array.findIndexRight = function(arr, f, opt_obj) {
    586 var l = arr.length; // must be fixed during loop... see docs
    587 var arr2 = goog.isString(arr) ? arr.split('') : arr;
    588 for (var i = l - 1; i >= 0; i--) {
    589 if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
    590 return i;
    591 }
    592 }
    593 return -1;
    594};
    595
    596
    597/**
    598 * Whether the array contains the given object.
    599 * @param {goog.array.ArrayLike} arr The array to test for the presence of the
    600 * element.
    601 * @param {*} obj The object for which to test.
    602 * @return {boolean} true if obj is present.
    603 */
    604goog.array.contains = function(arr, obj) {
    605 return goog.array.indexOf(arr, obj) >= 0;
    606};
    607
    608
    609/**
    610 * Whether the array is empty.
    611 * @param {goog.array.ArrayLike} arr The array to test.
    612 * @return {boolean} true if empty.
    613 */
    614goog.array.isEmpty = function(arr) {
    615 return arr.length == 0;
    616};
    617
    618
    619/**
    620 * Clears the array.
    621 * @param {goog.array.ArrayLike} arr Array or array like object to clear.
    622 */
    623goog.array.clear = function(arr) {
    624 // For non real arrays we don't have the magic length so we delete the
    625 // indices.
    626 if (!goog.isArray(arr)) {
    627 for (var i = arr.length - 1; i >= 0; i--) {
    628 delete arr[i];
    629 }
    630 }
    631 arr.length = 0;
    632};
    633
    634
    635/**
    636 * Pushes an item into an array, if it's not already in the array.
    637 * @param {Array.<T>} arr Array into which to insert the item.
    638 * @param {T} obj Value to add.
    639 * @template T
    640 */
    641goog.array.insert = function(arr, obj) {
    642 if (!goog.array.contains(arr, obj)) {
    643 arr.push(obj);
    644 }
    645};
    646
    647
    648/**
    649 * Inserts an object at the given index of the array.
    650 * @param {goog.array.ArrayLike} arr The array to modify.
    651 * @param {*} obj The object to insert.
    652 * @param {number=} opt_i The index at which to insert the object. If omitted,
    653 * treated as 0. A negative index is counted from the end of the array.
    654 */
    655goog.array.insertAt = function(arr, obj, opt_i) {
    656 goog.array.splice(arr, opt_i, 0, obj);
    657};
    658
    659
    660/**
    661 * Inserts at the given index of the array, all elements of another array.
    662 * @param {goog.array.ArrayLike} arr The array to modify.
    663 * @param {goog.array.ArrayLike} elementsToAdd The array of elements to add.
    664 * @param {number=} opt_i The index at which to insert the object. If omitted,
    665 * treated as 0. A negative index is counted from the end of the array.
    666 */
    667goog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) {
    668 goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd);
    669};
    670
    671
    672/**
    673 * Inserts an object into an array before a specified object.
    674 * @param {Array.<T>} arr The array to modify.
    675 * @param {T} obj The object to insert.
    676 * @param {T=} opt_obj2 The object before which obj should be inserted. If obj2
    677 * is omitted or not found, obj is inserted at the end of the array.
    678 * @template T
    679 */
    680goog.array.insertBefore = function(arr, obj, opt_obj2) {
    681 var i;
    682 if (arguments.length == 2 || (i = goog.array.indexOf(arr, opt_obj2)) < 0) {
    683 arr.push(obj);
    684 } else {
    685 goog.array.insertAt(arr, obj, i);
    686 }
    687};
    688
    689
    690/**
    691 * Removes the first occurrence of a particular value from an array.
    692 * @param {Array.<T>|goog.array.ArrayLike} arr Array from which to remove
    693 * value.
    694 * @param {T} obj Object to remove.
    695 * @return {boolean} True if an element was removed.
    696 * @template T
    697 */
    698goog.array.remove = function(arr, obj) {
    699 var i = goog.array.indexOf(arr, obj);
    700 var rv;
    701 if ((rv = i >= 0)) {
    702 goog.array.removeAt(arr, i);
    703 }
    704 return rv;
    705};
    706
    707
    708/**
    709 * Removes from an array the element at index i
    710 * @param {goog.array.ArrayLike} arr Array or array like object from which to
    711 * remove value.
    712 * @param {number} i The index to remove.
    713 * @return {boolean} True if an element was removed.
    714 */
    715goog.array.removeAt = function(arr, i) {
    716 goog.asserts.assert(arr.length != null);
    717
    718 // use generic form of splice
    719 // splice returns the removed items and if successful the length of that
    720 // will be 1
    721 return goog.array.ARRAY_PROTOTYPE_.splice.call(arr, i, 1).length == 1;
    722};
    723
    724
    725/**
    726 * Removes the first value that satisfies the given condition.
    727 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array
    728 * like object over which to iterate.
    729 * @param {?function(this:S, T, number, ?) : boolean} f The function to call
    730 * for every element. This function
    731 * takes 3 arguments (the element, the index and the array) and should
    732 * return a boolean.
    733 * @param {S=} opt_obj An optional "this" context for the function.
    734 * @return {boolean} True if an element was removed.
    735 * @template T,S
    736 */
    737goog.array.removeIf = function(arr, f, opt_obj) {
    738 var i = goog.array.findIndex(arr, f, opt_obj);
    739 if (i >= 0) {
    740 goog.array.removeAt(arr, i);
    741 return true;
    742 }
    743 return false;
    744};
    745
    746
    747/**
    748 * Returns a new array that is the result of joining the arguments. If arrays
    749 * are passed then their items are added, however, if non-arrays are passed they
    750 * will be added to the return array as is.
    751 *
    752 * Note that ArrayLike objects will be added as is, rather than having their
    753 * items added.
    754 *
    755 * goog.array.concat([1, 2], [3, 4]) -> [1, 2, 3, 4]
    756 * goog.array.concat(0, [1, 2]) -> [0, 1, 2]
    757 * goog.array.concat([1, 2], null) -> [1, 2, null]
    758 *
    759 * There is bug in all current versions of IE (6, 7 and 8) where arrays created
    760 * in an iframe become corrupted soon (not immediately) after the iframe is
    761 * destroyed. This is common if loading data via goog.net.IframeIo, for example.
    762 * This corruption only affects the concat method which will start throwing
    763 * Catastrophic Errors (#-2147418113).
    764 *
    765 * See http://endoflow.com/scratch/corrupted-arrays.html for a test case.
    766 *
    767 * Internally goog.array should use this, so that all methods will continue to
    768 * work on these broken array objects.
    769 *
    770 * @param {...*} var_args Items to concatenate. Arrays will have each item
    771 * added, while primitives and objects will be added as is.
    772 * @return {!Array} The new resultant array.
    773 */
    774goog.array.concat = function(var_args) {
    775 return goog.array.ARRAY_PROTOTYPE_.concat.apply(
    776 goog.array.ARRAY_PROTOTYPE_, arguments);
    777};
    778
    779
    780/**
    781 * Returns a new array that contains the contents of all the arrays passed.
    782 * @param {...!Array.<T>} var_args
    783 * @return {!Array.<T>}
    784 * @template T
    785 */
    786goog.array.join = function(var_args) {
    787 return goog.array.ARRAY_PROTOTYPE_.concat.apply(
    788 goog.array.ARRAY_PROTOTYPE_, arguments);
    789};
    790
    791
    792/**
    793 * Converts an object to an array.
    794 * @param {Array.<T>|goog.array.ArrayLike} object The object to convert to an
    795 * array.
    796 * @return {!Array.<T>} The object converted into an array. If object has a
    797 * length property, every property indexed with a non-negative number
    798 * less than length will be included in the result. If object does not
    799 * have a length property, an empty array will be returned.
    800 * @template T
    801 */
    802goog.array.toArray = function(object) {
    803 var length = object.length;
    804
    805 // If length is not a number the following it false. This case is kept for
    806 // backwards compatibility since there are callers that pass objects that are
    807 // not array like.
    808 if (length > 0) {
    809 var rv = new Array(length);
    810 for (var i = 0; i < length; i++) {
    811 rv[i] = object[i];
    812 }
    813 return rv;
    814 }
    815 return [];
    816};
    817
    818
    819/**
    820 * Does a shallow copy of an array.
    821 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array-like object to
    822 * clone.
    823 * @return {!Array.<T>} Clone of the input array.
    824 * @template T
    825 */
    826goog.array.clone = goog.array.toArray;
    827
    828
    829/**
    830 * Extends an array with another array, element, or "array like" object.
    831 * This function operates 'in-place', it does not create a new Array.
    832 *
    833 * Example:
    834 * var a = [];
    835 * goog.array.extend(a, [0, 1]);
    836 * a; // [0, 1]
    837 * goog.array.extend(a, 2);
    838 * a; // [0, 1, 2]
    839 *
    840 * @param {Array.<VALUE>} arr1 The array to modify.
    841 * @param {...(Array.<VALUE>|VALUE)} var_args The elements or arrays of elements
    842 * to add to arr1.
    843 * @template VALUE
    844 */
    845goog.array.extend = function(arr1, var_args) {
    846 for (var i = 1; i < arguments.length; i++) {
    847 var arr2 = arguments[i];
    848 // If we have an Array or an Arguments object we can just call push
    849 // directly.
    850 var isArrayLike;
    851 if (goog.isArray(arr2) ||
    852 // Detect Arguments. ES5 says that the [[Class]] of an Arguments object
    853 // is "Arguments" but only V8 and JSC/Safari gets this right. We instead
    854 // detect Arguments by checking for array like and presence of "callee".
    855 (isArrayLike = goog.isArrayLike(arr2)) &&
    856 // The getter for callee throws an exception in strict mode
    857 // according to section 10.6 in ES5 so check for presence instead.
    858 Object.prototype.hasOwnProperty.call(arr2, 'callee')) {
    859 arr1.push.apply(arr1, arr2);
    860 } else if (isArrayLike) {
    861 // Otherwise loop over arr2 to prevent copying the object.
    862 var len1 = arr1.length;
    863 var len2 = arr2.length;
    864 for (var j = 0; j < len2; j++) {
    865 arr1[len1 + j] = arr2[j];
    866 }
    867 } else {
    868 arr1.push(arr2);
    869 }
    870 }
    871};
    872
    873
    874/**
    875 * Adds or removes elements from an array. This is a generic version of Array
    876 * splice. This means that it might work on other objects similar to arrays,
    877 * such as the arguments object.
    878 *
    879 * @param {Array.<T>|goog.array.ArrayLike} arr The array to modify.
    880 * @param {number|undefined} index The index at which to start changing the
    881 * array. If not defined, treated as 0.
    882 * @param {number} howMany How many elements to remove (0 means no removal. A
    883 * value below 0 is treated as zero and so is any other non number. Numbers
    884 * are floored).
    885 * @param {...T} var_args Optional, additional elements to insert into the
    886 * array.
    887 * @return {!Array.<T>} the removed elements.
    888 * @template T
    889 */
    890goog.array.splice = function(arr, index, howMany, var_args) {
    891 goog.asserts.assert(arr.length != null);
    892
    893 return goog.array.ARRAY_PROTOTYPE_.splice.apply(
    894 arr, goog.array.slice(arguments, 1));
    895};
    896
    897
    898/**
    899 * Returns a new array from a segment of an array. This is a generic version of
    900 * Array slice. This means that it might work on other objects similar to
    901 * arrays, such as the arguments object.
    902 *
    903 * @param {Array.<T>|goog.array.ArrayLike} arr The array from
    904 * which to copy a segment.
    905 * @param {number} start The index of the first element to copy.
    906 * @param {number=} opt_end The index after the last element to copy.
    907 * @return {!Array.<T>} A new array containing the specified segment of the
    908 * original array.
    909 * @template T
    910 */
    911goog.array.slice = function(arr, start, opt_end) {
    912 goog.asserts.assert(arr.length != null);
    913
    914 // passing 1 arg to slice is not the same as passing 2 where the second is
    915 // null or undefined (in that case the second argument is treated as 0).
    916 // we could use slice on the arguments object and then use apply instead of
    917 // testing the length
    918 if (arguments.length <= 2) {
    919 return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start);
    920 } else {
    921 return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start, opt_end);
    922 }
    923};
    924
    925
    926/**
    927 * Removes all duplicates from an array (retaining only the first
    928 * occurrence of each array element). This function modifies the
    929 * array in place and doesn't change the order of the non-duplicate items.
    930 *
    931 * For objects, duplicates are identified as having the same unique ID as
    932 * defined by {@link goog.getUid}.
    933 *
    934 * Alternatively you can specify a custom hash function that returns a unique
    935 * value for each item in the array it should consider unique.
    936 *
    937 * Runtime: N,
    938 * Worstcase space: 2N (no dupes)
    939 *
    940 * @param {Array.<T>|goog.array.ArrayLike} arr The array from which to remove
    941 * duplicates.
    942 * @param {Array=} opt_rv An optional array in which to return the results,
    943 * instead of performing the removal inplace. If specified, the original
    944 * array will remain unchanged.
    945 * @param {function(T):string=} opt_hashFn An optional function to use to
    946 * apply to every item in the array. This function should return a unique
    947 * value for each item in the array it should consider unique.
    948 * @template T
    949 */
    950goog.array.removeDuplicates = function(arr, opt_rv, opt_hashFn) {
    951 var returnArray = opt_rv || arr;
    952 var defaultHashFn = function(item) {
    953 // Prefix each type with a single character representing the type to
    954 // prevent conflicting keys (e.g. true and 'true').
    955 return goog.isObject(current) ? 'o' + goog.getUid(current) :
    956 (typeof current).charAt(0) + current;
    957 };
    958 var hashFn = opt_hashFn || defaultHashFn;
    959
    960 var seen = {}, cursorInsert = 0, cursorRead = 0;
    961 while (cursorRead < arr.length) {
    962 var current = arr[cursorRead++];
    963 var key = hashFn(current);
    964 if (!Object.prototype.hasOwnProperty.call(seen, key)) {
    965 seen[key] = true;
    966 returnArray[cursorInsert++] = current;
    967 }
    968 }
    969 returnArray.length = cursorInsert;
    970};
    971
    972
    973/**
    974 * Searches the specified array for the specified target using the binary
    975 * search algorithm. If no opt_compareFn is specified, elements are compared
    976 * using <code>goog.array.defaultCompare</code>, which compares the elements
    977 * using the built in < and > operators. This will produce the expected
    978 * behavior for homogeneous arrays of String(s) and Number(s). The array
    979 * specified <b>must</b> be sorted in ascending order (as defined by the
    980 * comparison function). If the array is not sorted, results are undefined.
    981 * If the array contains multiple instances of the specified target value, any
    982 * of these instances may be found.
    983 *
    984 * Runtime: O(log n)
    985 *
    986 * @param {Array.<VALUE>|goog.array.ArrayLike} arr The array to be searched.
    987 * @param {TARGET} target The sought value.
    988 * @param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison
    989 * function by which the array is ordered. Should take 2 arguments to
    990 * compare, and return a negative number, zero, or a positive number
    991 * depending on whether the first argument is less than, equal to, or
    992 * greater than the second.
    993 * @return {number} Lowest index of the target value if found, otherwise
    994 * (-(insertion point) - 1). The insertion point is where the value should
    995 * be inserted into arr to preserve the sorted property. Return value >= 0
    996 * iff target is found.
    997 * @template TARGET, VALUE
    998 */
    999goog.array.binarySearch = function(arr, target, opt_compareFn) {
    1000 return goog.array.binarySearch_(arr,
    1001 opt_compareFn || goog.array.defaultCompare, false /* isEvaluator */,
    1002 target);
    1003};
    1004
    1005
    1006/**
    1007 * Selects an index in the specified array using the binary search algorithm.
    1008 * The evaluator receives an element and determines whether the desired index
    1009 * is before, at, or after it. The evaluator must be consistent (formally,
    1010 * goog.array.map(goog.array.map(arr, evaluator, opt_obj), goog.math.sign)
    1011 * must be monotonically non-increasing).
    1012 *
    1013 * Runtime: O(log n)
    1014 *
    1015 * @param {Array.<VALUE>|goog.array.ArrayLike} arr The array to be searched.
    1016 * @param {function(this:THIS, VALUE, number, ?): number} evaluator
    1017 * Evaluator function that receives 3 arguments (the element, the index and
    1018 * the array). Should return a negative number, zero, or a positive number
    1019 * depending on whether the desired index is before, at, or after the
    1020 * element passed to it.
    1021 * @param {THIS=} opt_obj The object to be used as the value of 'this'
    1022 * within evaluator.
    1023 * @return {number} Index of the leftmost element matched by the evaluator, if
    1024 * such exists; otherwise (-(insertion point) - 1). The insertion point is
    1025 * the index of the first element for which the evaluator returns negative,
    1026 * or arr.length if no such element exists. The return value is non-negative
    1027 * iff a match is found.
    1028 * @template THIS, VALUE
    1029 */
    1030goog.array.binarySelect = function(arr, evaluator, opt_obj) {
    1031 return goog.array.binarySearch_(arr, evaluator, true /* isEvaluator */,
    1032 undefined /* opt_target */, opt_obj);
    1033};
    1034
    1035
    1036/**
    1037 * Implementation of a binary search algorithm which knows how to use both
    1038 * comparison functions and evaluators. If an evaluator is provided, will call
    1039 * the evaluator with the given optional data object, conforming to the
    1040 * interface defined in binarySelect. Otherwise, if a comparison function is
    1041 * provided, will call the comparison function against the given data object.
    1042 *
    1043 * This implementation purposefully does not use goog.bind or goog.partial for
    1044 * performance reasons.
    1045 *
    1046 * Runtime: O(log n)
    1047 *
    1048 * @param {Array.<VALUE>|goog.array.ArrayLike} arr The array to be searched.
    1049 * @param {function(TARGET, VALUE): number|
    1050 * function(this:THIS, VALUE, number, ?): number} compareFn Either an
    1051 * evaluator or a comparison function, as defined by binarySearch
    1052 * and binarySelect above.
    1053 * @param {boolean} isEvaluator Whether the function is an evaluator or a
    1054 * comparison function.
    1055 * @param {TARGET=} opt_target If the function is a comparison function, then
    1056 * this is the target to binary search for.
    1057 * @param {THIS=} opt_selfObj If the function is an evaluator, this is an
    1058 * optional this object for the evaluator.
    1059 * @return {number} Lowest index of the target value if found, otherwise
    1060 * (-(insertion point) - 1). The insertion point is where the value should
    1061 * be inserted into arr to preserve the sorted property. Return value >= 0
    1062 * iff target is found.
    1063 * @template THIS, VALUE, TARGET
    1064 * @private
    1065 */
    1066goog.array.binarySearch_ = function(arr, compareFn, isEvaluator, opt_target,
    1067 opt_selfObj) {
    1068 var left = 0; // inclusive
    1069 var right = arr.length; // exclusive
    1070 var found;
    1071 while (left < right) {
    1072 var middle = (left + right) >> 1;
    1073 var compareResult;
    1074 if (isEvaluator) {
    1075 compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);
    1076 } else {
    1077 compareResult = compareFn(opt_target, arr[middle]);
    1078 }
    1079 if (compareResult > 0) {
    1080 left = middle + 1;
    1081 } else {
    1082 right = middle;
    1083 // We are looking for the lowest index so we can't return immediately.
    1084 found = !compareResult;
    1085 }
    1086 }
    1087 // left is the index if found, or the insertion point otherwise.
    1088 // ~left is a shorthand for -left - 1.
    1089 return found ? left : ~left;
    1090};
    1091
    1092
    1093/**
    1094 * Sorts the specified array into ascending order. If no opt_compareFn is
    1095 * specified, elements are compared using
    1096 * <code>goog.array.defaultCompare</code>, which compares the elements using
    1097 * the built in < and > operators. This will produce the expected behavior
    1098 * for homogeneous arrays of String(s) and Number(s), unlike the native sort,
    1099 * but will give unpredictable results for heterogenous lists of strings and
    1100 * numbers with different numbers of digits.
    1101 *
    1102 * This sort is not guaranteed to be stable.
    1103 *
    1104 * Runtime: Same as <code>Array.prototype.sort</code>
    1105 *
    1106 * @param {Array.<T>} arr The array to be sorted.
    1107 * @param {?function(T,T):number=} opt_compareFn Optional comparison
    1108 * function by which the
    1109 * array is to be ordered. Should take 2 arguments to compare, and return a
    1110 * negative number, zero, or a positive number depending on whether the
    1111 * first argument is less than, equal to, or greater than the second.
    1112 * @template T
    1113 */
    1114goog.array.sort = function(arr, opt_compareFn) {
    1115 // TODO(arv): Update type annotation since null is not accepted.
    1116 arr.sort(opt_compareFn || goog.array.defaultCompare);
    1117};
    1118
    1119
    1120/**
    1121 * Sorts the specified array into ascending order in a stable way. If no
    1122 * opt_compareFn is specified, elements are compared using
    1123 * <code>goog.array.defaultCompare</code>, which compares the elements using
    1124 * the built in < and > operators. This will produce the expected behavior
    1125 * for homogeneous arrays of String(s) and Number(s).
    1126 *
    1127 * Runtime: Same as <code>Array.prototype.sort</code>, plus an additional
    1128 * O(n) overhead of copying the array twice.
    1129 *
    1130 * @param {Array.<T>} arr The array to be sorted.
    1131 * @param {?function(T, T): number=} opt_compareFn Optional comparison function
    1132 * by which the array is to be ordered. Should take 2 arguments to compare,
    1133 * and return a negative number, zero, or a positive number depending on
    1134 * whether the first argument is less than, equal to, or greater than the
    1135 * second.
    1136 * @template T
    1137 */
    1138goog.array.stableSort = function(arr, opt_compareFn) {
    1139 for (var i = 0; i < arr.length; i++) {
    1140 arr[i] = {index: i, value: arr[i]};
    1141 }
    1142 var valueCompareFn = opt_compareFn || goog.array.defaultCompare;
    1143 function stableCompareFn(obj1, obj2) {
    1144 return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;
    1145 };
    1146 goog.array.sort(arr, stableCompareFn);
    1147 for (var i = 0; i < arr.length; i++) {
    1148 arr[i] = arr[i].value;
    1149 }
    1150};
    1151
    1152
    1153/**
    1154 * Sorts an array of objects by the specified object key and compare
    1155 * function. If no compare function is provided, the key values are
    1156 * compared in ascending order using <code>goog.array.defaultCompare</code>.
    1157 * This won't work for keys that get renamed by the compiler. So use
    1158 * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.
    1159 * @param {Array.<Object>} arr An array of objects to sort.
    1160 * @param {string} key The object key to sort by.
    1161 * @param {Function=} opt_compareFn The function to use to compare key
    1162 * values.
    1163 */
    1164goog.array.sortObjectsByKey = function(arr, key, opt_compareFn) {
    1165 var compare = opt_compareFn || goog.array.defaultCompare;
    1166 goog.array.sort(arr, function(a, b) {
    1167 return compare(a[key], b[key]);
    1168 });
    1169};
    1170
    1171
    1172/**
    1173 * Tells if the array is sorted.
    1174 * @param {!Array.<T>} arr The array.
    1175 * @param {?function(T,T):number=} opt_compareFn Function to compare the
    1176 * array elements.
    1177 * Should take 2 arguments to compare, and return a negative number, zero,
    1178 * or a positive number depending on whether the first argument is less
    1179 * than, equal to, or greater than the second.
    1180 * @param {boolean=} opt_strict If true no equal elements are allowed.
    1181 * @return {boolean} Whether the array is sorted.
    1182 * @template T
    1183 */
    1184goog.array.isSorted = function(arr, opt_compareFn, opt_strict) {
    1185 var compare = opt_compareFn || goog.array.defaultCompare;
    1186 for (var i = 1; i < arr.length; i++) {
    1187 var compareResult = compare(arr[i - 1], arr[i]);
    1188 if (compareResult > 0 || compareResult == 0 && opt_strict) {
    1189 return false;
    1190 }
    1191 }
    1192 return true;
    1193};
    1194
    1195
    1196/**
    1197 * Compares two arrays for equality. Two arrays are considered equal if they
    1198 * have the same length and their corresponding elements are equal according to
    1199 * the comparison function.
    1200 *
    1201 * @param {goog.array.ArrayLike} arr1 The first array to compare.
    1202 * @param {goog.array.ArrayLike} arr2 The second array to compare.
    1203 * @param {Function=} opt_equalsFn Optional comparison function.
    1204 * Should take 2 arguments to compare, and return true if the arguments
    1205 * are equal. Defaults to {@link goog.array.defaultCompareEquality} which
    1206 * compares the elements using the built-in '===' operator.
    1207 * @return {boolean} Whether the two arrays are equal.
    1208 */
    1209goog.array.equals = function(arr1, arr2, opt_equalsFn) {
    1210 if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||
    1211 arr1.length != arr2.length) {
    1212 return false;
    1213 }
    1214 var l = arr1.length;
    1215 var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality;
    1216 for (var i = 0; i < l; i++) {
    1217 if (!equalsFn(arr1[i], arr2[i])) {
    1218 return false;
    1219 }
    1220 }
    1221 return true;
    1222};
    1223
    1224
    1225/**
    1226 * 3-way array compare function.
    1227 * @param {!Array.<VALUE>|!goog.array.ArrayLike} arr1 The first array to
    1228 * compare.
    1229 * @param {!Array.<VALUE>|!goog.array.ArrayLike} arr2 The second array to
    1230 * compare.
    1231 * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison
    1232 * function by which the array is to be ordered. Should take 2 arguments to
    1233 * compare, and return a negative number, zero, or a positive number
    1234 * depending on whether the first argument is less than, equal to, or
    1235 * greater than the second.
    1236 * @return {number} Negative number, zero, or a positive number depending on
    1237 * whether the first argument is less than, equal to, or greater than the
    1238 * second.
    1239 * @template VALUE
    1240 */
    1241goog.array.compare3 = function(arr1, arr2, opt_compareFn) {
    1242 var compare = opt_compareFn || goog.array.defaultCompare;
    1243 var l = Math.min(arr1.length, arr2.length);
    1244 for (var i = 0; i < l; i++) {
    1245 var result = compare(arr1[i], arr2[i]);
    1246 if (result != 0) {
    1247 return result;
    1248 }
    1249 }
    1250 return goog.array.defaultCompare(arr1.length, arr2.length);
    1251};
    1252
    1253
    1254/**
    1255 * Compares its two arguments for order, using the built in < and >
    1256 * operators.
    1257 * @param {VALUE} a The first object to be compared.
    1258 * @param {VALUE} b The second object to be compared.
    1259 * @return {number} A negative number, zero, or a positive number as the first
    1260 * argument is less than, equal to, or greater than the second.
    1261 * @template VALUE
    1262 */
    1263goog.array.defaultCompare = function(a, b) {
    1264 return a > b ? 1 : a < b ? -1 : 0;
    1265};
    1266
    1267
    1268/**
    1269 * Compares its two arguments for equality, using the built in === operator.
    1270 * @param {*} a The first object to compare.
    1271 * @param {*} b The second object to compare.
    1272 * @return {boolean} True if the two arguments are equal, false otherwise.
    1273 */
    1274goog.array.defaultCompareEquality = function(a, b) {
    1275 return a === b;
    1276};
    1277
    1278
    1279/**
    1280 * Inserts a value into a sorted array. The array is not modified if the
    1281 * value is already present.
    1282 * @param {Array.<VALUE>|goog.array.ArrayLike} array The array to modify.
    1283 * @param {VALUE} value The object to insert.
    1284 * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison
    1285 * function by which the array is ordered. Should take 2 arguments to
    1286 * compare, and return a negative number, zero, or a positive number
    1287 * depending on whether the first argument is less than, equal to, or
    1288 * greater than the second.
    1289 * @return {boolean} True if an element was inserted.
    1290 * @template VALUE
    1291 */
    1292goog.array.binaryInsert = function(array, value, opt_compareFn) {
    1293 var index = goog.array.binarySearch(array, value, opt_compareFn);
    1294 if (index < 0) {
    1295 goog.array.insertAt(array, value, -(index + 1));
    1296 return true;
    1297 }
    1298 return false;
    1299};
    1300
    1301
    1302/**
    1303 * Removes a value from a sorted array.
    1304 * @param {!Array.<VALUE>|!goog.array.ArrayLike} array The array to modify.
    1305 * @param {VALUE} value The object to remove.
    1306 * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison
    1307 * function by which the array is ordered. Should take 2 arguments to
    1308 * compare, and return a negative number, zero, or a positive number
    1309 * depending on whether the first argument is less than, equal to, or
    1310 * greater than the second.
    1311 * @return {boolean} True if an element was removed.
    1312 * @template VALUE
    1313 */
    1314goog.array.binaryRemove = function(array, value, opt_compareFn) {
    1315 var index = goog.array.binarySearch(array, value, opt_compareFn);
    1316 return (index >= 0) ? goog.array.removeAt(array, index) : false;
    1317};
    1318
    1319
    1320/**
    1321 * Splits an array into disjoint buckets according to a splitting function.
    1322 * @param {Array.<T>} array The array.
    1323 * @param {function(this:S, T,number,Array.<T>):?} sorter Function to call for
    1324 * every element. This takes 3 arguments (the element, the index and the
    1325 * array) and must return a valid object key (a string, number, etc), or
    1326 * undefined, if that object should not be placed in a bucket.
    1327 * @param {S=} opt_obj The object to be used as the value of 'this' within
    1328 * sorter.
    1329 * @return {!Object} An object, with keys being all of the unique return values
    1330 * of sorter, and values being arrays containing the items for
    1331 * which the splitter returned that key.
    1332 * @template T,S
    1333 */
    1334goog.array.bucket = function(array, sorter, opt_obj) {
    1335 var buckets = {};
    1336
    1337 for (var i = 0; i < array.length; i++) {
    1338 var value = array[i];
    1339 var key = sorter.call(opt_obj, value, i, array);
    1340 if (goog.isDef(key)) {
    1341 // Push the value to the right bucket, creating it if necessary.
    1342 var bucket = buckets[key] || (buckets[key] = []);
    1343 bucket.push(value);
    1344 }
    1345 }
    1346
    1347 return buckets;
    1348};
    1349
    1350
    1351/**
    1352 * Creates a new object built from the provided array and the key-generation
    1353 * function.
    1354 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array like object over
    1355 * which to iterate whose elements will be the values in the new object.
    1356 * @param {?function(this:S, T, number, ?) : string} keyFunc The function to
    1357 * call for every element. This function takes 3 arguments (the element, the
    1358 * index and the array) and should return a string that will be used as the
    1359 * key for the element in the new object. If the function returns the same
    1360 * key for more than one element, the value for that key is
    1361 * implementation-defined.
    1362 * @param {S=} opt_obj The object to be used as the value of 'this'
    1363 * within keyFunc.
    1364 * @return {!Object.<T>} The new object.
    1365 * @template T,S
    1366 */
    1367goog.array.toObject = function(arr, keyFunc, opt_obj) {
    1368 var ret = {};
    1369 goog.array.forEach(arr, function(element, index) {
    1370 ret[keyFunc.call(opt_obj, element, index, arr)] = element;
    1371 });
    1372 return ret;
    1373};
    1374
    1375
    1376/**
    1377 * Creates a range of numbers in an arithmetic progression.
    1378 *
    1379 * Range takes 1, 2, or 3 arguments:
    1380 * <pre>
    1381 * range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]
    1382 * range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]
    1383 * range(-2, -5, -1) produces [-2, -3, -4]
    1384 * range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.
    1385 * </pre>
    1386 *
    1387 * @param {number} startOrEnd The starting value of the range if an end argument
    1388 * is provided. Otherwise, the start value is 0, and this is the end value.
    1389 * @param {number=} opt_end The optional end value of the range.
    1390 * @param {number=} opt_step The step size between range values. Defaults to 1
    1391 * if opt_step is undefined or 0.
    1392 * @return {!Array.<number>} An array of numbers for the requested range. May be
    1393 * an empty array if adding the step would not converge toward the end
    1394 * value.
    1395 */
    1396goog.array.range = function(startOrEnd, opt_end, opt_step) {
    1397 var array = [];
    1398 var start = 0;
    1399 var end = startOrEnd;
    1400 var step = opt_step || 1;
    1401 if (opt_end !== undefined) {
    1402 start = startOrEnd;
    1403 end = opt_end;
    1404 }
    1405
    1406 if (step * (end - start) < 0) {
    1407 // Sign mismatch: start + step will never reach the end value.
    1408 return [];
    1409 }
    1410
    1411 if (step > 0) {
    1412 for (var i = start; i < end; i += step) {
    1413 array.push(i);
    1414 }
    1415 } else {
    1416 for (var i = start; i > end; i += step) {
    1417 array.push(i);
    1418 }
    1419 }
    1420 return array;
    1421};
    1422
    1423
    1424/**
    1425 * Returns an array consisting of the given value repeated N times.
    1426 *
    1427 * @param {VALUE} value The value to repeat.
    1428 * @param {number} n The repeat count.
    1429 * @return {!Array.<VALUE>} An array with the repeated value.
    1430 * @template VALUE
    1431 */
    1432goog.array.repeat = function(value, n) {
    1433 var array = [];
    1434 for (var i = 0; i < n; i++) {
    1435 array[i] = value;
    1436 }
    1437 return array;
    1438};
    1439
    1440
    1441/**
    1442 * Returns an array consisting of every argument with all arrays
    1443 * expanded in-place recursively.
    1444 *
    1445 * @param {...*} var_args The values to flatten.
    1446 * @return {!Array} An array containing the flattened values.
    1447 */
    1448goog.array.flatten = function(var_args) {
    1449 var result = [];
    1450 for (var i = 0; i < arguments.length; i++) {
    1451 var element = arguments[i];
    1452 if (goog.isArray(element)) {
    1453 result.push.apply(result, goog.array.flatten.apply(null, element));
    1454 } else {
    1455 result.push(element);
    1456 }
    1457 }
    1458 return result;
    1459};
    1460
    1461
    1462/**
    1463 * Rotates an array in-place. After calling this method, the element at
    1464 * index i will be the element previously at index (i - n) %
    1465 * array.length, for all values of i between 0 and array.length - 1,
    1466 * inclusive.
    1467 *
    1468 * For example, suppose list comprises [t, a, n, k, s]. After invoking
    1469 * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].
    1470 *
    1471 * @param {!Array.<T>} array The array to rotate.
    1472 * @param {number} n The amount to rotate.
    1473 * @return {!Array.<T>} The array.
    1474 * @template T
    1475 */
    1476goog.array.rotate = function(array, n) {
    1477 goog.asserts.assert(array.length != null);
    1478
    1479 if (array.length) {
    1480 n %= array.length;
    1481 if (n > 0) {
    1482 goog.array.ARRAY_PROTOTYPE_.unshift.apply(array, array.splice(-n, n));
    1483 } else if (n < 0) {
    1484 goog.array.ARRAY_PROTOTYPE_.push.apply(array, array.splice(0, -n));
    1485 }
    1486 }
    1487 return array;
    1488};
    1489
    1490
    1491/**
    1492 * Moves one item of an array to a new position keeping the order of the rest
    1493 * of the items. Example use case: keeping a list of JavaScript objects
    1494 * synchronized with the corresponding list of DOM elements after one of the
    1495 * elements has been dragged to a new position.
    1496 * @param {!(Array|Arguments|{length:number})} arr The array to modify.
    1497 * @param {number} fromIndex Index of the item to move between 0 and
    1498 * {@code arr.length - 1}.
    1499 * @param {number} toIndex Target index between 0 and {@code arr.length - 1}.
    1500 */
    1501goog.array.moveItem = function(arr, fromIndex, toIndex) {
    1502 goog.asserts.assert(fromIndex >= 0 && fromIndex < arr.length);
    1503 goog.asserts.assert(toIndex >= 0 && toIndex < arr.length);
    1504 // Remove 1 item at fromIndex.
    1505 var removedItems = goog.array.ARRAY_PROTOTYPE_.splice.call(arr, fromIndex, 1);
    1506 // Insert the removed item at toIndex.
    1507 goog.array.ARRAY_PROTOTYPE_.splice.call(arr, toIndex, 0, removedItems[0]);
    1508 // We don't use goog.array.insertAt and goog.array.removeAt, because they're
    1509 // significantly slower than splice.
    1510};
    1511
    1512
    1513/**
    1514 * Creates a new array for which the element at position i is an array of the
    1515 * ith element of the provided arrays. The returned array will only be as long
    1516 * as the shortest array provided; additional values are ignored. For example,
    1517 * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]].
    1518 *
    1519 * This is similar to the zip() function in Python. See {@link
    1520 * http://docs.python.org/library/functions.html#zip}
    1521 *
    1522 * @param {...!goog.array.ArrayLike} var_args Arrays to be combined.
    1523 * @return {!Array.<!Array>} A new array of arrays created from provided arrays.
    1524 */
    1525goog.array.zip = function(var_args) {
    1526 if (!arguments.length) {
    1527 return [];
    1528 }
    1529 var result = [];
    1530 for (var i = 0; true; i++) {
    1531 var value = [];
    1532 for (var j = 0; j < arguments.length; j++) {
    1533 var arr = arguments[j];
    1534 // If i is larger than the array length, this is the shortest array.
    1535 if (i >= arr.length) {
    1536 return result;
    1537 }
    1538 value.push(arr[i]);
    1539 }
    1540 result.push(value);
    1541 }
    1542};
    1543
    1544
    1545/**
    1546 * Shuffles the values in the specified array using the Fisher-Yates in-place
    1547 * shuffle (also known as the Knuth Shuffle). By default, calls Math.random()
    1548 * and so resets the state of that random number generator. Similarly, may reset
    1549 * the state of the any other specified random number generator.
    1550 *
    1551 * Runtime: O(n)
    1552 *
    1553 * @param {!Array} arr The array to be shuffled.
    1554 * @param {function():number=} opt_randFn Optional random function to use for
    1555 * shuffling.
    1556 * Takes no arguments, and returns a random number on the interval [0, 1).
    1557 * Defaults to Math.random() using JavaScript's built-in Math library.
    1558 */
    1559goog.array.shuffle = function(arr, opt_randFn) {
    1560 var randFn = opt_randFn || Math.random;
    1561
    1562 for (var i = arr.length - 1; i > 0; i--) {
    1563 // Choose a random array index in [0, i] (inclusive with i).
    1564 var j = Math.floor(randFn() * (i + 1));
    1565
    1566 var tmp = arr[i];
    1567 arr[i] = arr[j];
    1568 arr[j] = tmp;
    1569 }
    1570};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/asserts/asserts.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/asserts/asserts.js.src.html new file mode 100644 index 0000000..32fc68e --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/asserts/asserts.js.src.html @@ -0,0 +1 @@ +asserts.js

    lib/goog/asserts/asserts.js

    1// Copyright 2008 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Utilities to check the preconditions, postconditions and
    17 * invariants runtime.
    18 *
    19 * Methods in this package should be given special treatment by the compiler
    20 * for type-inference. For example, <code>goog.asserts.assert(foo)</code>
    21 * will restrict <code>foo</code> to a truthy value.
    22 *
    23 * The compiler has an option to disable asserts. So code like:
    24 * <code>
    25 * var x = goog.asserts.assert(foo()); goog.asserts.assert(bar());
    26 * </code>
    27 * will be transformed into:
    28 * <code>
    29 * var x = foo();
    30 * </code>
    31 * The compiler will leave in foo() (because its return value is used),
    32 * but it will remove bar() because it assumes it does not have side-effects.
    33 *
    34 */
    35
    36goog.provide('goog.asserts');
    37goog.provide('goog.asserts.AssertionError');
    38
    39goog.require('goog.debug.Error');
    40goog.require('goog.dom.NodeType');
    41goog.require('goog.string');
    42
    43
    44/**
    45 * @define {boolean} Whether to strip out asserts or to leave them in.
    46 */
    47goog.define('goog.asserts.ENABLE_ASSERTS', goog.DEBUG);
    48
    49
    50
    51/**
    52 * Error object for failed assertions.
    53 * @param {string} messagePattern The pattern that was used to form message.
    54 * @param {!Array.<*>} messageArgs The items to substitute into the pattern.
    55 * @constructor
    56 * @extends {goog.debug.Error}
    57 * @final
    58 */
    59goog.asserts.AssertionError = function(messagePattern, messageArgs) {
    60 messageArgs.unshift(messagePattern);
    61 goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs));
    62 // Remove the messagePattern afterwards to avoid permenantly modifying the
    63 // passed in array.
    64 messageArgs.shift();
    65
    66 /**
    67 * The message pattern used to format the error message. Error handlers can
    68 * use this to uniquely identify the assertion.
    69 * @type {string}
    70 */
    71 this.messagePattern = messagePattern;
    72};
    73goog.inherits(goog.asserts.AssertionError, goog.debug.Error);
    74
    75
    76/** @override */
    77goog.asserts.AssertionError.prototype.name = 'AssertionError';
    78
    79
    80/**
    81 * Throws an exception with the given message and "Assertion failed" prefixed
    82 * onto it.
    83 * @param {string} defaultMessage The message to use if givenMessage is empty.
    84 * @param {Array.<*>} defaultArgs The substitution arguments for defaultMessage.
    85 * @param {string|undefined} givenMessage Message supplied by the caller.
    86 * @param {Array.<*>} givenArgs The substitution arguments for givenMessage.
    87 * @throws {goog.asserts.AssertionError} When the value is not a number.
    88 * @private
    89 */
    90goog.asserts.doAssertFailure_ =
    91 function(defaultMessage, defaultArgs, givenMessage, givenArgs) {
    92 var message = 'Assertion failed';
    93 if (givenMessage) {
    94 message += ': ' + givenMessage;
    95 var args = givenArgs;
    96 } else if (defaultMessage) {
    97 message += ': ' + defaultMessage;
    98 args = defaultArgs;
    99 }
    100 // The '' + works around an Opera 10 bug in the unit tests. Without it,
    101 // a stack trace is added to var message above. With this, a stack trace is
    102 // not added until this line (it causes the extra garbage to be added after
    103 // the assertion message instead of in the middle of it).
    104 throw new goog.asserts.AssertionError('' + message, args || []);
    105};
    106
    107
    108/**
    109 * Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is
    110 * true.
    111 * @template T
    112 * @param {T} condition The condition to check.
    113 * @param {string=} opt_message Error message in case of failure.
    114 * @param {...*} var_args The items to substitute into the failure message.
    115 * @return {T} The value of the condition.
    116 * @throws {goog.asserts.AssertionError} When the condition evaluates to false.
    117 */
    118goog.asserts.assert = function(condition, opt_message, var_args) {
    119 if (goog.asserts.ENABLE_ASSERTS && !condition) {
    120 goog.asserts.doAssertFailure_('', null, opt_message,
    121 Array.prototype.slice.call(arguments, 2));
    122 }
    123 return condition;
    124};
    125
    126
    127/**
    128 * Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case
    129 * when we want to add a check in the unreachable area like switch-case
    130 * statement:
    131 *
    132 * <pre>
    133 * switch(type) {
    134 * case FOO: doSomething(); break;
    135 * case BAR: doSomethingElse(); break;
    136 * default: goog.assert.fail('Unrecognized type: ' + type);
    137 * // We have only 2 types - "default:" section is unreachable code.
    138 * }
    139 * </pre>
    140 *
    141 * @param {string=} opt_message Error message in case of failure.
    142 * @param {...*} var_args The items to substitute into the failure message.
    143 * @throws {goog.asserts.AssertionError} Failure.
    144 */
    145goog.asserts.fail = function(opt_message, var_args) {
    146 if (goog.asserts.ENABLE_ASSERTS) {
    147 throw new goog.asserts.AssertionError(
    148 'Failure' + (opt_message ? ': ' + opt_message : ''),
    149 Array.prototype.slice.call(arguments, 1));
    150 }
    151};
    152
    153
    154/**
    155 * Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true.
    156 * @param {*} value The value to check.
    157 * @param {string=} opt_message Error message in case of failure.
    158 * @param {...*} var_args The items to substitute into the failure message.
    159 * @return {number} The value, guaranteed to be a number when asserts enabled.
    160 * @throws {goog.asserts.AssertionError} When the value is not a number.
    161 */
    162goog.asserts.assertNumber = function(value, opt_message, var_args) {
    163 if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) {
    164 goog.asserts.doAssertFailure_('Expected number but got %s: %s.',
    165 [goog.typeOf(value), value], opt_message,
    166 Array.prototype.slice.call(arguments, 2));
    167 }
    168 return /** @type {number} */ (value);
    169};
    170
    171
    172/**
    173 * Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true.
    174 * @param {*} value The value to check.
    175 * @param {string=} opt_message Error message in case of failure.
    176 * @param {...*} var_args The items to substitute into the failure message.
    177 * @return {string} The value, guaranteed to be a string when asserts enabled.
    178 * @throws {goog.asserts.AssertionError} When the value is not a string.
    179 */
    180goog.asserts.assertString = function(value, opt_message, var_args) {
    181 if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) {
    182 goog.asserts.doAssertFailure_('Expected string but got %s: %s.',
    183 [goog.typeOf(value), value], opt_message,
    184 Array.prototype.slice.call(arguments, 2));
    185 }
    186 return /** @type {string} */ (value);
    187};
    188
    189
    190/**
    191 * Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true.
    192 * @param {*} value The value to check.
    193 * @param {string=} opt_message Error message in case of failure.
    194 * @param {...*} var_args The items to substitute into the failure message.
    195 * @return {!Function} The value, guaranteed to be a function when asserts
    196 * enabled.
    197 * @throws {goog.asserts.AssertionError} When the value is not a function.
    198 */
    199goog.asserts.assertFunction = function(value, opt_message, var_args) {
    200 if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) {
    201 goog.asserts.doAssertFailure_('Expected function but got %s: %s.',
    202 [goog.typeOf(value), value], opt_message,
    203 Array.prototype.slice.call(arguments, 2));
    204 }
    205 return /** @type {!Function} */ (value);
    206};
    207
    208
    209/**
    210 * Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true.
    211 * @param {*} value The value to check.
    212 * @param {string=} opt_message Error message in case of failure.
    213 * @param {...*} var_args The items to substitute into the failure message.
    214 * @return {!Object} The value, guaranteed to be a non-null object.
    215 * @throws {goog.asserts.AssertionError} When the value is not an object.
    216 */
    217goog.asserts.assertObject = function(value, opt_message, var_args) {
    218 if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) {
    219 goog.asserts.doAssertFailure_('Expected object but got %s: %s.',
    220 [goog.typeOf(value), value],
    221 opt_message, Array.prototype.slice.call(arguments, 2));
    222 }
    223 return /** @type {!Object} */ (value);
    224};
    225
    226
    227/**
    228 * Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true.
    229 * @param {*} value The value to check.
    230 * @param {string=} opt_message Error message in case of failure.
    231 * @param {...*} var_args The items to substitute into the failure message.
    232 * @return {!Array} The value, guaranteed to be a non-null array.
    233 * @throws {goog.asserts.AssertionError} When the value is not an array.
    234 */
    235goog.asserts.assertArray = function(value, opt_message, var_args) {
    236 if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) {
    237 goog.asserts.doAssertFailure_('Expected array but got %s: %s.',
    238 [goog.typeOf(value), value], opt_message,
    239 Array.prototype.slice.call(arguments, 2));
    240 }
    241 return /** @type {!Array} */ (value);
    242};
    243
    244
    245/**
    246 * Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true.
    247 * @param {*} value The value to check.
    248 * @param {string=} opt_message Error message in case of failure.
    249 * @param {...*} var_args The items to substitute into the failure message.
    250 * @return {boolean} The value, guaranteed to be a boolean when asserts are
    251 * enabled.
    252 * @throws {goog.asserts.AssertionError} When the value is not a boolean.
    253 */
    254goog.asserts.assertBoolean = function(value, opt_message, var_args) {
    255 if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) {
    256 goog.asserts.doAssertFailure_('Expected boolean but got %s: %s.',
    257 [goog.typeOf(value), value], opt_message,
    258 Array.prototype.slice.call(arguments, 2));
    259 }
    260 return /** @type {boolean} */ (value);
    261};
    262
    263
    264/**
    265 * Checks if the value is a DOM Element if goog.asserts.ENABLE_ASSERTS is true.
    266 * @param {*} value The value to check.
    267 * @param {string=} opt_message Error message in case of failure.
    268 * @param {...*} var_args The items to substitute into the failure message.
    269 * @return {!Element} The value, likely to be a DOM Element when asserts are
    270 * enabled.
    271 * @throws {goog.asserts.AssertionError} When the value is not a boolean.
    272 */
    273goog.asserts.assertElement = function(value, opt_message, var_args) {
    274 if (goog.asserts.ENABLE_ASSERTS && (!goog.isObject(value) ||
    275 value.nodeType != goog.dom.NodeType.ELEMENT)) {
    276 goog.asserts.doAssertFailure_('Expected Element but got %s: %s.',
    277 [goog.typeOf(value), value], opt_message,
    278 Array.prototype.slice.call(arguments, 2));
    279 }
    280 return /** @type {!Element} */ (value);
    281};
    282
    283
    284/**
    285 * Checks if the value is an instance of the user-defined type if
    286 * goog.asserts.ENABLE_ASSERTS is true.
    287 *
    288 * The compiler may tighten the type returned by this function.
    289 *
    290 * @param {*} value The value to check.
    291 * @param {function(new: T, ...)} type A user-defined constructor.
    292 * @param {string=} opt_message Error message in case of failure.
    293 * @param {...*} var_args The items to substitute into the failure message.
    294 * @throws {goog.asserts.AssertionError} When the value is not an instance of
    295 * type.
    296 * @return {!T}
    297 * @template T
    298 */
    299goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) {
    300 if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) {
    301 goog.asserts.doAssertFailure_('instanceof check failed.', null,
    302 opt_message, Array.prototype.slice.call(arguments, 3));
    303 }
    304 return value;
    305};
    306
    307
    308/**
    309 * Checks that no enumerable keys are present in Object.prototype. Such keys
    310 * would break most code that use {@code for (var ... in ...)} loops.
    311 */
    312goog.asserts.assertObjectPrototypeIsIntact = function() {
    313 for (var key in Object.prototype) {
    314 goog.asserts.fail(key + ' should not be enumerable in Object.prototype.');
    315 }
    316};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/base.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/base.js.src.html new file mode 100644 index 0000000..6b78dc2 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/base.js.src.html @@ -0,0 +1 @@ +base.js

    lib/goog/base.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Bootstrap for the Google JS Library (Closure).
    17 *
    18 * In uncompiled mode base.js will write out Closure's deps file, unless the
    19 * global <code>CLOSURE_NO_DEPS</code> is set to true. This allows projects to
    20 * include their own deps file(s) from different locations.
    21 *
    22 *
    23 * @provideGoog
    24 */
    25
    26
    27/**
    28 * @define {boolean} Overridden to true by the compiler when --closure_pass
    29 * or --mark_as_compiled is specified.
    30 */
    31var COMPILED = false;
    32
    33
    34/**
    35 * Base namespace for the Closure library. Checks to see goog is already
    36 * defined in the current scope before assigning to prevent clobbering if
    37 * base.js is loaded more than once.
    38 *
    39 * @const
    40 */
    41var goog = goog || {};
    42
    43
    44/**
    45 * Reference to the global context. In most cases this will be 'window'.
    46 */
    47goog.global = this;
    48
    49
    50/**
    51 * A hook for overriding the define values in uncompiled mode.
    52 *
    53 * In uncompiled mode, {@code CLOSURE_UNCOMPILED_DEFINES} may be defined before
    54 * loading base.js. If a key is defined in {@code CLOSURE_UNCOMPILED_DEFINES},
    55 * {@code goog.define} will use the value instead of the default value. This
    56 * allows flags to be overwritten without compilation (this is normally
    57 * accomplished with the compiler's "define" flag).
    58 *
    59 * Example:
    60 * <pre>
    61 * var CLOSURE_UNCOMPILED_DEFINES = {'goog.DEBUG': false};
    62 * </pre>
    63 *
    64 * @type {Object.<string, (string|number|boolean)>|undefined}
    65 */
    66goog.global.CLOSURE_UNCOMPILED_DEFINES;
    67
    68
    69/**
    70 * A hook for overriding the define values in uncompiled or compiled mode,
    71 * like CLOSURE_UNCOMPILED_DEFINES but effective in compiled code. In
    72 * uncompiled code CLOSURE_UNCOMPILED_DEFINES takes precedence.
    73 *
    74 * Also unlike CLOSURE_UNCOMPILED_DEFINES the values must be number, boolean or
    75 * string literals or the compiler will emit an error.
    76 *
    77 * While any @define value may be set, only those set with goog.define will be
    78 * effective for uncompiled code.
    79 *
    80 * Example:
    81 * <pre>
    82 * var CLOSURE_DEFINES = {'goog.DEBUG': false};
    83 * </pre>
    84 *
    85 * @type {Object.<string, (string|number|boolean)>|undefined}
    86 */
    87goog.global.CLOSURE_DEFINES;
    88
    89
    90/**
    91 * Returns true if the specified value is not undefined.
    92 * WARNING: Do not use this to test if an object has a property. Use the in
    93 * operator instead.
    94 *
    95 * @param {?} val Variable to test.
    96 * @return {boolean} Whether variable is defined.
    97 */
    98goog.isDef = function(val) {
    99 // void 0 always evaluates to undefined and hence we do not need to depend on
    100 // the definition of the global variable named 'undefined'.
    101 return val !== void 0;
    102};
    103
    104
    105/**
    106 * Builds an object structure for the provided namespace path, ensuring that
    107 * names that already exist are not overwritten. For example:
    108 * "a.b.c" -> a = {};a.b={};a.b.c={};
    109 * Used by goog.provide and goog.exportSymbol.
    110 * @param {string} name name of the object that this file defines.
    111 * @param {*=} opt_object the object to expose at the end of the path.
    112 * @param {Object=} opt_objectToExportTo The object to add the path to; default
    113 * is |goog.global|.
    114 * @private
    115 */
    116goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
    117 var parts = name.split('.');
    118 var cur = opt_objectToExportTo || goog.global;
    119
    120 // Internet Explorer exhibits strange behavior when throwing errors from
    121 // methods externed in this manner. See the testExportSymbolExceptions in
    122 // base_test.html for an example.
    123 if (!(parts[0] in cur) && cur.execScript) {
    124 cur.execScript('var ' + parts[0]);
    125 }
    126
    127 // Certain browsers cannot parse code in the form for((a in b); c;);
    128 // This pattern is produced by the JSCompiler when it collapses the
    129 // statement above into the conditional loop below. To prevent this from
    130 // happening, use a for-loop and reserve the init logic as below.
    131
    132 // Parentheses added to eliminate strict JS warning in Firefox.
    133 for (var part; parts.length && (part = parts.shift());) {
    134 if (!parts.length && goog.isDef(opt_object)) {
    135 // last part and we have an object; use it
    136 cur[part] = opt_object;
    137 } else if (cur[part]) {
    138 cur = cur[part];
    139 } else {
    140 cur = cur[part] = {};
    141 }
    142 }
    143};
    144
    145
    146/**
    147 * Defines a named value. In uncompiled mode, the value is retreived from
    148 * CLOSURE_DEFINES or CLOSURE_UNCOMPILED_DEFINES if the object is defined and
    149 * has the property specified, and otherwise used the defined defaultValue.
    150 * When compiled, the default can be overridden using compiler command-line
    151 * options.
    152 *
    153 * @param {string} name The distinguished name to provide.
    154 * @param {string|number|boolean} defaultValue
    155 */
    156goog.define = function(name, defaultValue) {
    157 var value = defaultValue;
    158 if (!COMPILED) {
    159 if (goog.global.CLOSURE_UNCOMPILED_DEFINES &&
    160 Object.prototype.hasOwnProperty.call(
    161 goog.global.CLOSURE_UNCOMPILED_DEFINES, name)) {
    162 value = goog.global.CLOSURE_UNCOMPILED_DEFINES[name];
    163 } else if (goog.global.CLOSURE_DEFINES &&
    164 Object.prototype.hasOwnProperty.call(
    165 goog.global.CLOSURE_DEFINES, name)) {
    166 value = goog.global.CLOSURE_DEFINES[name];
    167 }
    168 }
    169 goog.exportPath_(name, value);
    170};
    171
    172
    173/**
    174 * @define {boolean} DEBUG is provided as a convenience so that debugging code
    175 * that should not be included in a production js_binary can be easily stripped
    176 * by specifying --define goog.DEBUG=false to the JSCompiler. For example, most
    177 * toString() methods should be declared inside an "if (goog.DEBUG)" conditional
    178 * because they are generally used for debugging purposes and it is difficult
    179 * for the JSCompiler to statically determine whether they are used.
    180 */
    181goog.DEBUG = true;
    182
    183
    184/**
    185 * @define {string} LOCALE defines the locale being used for compilation. It is
    186 * used to select locale specific data to be compiled in js binary. BUILD rule
    187 * can specify this value by "--define goog.LOCALE=<locale_name>" as JSCompiler
    188 * option.
    189 *
    190 * Take into account that the locale code format is important. You should use
    191 * the canonical Unicode format with hyphen as a delimiter. Language must be
    192 * lowercase, Language Script - Capitalized, Region - UPPERCASE.
    193 * There are few examples: pt-BR, en, en-US, sr-Latin-BO, zh-Hans-CN.
    194 *
    195 * See more info about locale codes here:
    196 * http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers
    197 *
    198 * For language codes you should use values defined by ISO 693-1. See it here
    199 * http://www.w3.org/WAI/ER/IG/ert/iso639.htm. There is only one exception from
    200 * this rule: the Hebrew language. For legacy reasons the old code (iw) should
    201 * be used instead of the new code (he), see http://wiki/Main/IIISynonyms.
    202 */
    203goog.define('goog.LOCALE', 'en'); // default to en
    204
    205
    206/**
    207 * @define {boolean} Whether this code is running on trusted sites.
    208 *
    209 * On untrusted sites, several native functions can be defined or overridden by
    210 * external libraries like Prototype, Datejs, and JQuery and setting this flag
    211 * to false forces closure to use its own implementations when possible.
    212 *
    213 * If your JavaScript can be loaded by a third party site and you are wary about
    214 * relying on non-standard implementations, specify
    215 * "--define goog.TRUSTED_SITE=false" to the JSCompiler.
    216 */
    217goog.define('goog.TRUSTED_SITE', true);
    218
    219
    220/**
    221 * @define {boolean} Whether a project is expected to be running in strict mode.
    222 *
    223 * This define can be used to trigger alternate implementations compatible with
    224 * running in EcmaScript Strict mode or warn about unavailable functionality.
    225 * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode
    226 */
    227goog.define('goog.STRICT_MODE_COMPATIBLE', false);
    228
    229
    230/**
    231 * Creates object stubs for a namespace. The presence of one or more
    232 * goog.provide() calls indicate that the file defines the given
    233 * objects/namespaces. Provided objects must not be null or undefined.
    234 * Build tools also scan for provide/require statements
    235 * to discern dependencies, build dependency files (see deps.js), etc.
    236 * @see goog.require
    237 * @param {string} name Namespace provided by this file in the form
    238 * "goog.package.part".
    239 */
    240goog.provide = function(name) {
    241 if (!COMPILED) {
    242 // Ensure that the same namespace isn't provided twice. This is intended
    243 // to teach new developers that 'goog.provide' is effectively a variable
    244 // declaration. And when JSCompiler transforms goog.provide into a real
    245 // variable declaration, the compiled JS should work the same as the raw
    246 // JS--even when the raw JS uses goog.provide incorrectly.
    247 if (goog.isProvided_(name)) {
    248 throw Error('Namespace "' + name + '" already declared.');
    249 }
    250 delete goog.implicitNamespaces_[name];
    251
    252 var namespace = name;
    253 while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {
    254 if (goog.getObjectByName(namespace)) {
    255 break;
    256 }
    257 goog.implicitNamespaces_[namespace] = true;
    258 }
    259 }
    260
    261 goog.exportPath_(name);
    262};
    263
    264
    265/**
    266 * Marks that the current file should only be used for testing, and never for
    267 * live code in production.
    268 *
    269 * In the case of unit tests, the message may optionally be an exact namespace
    270 * for the test (e.g. 'goog.stringTest'). The linter will then ignore the extra
    271 * provide (if not explicitly defined in the code).
    272 *
    273 * @param {string=} opt_message Optional message to add to the error that's
    274 * raised when used in production code.
    275 */
    276goog.setTestOnly = function(opt_message) {
    277 if (COMPILED && !goog.DEBUG) {
    278 opt_message = opt_message || '';
    279 throw Error('Importing test-only code into non-debug environment' +
    280 opt_message ? ': ' + opt_message : '.');
    281 }
    282};
    283
    284
    285/**
    286 * Forward declares a symbol. This is an indication to the compiler that the
    287 * symbol may be used in the source yet is not required and may not be provided
    288 * in compilation.
    289 *
    290 * The most common usage of forward declaration is code that takes a type as a
    291 * function parameter but does not need to require it. By forward declaring
    292 * instead of requiring, no hard dependency is made, and (if not required
    293 * elsewhere) the namespace may never be required and thus, not be pulled
    294 * into the JavaScript binary. If it is required elsewhere, it will be type
    295 * checked as normal.
    296 *
    297 *
    298 * @param {string} name The namespace to forward declare in the form of
    299 * "goog.package.part".
    300 */
    301goog.forwardDeclare = function(name) {};
    302
    303
    304if (!COMPILED) {
    305
    306 /**
    307 * Check if the given name has been goog.provided. This will return false for
    308 * names that are available only as implicit namespaces.
    309 * @param {string} name name of the object to look for.
    310 * @return {boolean} Whether the name has been provided.
    311 * @private
    312 */
    313 goog.isProvided_ = function(name) {
    314 return !goog.implicitNamespaces_[name] &&
    315 goog.isDefAndNotNull(goog.getObjectByName(name));
    316 };
    317
    318 /**
    319 * Namespaces implicitly defined by goog.provide. For example,
    320 * goog.provide('goog.events.Event') implicitly declares that 'goog' and
    321 * 'goog.events' must be namespaces.
    322 *
    323 * @type {Object}
    324 * @private
    325 */
    326 goog.implicitNamespaces_ = {};
    327}
    328
    329
    330/**
    331 * Returns an object based on its fully qualified external name. The object
    332 * is not found if null or undefined. If you are using a compilation pass that
    333 * renames property names beware that using this function will not find renamed
    334 * properties.
    335 *
    336 * @param {string} name The fully qualified name.
    337 * @param {Object=} opt_obj The object within which to look; default is
    338 * |goog.global|.
    339 * @return {?} The value (object or primitive) or, if not found, null.
    340 */
    341goog.getObjectByName = function(name, opt_obj) {
    342 var parts = name.split('.');
    343 var cur = opt_obj || goog.global;
    344 for (var part; part = parts.shift(); ) {
    345 if (goog.isDefAndNotNull(cur[part])) {
    346 cur = cur[part];
    347 } else {
    348 return null;
    349 }
    350 }
    351 return cur;
    352};
    353
    354
    355/**
    356 * Globalizes a whole namespace, such as goog or goog.lang.
    357 *
    358 * @param {Object} obj The namespace to globalize.
    359 * @param {Object=} opt_global The object to add the properties to.
    360 * @deprecated Properties may be explicitly exported to the global scope, but
    361 * this should no longer be done in bulk.
    362 */
    363goog.globalize = function(obj, opt_global) {
    364 var global = opt_global || goog.global;
    365 for (var x in obj) {
    366 global[x] = obj[x];
    367 }
    368};
    369
    370
    371/**
    372 * Adds a dependency from a file to the files it requires.
    373 * @param {string} relPath The path to the js file.
    374 * @param {Array} provides An array of strings with the names of the objects
    375 * this file provides.
    376 * @param {Array} requires An array of strings with the names of the objects
    377 * this file requires.
    378 */
    379goog.addDependency = function(relPath, provides, requires) {
    380 if (goog.DEPENDENCIES_ENABLED) {
    381 var provide, require;
    382 var path = relPath.replace(/\\/g, '/');
    383 var deps = goog.dependencies_;
    384 for (var i = 0; provide = provides[i]; i++) {
    385 deps.nameToPath[provide] = path;
    386 if (!(path in deps.pathToNames)) {
    387 deps.pathToNames[path] = {};
    388 }
    389 deps.pathToNames[path][provide] = true;
    390 }
    391 for (var j = 0; require = requires[j]; j++) {
    392 if (!(path in deps.requires)) {
    393 deps.requires[path] = {};
    394 }
    395 deps.requires[path][require] = true;
    396 }
    397 }
    398};
    399
    400
    401
    402
    403// NOTE(nnaze): The debug DOM loader was included in base.js as an original way
    404// to do "debug-mode" development. The dependency system can sometimes be
    405// confusing, as can the debug DOM loader's asynchronous nature.
    406//
    407// With the DOM loader, a call to goog.require() is not blocking -- the script
    408// will not load until some point after the current script. If a namespace is
    409// needed at runtime, it needs to be defined in a previous script, or loaded via
    410// require() with its registered dependencies.
    411// User-defined namespaces may need their own deps file. See http://go/js_deps,
    412// http://go/genjsdeps, or, externally, DepsWriter.
    413// http://code.google.com/closure/library/docs/depswriter.html
    414//
    415// Because of legacy clients, the DOM loader can't be easily removed from
    416// base.js. Work is being done to make it disableable or replaceable for
    417// different environments (DOM-less JavaScript interpreters like Rhino or V8,
    418// for example). See bootstrap/ for more information.
    419
    420
    421/**
    422 * @define {boolean} Whether to enable the debug loader.
    423 *
    424 * If enabled, a call to goog.require() will attempt to load the namespace by
    425 * appending a script tag to the DOM (if the namespace has been registered).
    426 *
    427 * If disabled, goog.require() will simply assert that the namespace has been
    428 * provided (and depend on the fact that some outside tool correctly ordered
    429 * the script).
    430 */
    431goog.define('goog.ENABLE_DEBUG_LOADER', true);
    432
    433
    434/**
    435 * Implements a system for the dynamic resolution of dependencies that works in
    436 * parallel with the BUILD system. Note that all calls to goog.require will be
    437 * stripped by the JSCompiler when the --closure_pass option is used.
    438 * @see goog.provide
    439 * @param {string} name Namespace to include (as was given in goog.provide()) in
    440 * the form "goog.package.part".
    441 */
    442goog.require = function(name) {
    443
    444 // If the object already exists we do not need do do anything.
    445 // TODO(arv): If we start to support require based on file name this has to
    446 // change.
    447 // TODO(arv): If we allow goog.foo.* this has to change.
    448 // TODO(arv): If we implement dynamic load after page load we should probably
    449 // not remove this code for the compiled output.
    450 if (!COMPILED) {
    451 if (goog.isProvided_(name)) {
    452 return;
    453 }
    454
    455 if (goog.ENABLE_DEBUG_LOADER) {
    456 var path = goog.getPathFromDeps_(name);
    457 if (path) {
    458 goog.included_[path] = true;
    459 goog.writeScripts_();
    460 return;
    461 }
    462 }
    463
    464 var errorMessage = 'goog.require could not find: ' + name;
    465 if (goog.global.console) {
    466 goog.global.console['error'](errorMessage);
    467 }
    468
    469
    470 throw Error(errorMessage);
    471
    472 }
    473};
    474
    475
    476/**
    477 * Path for included scripts.
    478 * @type {string}
    479 */
    480goog.basePath = '';
    481
    482
    483/**
    484 * A hook for overriding the base path.
    485 * @type {string|undefined}
    486 */
    487goog.global.CLOSURE_BASE_PATH;
    488
    489
    490/**
    491 * Whether to write out Closure's deps file. By default, the deps are written.
    492 * @type {boolean|undefined}
    493 */
    494goog.global.CLOSURE_NO_DEPS;
    495
    496
    497/**
    498 * A function to import a single script. This is meant to be overridden when
    499 * Closure is being run in non-HTML contexts, such as web workers. It's defined
    500 * in the global scope so that it can be set before base.js is loaded, which
    501 * allows deps.js to be imported properly.
    502 *
    503 * The function is passed the script source, which is a relative URI. It should
    504 * return true if the script was imported, false otherwise.
    505 * @type {(function(string): boolean)|undefined}
    506 */
    507goog.global.CLOSURE_IMPORT_SCRIPT;
    508
    509
    510/**
    511 * Null function used for default values of callbacks, etc.
    512 * @return {void} Nothing.
    513 */
    514goog.nullFunction = function() {};
    515
    516
    517/**
    518 * The identity function. Returns its first argument.
    519 *
    520 * @param {*=} opt_returnValue The single value that will be returned.
    521 * @param {...*} var_args Optional trailing arguments. These are ignored.
    522 * @return {?} The first argument. We can't know the type -- just pass it along
    523 * without type.
    524 * @deprecated Use goog.functions.identity instead.
    525 */
    526goog.identityFunction = function(opt_returnValue, var_args) {
    527 return opt_returnValue;
    528};
    529
    530
    531/**
    532 * When defining a class Foo with an abstract method bar(), you can do:
    533 * Foo.prototype.bar = goog.abstractMethod
    534 *
    535 * Now if a subclass of Foo fails to override bar(), an error will be thrown
    536 * when bar() is invoked.
    537 *
    538 * Note: This does not take the name of the function to override as an argument
    539 * because that would make it more difficult to obfuscate our JavaScript code.
    540 *
    541 * @type {!Function}
    542 * @throws {Error} when invoked to indicate the method should be overridden.
    543 */
    544goog.abstractMethod = function() {
    545 throw Error('unimplemented abstract method');
    546};
    547
    548
    549/**
    550 * Adds a {@code getInstance} static method that always returns the same
    551 * instance object.
    552 * @param {!Function} ctor The constructor for the class to add the static
    553 * method to.
    554 */
    555goog.addSingletonGetter = function(ctor) {
    556 ctor.getInstance = function() {
    557 if (ctor.instance_) {
    558 return ctor.instance_;
    559 }
    560 if (goog.DEBUG) {
    561 // NOTE: JSCompiler can't optimize away Array#push.
    562 goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor;
    563 }
    564 return ctor.instance_ = new ctor;
    565 };
    566};
    567
    568
    569/**
    570 * All singleton classes that have been instantiated, for testing. Don't read
    571 * it directly, use the {@code goog.testing.singleton} module. The compiler
    572 * removes this variable if unused.
    573 * @type {!Array.<!Function>}
    574 * @private
    575 */
    576goog.instantiatedSingletons_ = [];
    577
    578
    579/**
    580 * True if goog.dependencies_ is available.
    581 * @const {boolean}
    582 */
    583goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;
    584
    585
    586if (goog.DEPENDENCIES_ENABLED) {
    587 /**
    588 * Object used to keep track of urls that have already been added. This record
    589 * allows the prevention of circular dependencies.
    590 * @type {Object}
    591 * @private
    592 */
    593 goog.included_ = {};
    594
    595
    596 /**
    597 * This object is used to keep track of dependencies and other data that is
    598 * used for loading scripts.
    599 * @private
    600 * @type {Object}
    601 */
    602 goog.dependencies_ = {
    603 pathToNames: {}, // 1 to many
    604 nameToPath: {}, // 1 to 1
    605 requires: {}, // 1 to many
    606 // Used when resolving dependencies to prevent us from visiting file twice.
    607 visited: {},
    608 written: {} // Used to keep track of script files we have written.
    609 };
    610
    611
    612 /**
    613 * Tries to detect whether is in the context of an HTML document.
    614 * @return {boolean} True if it looks like HTML document.
    615 * @private
    616 */
    617 goog.inHtmlDocument_ = function() {
    618 var doc = goog.global.document;
    619 return typeof doc != 'undefined' &&
    620 'write' in doc; // XULDocument misses write.
    621 };
    622
    623
    624 /**
    625 * Tries to detect the base path of base.js script that bootstraps Closure.
    626 * @private
    627 */
    628 goog.findBasePath_ = function() {
    629 if (goog.global.CLOSURE_BASE_PATH) {
    630 goog.basePath = goog.global.CLOSURE_BASE_PATH;
    631 return;
    632 } else if (!goog.inHtmlDocument_()) {
    633 return;
    634 }
    635 var doc = goog.global.document;
    636 var scripts = doc.getElementsByTagName('script');
    637 // Search backwards since the current script is in almost all cases the one
    638 // that has base.js.
    639 for (var i = scripts.length - 1; i >= 0; --i) {
    640 var src = scripts[i].src;
    641 var qmark = src.lastIndexOf('?');
    642 var l = qmark == -1 ? src.length : qmark;
    643 if (src.substr(l - 7, 7) == 'base.js') {
    644 goog.basePath = src.substr(0, l - 7);
    645 return;
    646 }
    647 }
    648 };
    649
    650
    651 /**
    652 * Imports a script if, and only if, that script hasn't already been imported.
    653 * (Must be called at execution time)
    654 * @param {string} src Script source.
    655 * @private
    656 */
    657 goog.importScript_ = function(src) {
    658 var importScript = goog.global.CLOSURE_IMPORT_SCRIPT ||
    659 goog.writeScriptTag_;
    660 if (!goog.dependencies_.written[src] && importScript(src)) {
    661 goog.dependencies_.written[src] = true;
    662 }
    663 };
    664
    665
    666 /**
    667 * The default implementation of the import function. Writes a script tag to
    668 * import the script.
    669 *
    670 * @param {string} src The script source.
    671 * @return {boolean} True if the script was imported, false otherwise.
    672 * @private
    673 */
    674 goog.writeScriptTag_ = function(src) {
    675 if (goog.inHtmlDocument_()) {
    676 var doc = goog.global.document;
    677
    678 // If the user tries to require a new symbol after document load,
    679 // something has gone terribly wrong. Doing a document.write would
    680 // wipe out the page.
    681 if (doc.readyState == 'complete') {
    682 // Certain test frameworks load base.js multiple times, which tries
    683 // to write deps.js each time. If that happens, just fail silently.
    684 // These frameworks wipe the page between each load of base.js, so this
    685 // is OK.
    686 var isDeps = /\bdeps.js$/.test(src);
    687 if (isDeps) {
    688 return false;
    689 } else {
    690 throw Error('Cannot write "' + src + '" after document load');
    691 }
    692 }
    693
    694 doc.write(
    695 '<script type="text/javascript" src="' + src + '"></' + 'script>');
    696 return true;
    697 } else {
    698 return false;
    699 }
    700 };
    701
    702
    703 /**
    704 * Resolves dependencies based on the dependencies added using addDependency
    705 * and calls importScript_ in the correct order.
    706 * @private
    707 */
    708 goog.writeScripts_ = function() {
    709 // The scripts we need to write this time.
    710 var scripts = [];
    711 var seenScript = {};
    712 var deps = goog.dependencies_;
    713
    714 function visitNode(path) {
    715 if (path in deps.written) {
    716 return;
    717 }
    718
    719 // We have already visited this one. We can get here if we have cyclic
    720 // dependencies.
    721 if (path in deps.visited) {
    722 if (!(path in seenScript)) {
    723 seenScript[path] = true;
    724 scripts.push(path);
    725 }
    726 return;
    727 }
    728
    729 deps.visited[path] = true;
    730
    731 if (path in deps.requires) {
    732 for (var requireName in deps.requires[path]) {
    733 // If the required name is defined, we assume that it was already
    734 // bootstrapped by other means.
    735 if (!goog.isProvided_(requireName)) {
    736 if (requireName in deps.nameToPath) {
    737 visitNode(deps.nameToPath[requireName]);
    738 } else {
    739 throw Error('Undefined nameToPath for ' + requireName);
    740 }
    741 }
    742 }
    743 }
    744
    745 if (!(path in seenScript)) {
    746 seenScript[path] = true;
    747 scripts.push(path);
    748 }
    749 }
    750
    751 for (var path in goog.included_) {
    752 if (!deps.written[path]) {
    753 visitNode(path);
    754 }
    755 }
    756
    757 for (var i = 0; i < scripts.length; i++) {
    758 if (scripts[i]) {
    759 goog.importScript_(goog.basePath + scripts[i]);
    760 } else {
    761 throw Error('Undefined script input');
    762 }
    763 }
    764 };
    765
    766
    767 /**
    768 * Looks at the dependency rules and tries to determine the script file that
    769 * fulfills a particular rule.
    770 * @param {string} rule In the form goog.namespace.Class or project.script.
    771 * @return {?string} Url corresponding to the rule, or null.
    772 * @private
    773 */
    774 goog.getPathFromDeps_ = function(rule) {
    775 if (rule in goog.dependencies_.nameToPath) {
    776 return goog.dependencies_.nameToPath[rule];
    777 } else {
    778 return null;
    779 }
    780 };
    781
    782 goog.findBasePath_();
    783
    784 // Allow projects to manage the deps files themselves.
    785 if (!goog.global.CLOSURE_NO_DEPS) {
    786 goog.importScript_(goog.basePath + 'deps.js');
    787 }
    788}
    789
    790
    791
    792//==============================================================================
    793// Language Enhancements
    794//==============================================================================
    795
    796
    797/**
    798 * This is a "fixed" version of the typeof operator. It differs from the typeof
    799 * operator in such a way that null returns 'null' and arrays return 'array'.
    800 * @param {*} value The value to get the type of.
    801 * @return {string} The name of the type.
    802 */
    803goog.typeOf = function(value) {
    804 var s = typeof value;
    805 if (s == 'object') {
    806 if (value) {
    807 // Check these first, so we can avoid calling Object.prototype.toString if
    808 // possible.
    809 //
    810 // IE improperly marshals tyepof across execution contexts, but a
    811 // cross-context object will still return false for "instanceof Object".
    812 if (value instanceof Array) {
    813 return 'array';
    814 } else if (value instanceof Object) {
    815 return s;
    816 }
    817
    818 // HACK: In order to use an Object prototype method on the arbitrary
    819 // value, the compiler requires the value be cast to type Object,
    820 // even though the ECMA spec explicitly allows it.
    821 var className = Object.prototype.toString.call(
    822 /** @type {Object} */ (value));
    823 // In Firefox 3.6, attempting to access iframe window objects' length
    824 // property throws an NS_ERROR_FAILURE, so we need to special-case it
    825 // here.
    826 if (className == '[object Window]') {
    827 return 'object';
    828 }
    829
    830 // We cannot always use constructor == Array or instanceof Array because
    831 // different frames have different Array objects. In IE6, if the iframe
    832 // where the array was created is destroyed, the array loses its
    833 // prototype. Then dereferencing val.splice here throws an exception, so
    834 // we can't use goog.isFunction. Calling typeof directly returns 'unknown'
    835 // so that will work. In this case, this function will return false and
    836 // most array functions will still work because the array is still
    837 // array-like (supports length and []) even though it has lost its
    838 // prototype.
    839 // Mark Miller noticed that Object.prototype.toString
    840 // allows access to the unforgeable [[Class]] property.
    841 // 15.2.4.2 Object.prototype.toString ( )
    842 // When the toString method is called, the following steps are taken:
    843 // 1. Get the [[Class]] property of this object.
    844 // 2. Compute a string value by concatenating the three strings
    845 // "[object ", Result(1), and "]".
    846 // 3. Return Result(2).
    847 // and this behavior survives the destruction of the execution context.
    848 if ((className == '[object Array]' ||
    849 // In IE all non value types are wrapped as objects across window
    850 // boundaries (not iframe though) so we have to do object detection
    851 // for this edge case.
    852 typeof value.length == 'number' &&
    853 typeof value.splice != 'undefined' &&
    854 typeof value.propertyIsEnumerable != 'undefined' &&
    855 !value.propertyIsEnumerable('splice')
    856
    857 )) {
    858 return 'array';
    859 }
    860 // HACK: There is still an array case that fails.
    861 // function ArrayImpostor() {}
    862 // ArrayImpostor.prototype = [];
    863 // var impostor = new ArrayImpostor;
    864 // this can be fixed by getting rid of the fast path
    865 // (value instanceof Array) and solely relying on
    866 // (value && Object.prototype.toString.vall(value) === '[object Array]')
    867 // but that would require many more function calls and is not warranted
    868 // unless closure code is receiving objects from untrusted sources.
    869
    870 // IE in cross-window calls does not correctly marshal the function type
    871 // (it appears just as an object) so we cannot use just typeof val ==
    872 // 'function'. However, if the object has a call property, it is a
    873 // function.
    874 if ((className == '[object Function]' ||
    875 typeof value.call != 'undefined' &&
    876 typeof value.propertyIsEnumerable != 'undefined' &&
    877 !value.propertyIsEnumerable('call'))) {
    878 return 'function';
    879 }
    880
    881 } else {
    882 return 'null';
    883 }
    884
    885 } else if (s == 'function' && typeof value.call == 'undefined') {
    886 // In Safari typeof nodeList returns 'function', and on Firefox typeof
    887 // behaves similarly for HTML{Applet,Embed,Object}, Elements and RegExps. We
    888 // would like to return object for those and we can detect an invalid
    889 // function by making sure that the function object has a call method.
    890 return 'object';
    891 }
    892 return s;
    893};
    894
    895
    896/**
    897 * Returns true if the specified value is null.
    898 * @param {?} val Variable to test.
    899 * @return {boolean} Whether variable is null.
    900 */
    901goog.isNull = function(val) {
    902 return val === null;
    903};
    904
    905
    906/**
    907 * Returns true if the specified value is defined and not null.
    908 * @param {?} val Variable to test.
    909 * @return {boolean} Whether variable is defined and not null.
    910 */
    911goog.isDefAndNotNull = function(val) {
    912 // Note that undefined == null.
    913 return val != null;
    914};
    915
    916
    917/**
    918 * Returns true if the specified value is an array.
    919 * @param {?} val Variable to test.
    920 * @return {boolean} Whether variable is an array.
    921 */
    922goog.isArray = function(val) {
    923 return goog.typeOf(val) == 'array';
    924};
    925
    926
    927/**
    928 * Returns true if the object looks like an array. To qualify as array like
    929 * the value needs to be either a NodeList or an object with a Number length
    930 * property.
    931 * @param {?} val Variable to test.
    932 * @return {boolean} Whether variable is an array.
    933 */
    934goog.isArrayLike = function(val) {
    935 var type = goog.typeOf(val);
    936 return type == 'array' || type == 'object' && typeof val.length == 'number';
    937};
    938
    939
    940/**
    941 * Returns true if the object looks like a Date. To qualify as Date-like the
    942 * value needs to be an object and have a getFullYear() function.
    943 * @param {?} val Variable to test.
    944 * @return {boolean} Whether variable is a like a Date.
    945 */
    946goog.isDateLike = function(val) {
    947 return goog.isObject(val) && typeof val.getFullYear == 'function';
    948};
    949
    950
    951/**
    952 * Returns true if the specified value is a string.
    953 * @param {?} val Variable to test.
    954 * @return {boolean} Whether variable is a string.
    955 */
    956goog.isString = function(val) {
    957 return typeof val == 'string';
    958};
    959
    960
    961/**
    962 * Returns true if the specified value is a boolean.
    963 * @param {?} val Variable to test.
    964 * @return {boolean} Whether variable is boolean.
    965 */
    966goog.isBoolean = function(val) {
    967 return typeof val == 'boolean';
    968};
    969
    970
    971/**
    972 * Returns true if the specified value is a number.
    973 * @param {?} val Variable to test.
    974 * @return {boolean} Whether variable is a number.
    975 */
    976goog.isNumber = function(val) {
    977 return typeof val == 'number';
    978};
    979
    980
    981/**
    982 * Returns true if the specified value is a function.
    983 * @param {?} val Variable to test.
    984 * @return {boolean} Whether variable is a function.
    985 */
    986goog.isFunction = function(val) {
    987 return goog.typeOf(val) == 'function';
    988};
    989
    990
    991/**
    992 * Returns true if the specified value is an object. This includes arrays and
    993 * functions.
    994 * @param {?} val Variable to test.
    995 * @return {boolean} Whether variable is an object.
    996 */
    997goog.isObject = function(val) {
    998 var type = typeof val;
    999 return type == 'object' && val != null || type == 'function';
    1000 // return Object(val) === val also works, but is slower, especially if val is
    1001 // not an object.
    1002};
    1003
    1004
    1005/**
    1006 * Gets a unique ID for an object. This mutates the object so that further calls
    1007 * with the same object as a parameter returns the same value. The unique ID is
    1008 * guaranteed to be unique across the current session amongst objects that are
    1009 * passed into {@code getUid}. There is no guarantee that the ID is unique or
    1010 * consistent across sessions. It is unsafe to generate unique ID for function
    1011 * prototypes.
    1012 *
    1013 * @param {Object} obj The object to get the unique ID for.
    1014 * @return {number} The unique ID for the object.
    1015 */
    1016goog.getUid = function(obj) {
    1017 // TODO(arv): Make the type stricter, do not accept null.
    1018
    1019 // In Opera window.hasOwnProperty exists but always returns false so we avoid
    1020 // using it. As a consequence the unique ID generated for BaseClass.prototype
    1021 // and SubClass.prototype will be the same.
    1022 return obj[goog.UID_PROPERTY_] ||
    1023 (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_);
    1024};
    1025
    1026
    1027/**
    1028 * Whether the given object is alreay assigned a unique ID.
    1029 *
    1030 * This does not modify the object.
    1031 *
    1032 * @param {Object} obj The object to check.
    1033 * @return {boolean} Whether there an assigned unique id for the object.
    1034 */
    1035goog.hasUid = function(obj) {
    1036 return !!obj[goog.UID_PROPERTY_];
    1037};
    1038
    1039
    1040/**
    1041 * Removes the unique ID from an object. This is useful if the object was
    1042 * previously mutated using {@code goog.getUid} in which case the mutation is
    1043 * undone.
    1044 * @param {Object} obj The object to remove the unique ID field from.
    1045 */
    1046goog.removeUid = function(obj) {
    1047 // TODO(arv): Make the type stricter, do not accept null.
    1048
    1049 // In IE, DOM nodes are not instances of Object and throw an exception if we
    1050 // try to delete. Instead we try to use removeAttribute.
    1051 if ('removeAttribute' in obj) {
    1052 obj.removeAttribute(goog.UID_PROPERTY_);
    1053 }
    1054 /** @preserveTry */
    1055 try {
    1056 delete obj[goog.UID_PROPERTY_];
    1057 } catch (ex) {
    1058 }
    1059};
    1060
    1061
    1062/**
    1063 * Name for unique ID property. Initialized in a way to help avoid collisions
    1064 * with other closure JavaScript on the same page.
    1065 * @type {string}
    1066 * @private
    1067 */
    1068goog.UID_PROPERTY_ = 'closure_uid_' + ((Math.random() * 1e9) >>> 0);
    1069
    1070
    1071/**
    1072 * Counter for UID.
    1073 * @type {number}
    1074 * @private
    1075 */
    1076goog.uidCounter_ = 0;
    1077
    1078
    1079/**
    1080 * Adds a hash code field to an object. The hash code is unique for the
    1081 * given object.
    1082 * @param {Object} obj The object to get the hash code for.
    1083 * @return {number} The hash code for the object.
    1084 * @deprecated Use goog.getUid instead.
    1085 */
    1086goog.getHashCode = goog.getUid;
    1087
    1088
    1089/**
    1090 * Removes the hash code field from an object.
    1091 * @param {Object} obj The object to remove the field from.
    1092 * @deprecated Use goog.removeUid instead.
    1093 */
    1094goog.removeHashCode = goog.removeUid;
    1095
    1096
    1097/**
    1098 * Clones a value. The input may be an Object, Array, or basic type. Objects and
    1099 * arrays will be cloned recursively.
    1100 *
    1101 * WARNINGS:
    1102 * <code>goog.cloneObject</code> does not detect reference loops. Objects that
    1103 * refer to themselves will cause infinite recursion.
    1104 *
    1105 * <code>goog.cloneObject</code> is unaware of unique identifiers, and copies
    1106 * UIDs created by <code>getUid</code> into cloned results.
    1107 *
    1108 * @param {*} obj The value to clone.
    1109 * @return {*} A clone of the input value.
    1110 * @deprecated goog.cloneObject is unsafe. Prefer the goog.object methods.
    1111 */
    1112goog.cloneObject = function(obj) {
    1113 var type = goog.typeOf(obj);
    1114 if (type == 'object' || type == 'array') {
    1115 if (obj.clone) {
    1116 return obj.clone();
    1117 }
    1118 var clone = type == 'array' ? [] : {};
    1119 for (var key in obj) {
    1120 clone[key] = goog.cloneObject(obj[key]);
    1121 }
    1122 return clone;
    1123 }
    1124
    1125 return obj;
    1126};
    1127
    1128
    1129/**
    1130 * A native implementation of goog.bind.
    1131 * @param {Function} fn A function to partially apply.
    1132 * @param {Object|undefined} selfObj Specifies the object which this should
    1133 * point to when the function is run.
    1134 * @param {...*} var_args Additional arguments that are partially applied to the
    1135 * function.
    1136 * @return {!Function} A partially-applied form of the function bind() was
    1137 * invoked as a method of.
    1138 * @private
    1139 * @suppress {deprecated} The compiler thinks that Function.prototype.bind is
    1140 * deprecated because some people have declared a pure-JS version.
    1141 * Only the pure-JS version is truly deprecated.
    1142 */
    1143goog.bindNative_ = function(fn, selfObj, var_args) {
    1144 return /** @type {!Function} */ (fn.call.apply(fn.bind, arguments));
    1145};
    1146
    1147
    1148/**
    1149 * A pure-JS implementation of goog.bind.
    1150 * @param {Function} fn A function to partially apply.
    1151 * @param {Object|undefined} selfObj Specifies the object which this should
    1152 * point to when the function is run.
    1153 * @param {...*} var_args Additional arguments that are partially applied to the
    1154 * function.
    1155 * @return {!Function} A partially-applied form of the function bind() was
    1156 * invoked as a method of.
    1157 * @private
    1158 */
    1159goog.bindJs_ = function(fn, selfObj, var_args) {
    1160 if (!fn) {
    1161 throw new Error();
    1162 }
    1163
    1164 if (arguments.length > 2) {
    1165 var boundArgs = Array.prototype.slice.call(arguments, 2);
    1166 return function() {
    1167 // Prepend the bound arguments to the current arguments.
    1168 var newArgs = Array.prototype.slice.call(arguments);
    1169 Array.prototype.unshift.apply(newArgs, boundArgs);
    1170 return fn.apply(selfObj, newArgs);
    1171 };
    1172
    1173 } else {
    1174 return function() {
    1175 return fn.apply(selfObj, arguments);
    1176 };
    1177 }
    1178};
    1179
    1180
    1181/**
    1182 * Partially applies this function to a particular 'this object' and zero or
    1183 * more arguments. The result is a new function with some arguments of the first
    1184 * function pre-filled and the value of this 'pre-specified'.
    1185 *
    1186 * Remaining arguments specified at call-time are appended to the pre-specified
    1187 * ones.
    1188 *
    1189 * Also see: {@link #partial}.
    1190 *
    1191 * Usage:
    1192 * <pre>var barMethBound = bind(myFunction, myObj, 'arg1', 'arg2');
    1193 * barMethBound('arg3', 'arg4');</pre>
    1194 *
    1195 * @param {?function(this:T, ...)} fn A function to partially apply.
    1196 * @param {T} selfObj Specifies the object which this should point to when the
    1197 * function is run.
    1198 * @param {...*} var_args Additional arguments that are partially applied to the
    1199 * function.
    1200 * @return {!Function} A partially-applied form of the function bind() was
    1201 * invoked as a method of.
    1202 * @template T
    1203 * @suppress {deprecated} See above.
    1204 */
    1205goog.bind = function(fn, selfObj, var_args) {
    1206 // TODO(nicksantos): narrow the type signature.
    1207 if (Function.prototype.bind &&
    1208 // NOTE(nicksantos): Somebody pulled base.js into the default Chrome
    1209 // extension environment. This means that for Chrome extensions, they get
    1210 // the implementation of Function.prototype.bind that calls goog.bind
    1211 // instead of the native one. Even worse, we don't want to introduce a
    1212 // circular dependency between goog.bind and Function.prototype.bind, so
    1213 // we have to hack this to make sure it works correctly.
    1214 Function.prototype.bind.toString().indexOf('native code') != -1) {
    1215 goog.bind = goog.bindNative_;
    1216 } else {
    1217 goog.bind = goog.bindJs_;
    1218 }
    1219 return goog.bind.apply(null, arguments);
    1220};
    1221
    1222
    1223/**
    1224 * Like bind(), except that a 'this object' is not required. Useful when the
    1225 * target function is already bound.
    1226 *
    1227 * Usage:
    1228 * var g = partial(f, arg1, arg2);
    1229 * g(arg3, arg4);
    1230 *
    1231 * @param {Function} fn A function to partially apply.
    1232 * @param {...*} var_args Additional arguments that are partially applied to fn.
    1233 * @return {!Function} A partially-applied form of the function bind() was
    1234 * invoked as a method of.
    1235 */
    1236goog.partial = function(fn, var_args) {
    1237 var args = Array.prototype.slice.call(arguments, 1);
    1238 return function() {
    1239 // Clone the array (with slice()) and append additional arguments
    1240 // to the existing arguments.
    1241 var newArgs = args.slice();
    1242 newArgs.push.apply(newArgs, arguments);
    1243 return fn.apply(this, newArgs);
    1244 };
    1245};
    1246
    1247
    1248/**
    1249 * Copies all the members of a source object to a target object. This method
    1250 * does not work on all browsers for all objects that contain keys such as
    1251 * toString or hasOwnProperty. Use goog.object.extend for this purpose.
    1252 * @param {Object} target Target.
    1253 * @param {Object} source Source.
    1254 */
    1255goog.mixin = function(target, source) {
    1256 for (var x in source) {
    1257 target[x] = source[x];
    1258 }
    1259
    1260 // For IE7 or lower, the for-in-loop does not contain any properties that are
    1261 // not enumerable on the prototype object (for example, isPrototypeOf from
    1262 // Object.prototype) but also it will not include 'replace' on objects that
    1263 // extend String and change 'replace' (not that it is common for anyone to
    1264 // extend anything except Object).
    1265};
    1266
    1267
    1268/**
    1269 * @return {number} An integer value representing the number of milliseconds
    1270 * between midnight, January 1, 1970 and the current time.
    1271 */
    1272goog.now = (goog.TRUSTED_SITE && Date.now) || (function() {
    1273 // Unary plus operator converts its operand to a number which in the case of
    1274 // a date is done by calling getTime().
    1275 return +new Date();
    1276});
    1277
    1278
    1279/**
    1280 * Evals JavaScript in the global scope. In IE this uses execScript, other
    1281 * browsers use goog.global.eval. If goog.global.eval does not evaluate in the
    1282 * global scope (for example, in Safari), appends a script tag instead.
    1283 * Throws an exception if neither execScript or eval is defined.
    1284 * @param {string} script JavaScript string.
    1285 */
    1286goog.globalEval = function(script) {
    1287 if (goog.global.execScript) {
    1288 goog.global.execScript(script, 'JavaScript');
    1289 } else if (goog.global.eval) {
    1290 // Test to see if eval works
    1291 if (goog.evalWorksForGlobals_ == null) {
    1292 goog.global.eval('var _et_ = 1;');
    1293 if (typeof goog.global['_et_'] != 'undefined') {
    1294 delete goog.global['_et_'];
    1295 goog.evalWorksForGlobals_ = true;
    1296 } else {
    1297 goog.evalWorksForGlobals_ = false;
    1298 }
    1299 }
    1300
    1301 if (goog.evalWorksForGlobals_) {
    1302 goog.global.eval(script);
    1303 } else {
    1304 var doc = goog.global.document;
    1305 var scriptElt = doc.createElement('script');
    1306 scriptElt.type = 'text/javascript';
    1307 scriptElt.defer = false;
    1308 // Note(user): can't use .innerHTML since "t('<test>')" will fail and
    1309 // .text doesn't work in Safari 2. Therefore we append a text node.
    1310 scriptElt.appendChild(doc.createTextNode(script));
    1311 doc.body.appendChild(scriptElt);
    1312 doc.body.removeChild(scriptElt);
    1313 }
    1314 } else {
    1315 throw Error('goog.globalEval not available');
    1316 }
    1317};
    1318
    1319
    1320/**
    1321 * Indicates whether or not we can call 'eval' directly to eval code in the
    1322 * global scope. Set to a Boolean by the first call to goog.globalEval (which
    1323 * empirically tests whether eval works for globals). @see goog.globalEval
    1324 * @type {?boolean}
    1325 * @private
    1326 */
    1327goog.evalWorksForGlobals_ = null;
    1328
    1329
    1330/**
    1331 * Optional map of CSS class names to obfuscated names used with
    1332 * goog.getCssName().
    1333 * @type {Object|undefined}
    1334 * @private
    1335 * @see goog.setCssNameMapping
    1336 */
    1337goog.cssNameMapping_;
    1338
    1339
    1340/**
    1341 * Optional obfuscation style for CSS class names. Should be set to either
    1342 * 'BY_WHOLE' or 'BY_PART' if defined.
    1343 * @type {string|undefined}
    1344 * @private
    1345 * @see goog.setCssNameMapping
    1346 */
    1347goog.cssNameMappingStyle_;
    1348
    1349
    1350/**
    1351 * Handles strings that are intended to be used as CSS class names.
    1352 *
    1353 * This function works in tandem with @see goog.setCssNameMapping.
    1354 *
    1355 * Without any mapping set, the arguments are simple joined with a hyphen and
    1356 * passed through unaltered.
    1357 *
    1358 * When there is a mapping, there are two possible styles in which these
    1359 * mappings are used. In the BY_PART style, each part (i.e. in between hyphens)
    1360 * of the passed in css name is rewritten according to the map. In the BY_WHOLE
    1361 * style, the full css name is looked up in the map directly. If a rewrite is
    1362 * not specified by the map, the compiler will output a warning.
    1363 *
    1364 * When the mapping is passed to the compiler, it will replace calls to
    1365 * goog.getCssName with the strings from the mapping, e.g.
    1366 * var x = goog.getCssName('foo');
    1367 * var y = goog.getCssName(this.baseClass, 'active');
    1368 * becomes:
    1369 * var x= 'foo';
    1370 * var y = this.baseClass + '-active';
    1371 *
    1372 * If one argument is passed it will be processed, if two are passed only the
    1373 * modifier will be processed, as it is assumed the first argument was generated
    1374 * as a result of calling goog.getCssName.
    1375 *
    1376 * @param {string} className The class name.
    1377 * @param {string=} opt_modifier A modifier to be appended to the class name.
    1378 * @return {string} The class name or the concatenation of the class name and
    1379 * the modifier.
    1380 */
    1381goog.getCssName = function(className, opt_modifier) {
    1382 var getMapping = function(cssName) {
    1383 return goog.cssNameMapping_[cssName] || cssName;
    1384 };
    1385
    1386 var renameByParts = function(cssName) {
    1387 // Remap all the parts individually.
    1388 var parts = cssName.split('-');
    1389 var mapped = [];
    1390 for (var i = 0; i < parts.length; i++) {
    1391 mapped.push(getMapping(parts[i]));
    1392 }
    1393 return mapped.join('-');
    1394 };
    1395
    1396 var rename;
    1397 if (goog.cssNameMapping_) {
    1398 rename = goog.cssNameMappingStyle_ == 'BY_WHOLE' ?
    1399 getMapping : renameByParts;
    1400 } else {
    1401 rename = function(a) {
    1402 return a;
    1403 };
    1404 }
    1405
    1406 if (opt_modifier) {
    1407 return className + '-' + rename(opt_modifier);
    1408 } else {
    1409 return rename(className);
    1410 }
    1411};
    1412
    1413
    1414/**
    1415 * Sets the map to check when returning a value from goog.getCssName(). Example:
    1416 * <pre>
    1417 * goog.setCssNameMapping({
    1418 * "goog": "a",
    1419 * "disabled": "b",
    1420 * });
    1421 *
    1422 * var x = goog.getCssName('goog');
    1423 * // The following evaluates to: "a a-b".
    1424 * goog.getCssName('goog') + ' ' + goog.getCssName(x, 'disabled')
    1425 * </pre>
    1426 * When declared as a map of string literals to string literals, the JSCompiler
    1427 * will replace all calls to goog.getCssName() using the supplied map if the
    1428 * --closure_pass flag is set.
    1429 *
    1430 * @param {!Object} mapping A map of strings to strings where keys are possible
    1431 * arguments to goog.getCssName() and values are the corresponding values
    1432 * that should be returned.
    1433 * @param {string=} opt_style The style of css name mapping. There are two valid
    1434 * options: 'BY_PART', and 'BY_WHOLE'.
    1435 * @see goog.getCssName for a description.
    1436 */
    1437goog.setCssNameMapping = function(mapping, opt_style) {
    1438 goog.cssNameMapping_ = mapping;
    1439 goog.cssNameMappingStyle_ = opt_style;
    1440};
    1441
    1442
    1443/**
    1444 * To use CSS renaming in compiled mode, one of the input files should have a
    1445 * call to goog.setCssNameMapping() with an object literal that the JSCompiler
    1446 * can extract and use to replace all calls to goog.getCssName(). In uncompiled
    1447 * mode, JavaScript code should be loaded before this base.js file that declares
    1448 * a global variable, CLOSURE_CSS_NAME_MAPPING, which is used below. This is
    1449 * to ensure that the mapping is loaded before any calls to goog.getCssName()
    1450 * are made in uncompiled mode.
    1451 *
    1452 * A hook for overriding the CSS name mapping.
    1453 * @type {Object|undefined}
    1454 */
    1455goog.global.CLOSURE_CSS_NAME_MAPPING;
    1456
    1457
    1458if (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) {
    1459 // This does not call goog.setCssNameMapping() because the JSCompiler
    1460 // requires that goog.setCssNameMapping() be called with an object literal.
    1461 goog.cssNameMapping_ = goog.global.CLOSURE_CSS_NAME_MAPPING;
    1462}
    1463
    1464
    1465/**
    1466 * Gets a localized message.
    1467 *
    1468 * This function is a compiler primitive. If you give the compiler a localized
    1469 * message bundle, it will replace the string at compile-time with a localized
    1470 * version, and expand goog.getMsg call to a concatenated string.
    1471 *
    1472 * Messages must be initialized in the form:
    1473 * <code>
    1474 * var MSG_NAME = goog.getMsg('Hello {$placeholder}', {'placeholder': 'world'});
    1475 * </code>
    1476 *
    1477 * @param {string} str Translatable string, places holders in the form {$foo}.
    1478 * @param {Object=} opt_values Map of place holder name to value.
    1479 * @return {string} message with placeholders filled.
    1480 */
    1481goog.getMsg = function(str, opt_values) {
    1482 var values = opt_values || {};
    1483 for (var key in values) {
    1484 var value = ('' + values[key]).replace(/\$/g, '$$$$');
    1485 str = str.replace(new RegExp('\\{\\$' + key + '\\}', 'gi'), value);
    1486 }
    1487 return str;
    1488};
    1489
    1490
    1491/**
    1492 * Gets a localized message. If the message does not have a translation, gives a
    1493 * fallback message.
    1494 *
    1495 * This is useful when introducing a new message that has not yet been
    1496 * translated into all languages.
    1497 *
    1498 * This function is a compiler primitive. Must be used in the form:
    1499 * <code>var x = goog.getMsgWithFallback(MSG_A, MSG_B);</code>
    1500 * where MSG_A and MSG_B were initialized with goog.getMsg.
    1501 *
    1502 * @param {string} a The preferred message.
    1503 * @param {string} b The fallback message.
    1504 * @return {string} The best translated message.
    1505 */
    1506goog.getMsgWithFallback = function(a, b) {
    1507 return a;
    1508};
    1509
    1510
    1511/**
    1512 * Exposes an unobfuscated global namespace path for the given object.
    1513 * Note that fields of the exported object *will* be obfuscated, unless they are
    1514 * exported in turn via this function or goog.exportProperty.
    1515 *
    1516 * Also handy for making public items that are defined in anonymous closures.
    1517 *
    1518 * ex. goog.exportSymbol('public.path.Foo', Foo);
    1519 *
    1520 * ex. goog.exportSymbol('public.path.Foo.staticFunction', Foo.staticFunction);
    1521 * public.path.Foo.staticFunction();
    1522 *
    1523 * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod',
    1524 * Foo.prototype.myMethod);
    1525 * new public.path.Foo().myMethod();
    1526 *
    1527 * @param {string} publicPath Unobfuscated name to export.
    1528 * @param {*} object Object the name should point to.
    1529 * @param {Object=} opt_objectToExportTo The object to add the path to; default
    1530 * is goog.global.
    1531 */
    1532goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) {
    1533 goog.exportPath_(publicPath, object, opt_objectToExportTo);
    1534};
    1535
    1536
    1537/**
    1538 * Exports a property unobfuscated into the object's namespace.
    1539 * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction);
    1540 * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod);
    1541 * @param {Object} object Object whose static property is being exported.
    1542 * @param {string} publicName Unobfuscated name to export.
    1543 * @param {*} symbol Object the name should point to.
    1544 */
    1545goog.exportProperty = function(object, publicName, symbol) {
    1546 object[publicName] = symbol;
    1547};
    1548
    1549
    1550/**
    1551 * Inherit the prototype methods from one constructor into another.
    1552 *
    1553 * Usage:
    1554 * <pre>
    1555 * function ParentClass(a, b) { }
    1556 * ParentClass.prototype.foo = function(a) { }
    1557 *
    1558 * function ChildClass(a, b, c) {
    1559 * goog.base(this, a, b);
    1560 * }
    1561 * goog.inherits(ChildClass, ParentClass);
    1562 *
    1563 * var child = new ChildClass('a', 'b', 'see');
    1564 * child.foo(); // This works.
    1565 * </pre>
    1566 *
    1567 * In addition, a superclass' implementation of a method can be invoked as
    1568 * follows:
    1569 *
    1570 * <pre>
    1571 * ChildClass.prototype.foo = function(a) {
    1572 * ChildClass.superClass_.foo.call(this, a);
    1573 * // Other code here.
    1574 * };
    1575 * </pre>
    1576 *
    1577 * @param {Function} childCtor Child class.
    1578 * @param {Function} parentCtor Parent class.
    1579 */
    1580goog.inherits = function(childCtor, parentCtor) {
    1581 /** @constructor */
    1582 function tempCtor() {};
    1583 tempCtor.prototype = parentCtor.prototype;
    1584 childCtor.superClass_ = parentCtor.prototype;
    1585 childCtor.prototype = new tempCtor();
    1586 /** @override */
    1587 childCtor.prototype.constructor = childCtor;
    1588
    1589 /**
    1590 * Calls superclass constructor/method.
    1591 *
    1592 * This function is only available if you use goog.inherits to
    1593 * express inheritance relationships between classes.
    1594 *
    1595 * NOTE: This is a replacement for goog.base and for superClass_
    1596 * property defined in childCtor.
    1597 *
    1598 * @param {!Object} me Should always be "this".
    1599 * @param {string} methodName The method name to call. Calling
    1600 * superclass constructor can be done with the special string
    1601 * 'constructor'.
    1602 * @param {...*} var_args The arguments to pass to superclass
    1603 * method/constructor.
    1604 * @return {*} The return value of the superclass method/constructor.
    1605 */
    1606 childCtor.base = function(me, methodName, var_args) {
    1607 var args = Array.prototype.slice.call(arguments, 2);
    1608 return parentCtor.prototype[methodName].apply(me, args);
    1609 };
    1610};
    1611
    1612
    1613/**
    1614 * Call up to the superclass.
    1615 *
    1616 * If this is called from a constructor, then this calls the superclass
    1617 * constructor with arguments 1-N.
    1618 *
    1619 * If this is called from a prototype method, then you must pass the name of the
    1620 * method as the second argument to this function. If you do not, you will get a
    1621 * runtime error. This calls the superclass' method with arguments 2-N.
    1622 *
    1623 * This function only works if you use goog.inherits to express inheritance
    1624 * relationships between your classes.
    1625 *
    1626 * This function is a compiler primitive. At compile-time, the compiler will do
    1627 * macro expansion to remove a lot of the extra overhead that this function
    1628 * introduces. The compiler will also enforce a lot of the assumptions that this
    1629 * function makes, and treat it as a compiler error if you break them.
    1630 *
    1631 * @param {!Object} me Should always be "this".
    1632 * @param {*=} opt_methodName The method name if calling a super method.
    1633 * @param {...*} var_args The rest of the arguments.
    1634 * @return {*} The return value of the superclass method.
    1635 * @suppress {es5Strict} This method can not be used in strict mode, but
    1636 * all Closure Library consumers must depend on this file.
    1637 */
    1638goog.base = function(me, opt_methodName, var_args) {
    1639 var caller = arguments.callee.caller;
    1640
    1641 if (goog.STRICT_MODE_COMPATIBLE || (goog.DEBUG && !caller)) {
    1642 throw Error('arguments.caller not defined. goog.base() cannot be used ' +
    1643 'with strict mode code. See ' +
    1644 'http://www.ecma-international.org/ecma-262/5.1/#sec-C');
    1645 }
    1646
    1647 if (caller.superClass_) {
    1648 // This is a constructor. Call the superclass constructor.
    1649 return caller.superClass_.constructor.apply(
    1650 me, Array.prototype.slice.call(arguments, 1));
    1651 }
    1652
    1653 var args = Array.prototype.slice.call(arguments, 2);
    1654 var foundCaller = false;
    1655 for (var ctor = me.constructor;
    1656 ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) {
    1657 if (ctor.prototype[opt_methodName] === caller) {
    1658 foundCaller = true;
    1659 } else if (foundCaller) {
    1660 return ctor.prototype[opt_methodName].apply(me, args);
    1661 }
    1662 }
    1663
    1664 // If we did not find the caller in the prototype chain, then one of two
    1665 // things happened:
    1666 // 1) The caller is an instance method.
    1667 // 2) This method was not called by the right caller.
    1668 if (me[opt_methodName] === caller) {
    1669 return me.constructor.prototype[opt_methodName].apply(me, args);
    1670 } else {
    1671 throw Error(
    1672 'goog.base called from a method of one name ' +
    1673 'to a method of a different name');
    1674 }
    1675};
    1676
    1677
    1678/**
    1679 * Allow for aliasing within scope functions. This function exists for
    1680 * uncompiled code - in compiled code the calls will be inlined and the aliases
    1681 * applied. In uncompiled code the function is simply run since the aliases as
    1682 * written are valid JavaScript.
    1683 * @param {function()} fn Function to call. This function can contain aliases
    1684 * to namespaces (e.g. "var dom = goog.dom") or classes
    1685 * (e.g. "var Timer = goog.Timer").
    1686 */
    1687goog.scope = function(fn) {
    1688 fn.call(goog.global);
    1689};
    1690
    1691
    1692/*
    1693 * To support uncompiled, strict mode bundles that use eval to divide source
    1694 * like so:
    1695 * eval('someSource;//# sourceUrl sourcefile.js');
    1696 * We need to export the globally defined symbols "goog" and "COMPILED".
    1697 * Exporting "goog" breaks the compiler optimizations, so we required that
    1698 * be defined externally.
    1699 * NOTE: We don't use goog.exportSymbol here because we don't want to trigger
    1700 * extern generation when that compiler option is enabled.
    1701 */
    1702if (!COMPILED) {
    1703 goog.global['COMPILED'] = COMPILED;
    1704}
    1705
    1706
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/debug/error.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/debug/error.js.src.html new file mode 100644 index 0000000..e0d4295 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/debug/error.js.src.html @@ -0,0 +1 @@ +error.js

    lib/goog/debug/error.js

    1// Copyright 2009 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Provides a base class for custom Error objects such that the
    17 * stack is correctly maintained.
    18 *
    19 * You should never need to throw goog.debug.Error(msg) directly, Error(msg) is
    20 * sufficient.
    21 *
    22 */
    23
    24goog.provide('goog.debug.Error');
    25
    26
    27
    28/**
    29 * Base class for custom error objects.
    30 * @param {*=} opt_msg The message associated with the error.
    31 * @constructor
    32 * @extends {Error}
    33 */
    34goog.debug.Error = function(opt_msg) {
    35
    36 // Attempt to ensure there is a stack trace.
    37 if (Error.captureStackTrace) {
    38 Error.captureStackTrace(this, goog.debug.Error);
    39 } else {
    40 var stack = new Error().stack;
    41 if (stack) {
    42 this.stack = stack;
    43 }
    44 }
    45
    46 if (opt_msg) {
    47 this.message = String(opt_msg);
    48 }
    49};
    50goog.inherits(goog.debug.Error, Error);
    51
    52
    53/** @override */
    54goog.debug.Error.prototype.name = 'CustomError';
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/deps.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/deps.js.src.html new file mode 100644 index 0000000..6889637 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/deps.js.src.html @@ -0,0 +1 @@ +deps.js

    lib/goog/deps.js

    1// This file has been auto-generated; do not edit by hand
    2goog.addDependency("../atoms/error.js", ["bot.Error","bot.ErrorCode"], []);
    3goog.addDependency("../atoms/response.js", ["bot.response","bot.response.ResponseObject"], ["bot.Error","bot.ErrorCode"]);
    4goog.addDependency("../atoms/json.js", ["bot.json"], ["bot.userAgent","goog.json","goog.userAgent"]);
    5goog.addDependency("../atoms/userAgent.js", ["bot.userAgent"], ["goog.string","goog.userAgent","goog.userAgent.product","goog.userAgent.product.isVersion"]);
    6goog.addDependency("string/string.js", ["goog.string","goog.string.Unicode"], []);
    7goog.addDependency("useragent/useragent.js", ["goog.userAgent"], ["goog.labs.userAgent.browser","goog.labs.userAgent.engine","goog.labs.userAgent.util","goog.string"]);
    8goog.addDependency("labs/useragent/browser.js", ["goog.labs.userAgent.browser"], ["goog.array","goog.asserts","goog.labs.userAgent.util","goog.string"]);
    9goog.addDependency("array/array.js", ["goog.array","goog.array.ArrayLike"], ["goog.asserts"]);
    10goog.addDependency("asserts/asserts.js", ["goog.asserts","goog.asserts.AssertionError"], ["goog.debug.Error","goog.dom.NodeType","goog.string"]);
    11goog.addDependency("debug/error.js", ["goog.debug.Error"], []);
    12goog.addDependency("dom/nodetype.js", ["goog.dom.NodeType"], []);
    13goog.addDependency("labs/useragent/util.js", ["goog.labs.userAgent.util"], ["goog.string"]);
    14goog.addDependency("labs/useragent/engine.js", ["goog.labs.userAgent.engine"], ["goog.array","goog.labs.userAgent.util","goog.string"]);
    15goog.addDependency("useragent/product.js", ["goog.userAgent.product"], ["goog.userAgent"]);
    16goog.addDependency("useragent/product_isversion.js", ["goog.userAgent.product.isVersion"], ["goog.userAgent.product"]);
    17goog.addDependency("json/json.js", ["goog.json","goog.json.Replacer","goog.json.Reviver","goog.json.Serializer"], []);
    18goog.addDependency("../webdriver/capabilities.js", ["webdriver.Browser","webdriver.Capabilities","webdriver.Capability"], []);
    19goog.addDependency("../webdriver/logging.js", ["webdriver.logging","webdriver.logging.Preferences"], ["goog.object"]);
    20goog.addDependency("object/object.js", ["goog.object"], []);
    21goog.addDependency("../webdriver/actionsequence.js", ["webdriver.ActionSequence"], ["goog.array","webdriver.Button","webdriver.Command","webdriver.CommandName","webdriver.Key"]);
    22goog.addDependency("../webdriver/button.js", ["webdriver.Button"], []);
    23goog.addDependency("../webdriver/command.js", ["webdriver.Command","webdriver.CommandExecutor","webdriver.CommandName"], []);
    24goog.addDependency("../webdriver/key.js", ["webdriver.Key"], []);
    25goog.addDependency("../webdriver/stacktrace.js", ["webdriver.stacktrace","webdriver.stacktrace.Snapshot"], ["goog.array","goog.string","goog.userAgent"]);
    26goog.addDependency("../webdriver/locators.js", ["webdriver.By","webdriver.Locator","webdriver.Locator.Strategy"], ["goog.array","goog.object","goog.string"]);
    27goog.addDependency("../webdriver/promise.js", ["webdriver.promise","webdriver.promise.ControlFlow","webdriver.promise.ControlFlow.Timer","webdriver.promise.Deferred","webdriver.promise.Promise"], ["goog.array","goog.debug.Error","goog.object","webdriver.EventEmitter","webdriver.stacktrace.Snapshot"]);
    28goog.addDependency("../webdriver/events.js", ["webdriver.EventEmitter"], []);
    29goog.addDependency("../webdriver/process.js", ["webdriver.process"], ["goog.Uri","goog.array","goog.json"]);
    30goog.addDependency("uri/uri.js", ["goog.Uri","goog.Uri.QueryData"], ["goog.array","goog.string","goog.structs","goog.structs.Map","goog.uri.utils","goog.uri.utils.ComponentIndex","goog.uri.utils.StandardQueryParam"]);
    31goog.addDependency("structs/structs.js", ["goog.structs"], ["goog.array","goog.object"]);
    32goog.addDependency("structs/map.js", ["goog.structs.Map"], ["goog.iter.Iterator","goog.iter.StopIteration","goog.object"]);
    33goog.addDependency("iter/iter.js", ["goog.iter","goog.iter.Iterable","goog.iter.Iterator","goog.iter.StopIteration"], ["goog.array","goog.asserts","goog.functions","goog.math"]);
    34goog.addDependency("functions/functions.js", ["goog.functions"], []);
    35goog.addDependency("math/math.js", ["goog.math"], ["goog.array","goog.asserts"]);
    36goog.addDependency("uri/utils.js", ["goog.uri.utils","goog.uri.utils.ComponentIndex","goog.uri.utils.QueryArray","goog.uri.utils.QueryValue","goog.uri.utils.StandardQueryParam"], ["goog.asserts","goog.string","goog.userAgent"]);
    37goog.addDependency("../webdriver/webdriver.js", ["webdriver.Alert","webdriver.UnhandledAlertError","webdriver.WebDriver","webdriver.WebElement"], ["bot.Error","bot.ErrorCode","bot.response","goog.array","goog.object","webdriver.ActionSequence","webdriver.Command","webdriver.CommandName","webdriver.Key","webdriver.Locator","webdriver.Session","webdriver.logging","webdriver.promise"]);
    38goog.addDependency("../webdriver/session.js", ["webdriver.Session"], ["webdriver.Capabilities"]);
    39goog.addDependency("../webdriver/builder.js", ["webdriver.Builder"], ["goog.userAgent","webdriver.AbstractBuilder","webdriver.FirefoxDomExecutor","webdriver.WebDriver","webdriver.http.CorsClient","webdriver.http.Executor","webdriver.http.XhrClient","webdriver.process"]);
    40goog.addDependency("../webdriver/abstractbuilder.js", ["webdriver.AbstractBuilder"], ["webdriver.Capabilities","webdriver.process"]);
    41goog.addDependency("../webdriver/firefoxdomexecutor.js", ["webdriver.FirefoxDomExecutor"], ["bot.response","goog.json","goog.userAgent.product","webdriver.Command","webdriver.CommandName"]);
    42goog.addDependency("../webdriver/http/corsclient.js", ["webdriver.http.CorsClient"], ["goog.json","webdriver.http.Response"]);
    43goog.addDependency("../webdriver/http/http.js", ["webdriver.http.Client","webdriver.http.Executor","webdriver.http.Request","webdriver.http.Response"], ["bot.ErrorCode","goog.array","goog.json","webdriver.CommandName","webdriver.promise.Deferred"]);
    44goog.addDependency("../webdriver/http/xhrclient.js", ["webdriver.http.XhrClient"], ["goog.json","goog.net.XmlHttp","webdriver.http.Response"]);
    45goog.addDependency("net/xmlhttp.js", ["goog.net.DefaultXmlHttpFactory","goog.net.XmlHttp","goog.net.XmlHttp.OptionType","goog.net.XmlHttp.ReadyState","goog.net.XmlHttpDefines"], ["goog.asserts","goog.net.WrapperXmlHttpFactory","goog.net.XmlHttpFactory"]);
    46goog.addDependency("net/wrapperxmlhttpfactory.js", ["goog.net.WrapperXmlHttpFactory"], ["goog.net.XhrLike","goog.net.XmlHttpFactory"]);
    47goog.addDependency("net/xhrlike.js", ["goog.net.XhrLike"], []);
    48goog.addDependency("net/xmlhttpfactory.js", ["goog.net.XmlHttpFactory"], ["goog.net.XhrLike"]);
    49goog.addDependency("../webdriver/testing/asserts.js", ["webdriver.testing.Assertion","webdriver.testing.ContainsMatcher","webdriver.testing.NegatedAssertion","webdriver.testing.assert","webdriver.testing.asserts"], ["goog.array","goog.labs.testing.CloseToMatcher","goog.labs.testing.EndsWithMatcher","goog.labs.testing.EqualToMatcher","goog.labs.testing.EqualsMatcher","goog.labs.testing.GreaterThanEqualToMatcher","goog.labs.testing.GreaterThanMatcher","goog.labs.testing.LessThanEqualToMatcher","goog.labs.testing.LessThanMatcher","goog.labs.testing.InstanceOfMatcher","goog.labs.testing.IsNotMatcher","goog.labs.testing.IsNullMatcher","goog.labs.testing.IsNullOrUndefinedMatcher","goog.labs.testing.IsUndefinedMatcher","goog.labs.testing.Matcher","goog.labs.testing.ObjectEqualsMatcher","goog.labs.testing.RegexMatcher","goog.labs.testing.StartsWithMatcher","goog.labs.testing.assertThat","goog.string","webdriver.promise"]);
    50goog.addDependency("labs/testing/numbermatcher.js", ["goog.labs.testing.CloseToMatcher","goog.labs.testing.EqualToMatcher","goog.labs.testing.GreaterThanEqualToMatcher","goog.labs.testing.GreaterThanMatcher","goog.labs.testing.LessThanEqualToMatcher","goog.labs.testing.LessThanMatcher"], ["goog.asserts","goog.labs.testing.Matcher"]);
    51goog.addDependency("labs/testing/matcher.js", ["goog.labs.testing.Matcher"], []);
    52goog.addDependency("labs/testing/stringmatcher.js", ["goog.labs.testing.ContainsStringMatcher","goog.labs.testing.EndsWithMatcher","goog.labs.testing.EqualToIgnoringCaseMatcher","goog.labs.testing.EqualToIgnoringWhitespaceMatcher","goog.labs.testing.EqualsMatcher","goog.labs.testing.RegexMatcher","goog.labs.testing.StartsWithMatcher","goog.labs.testing.StringContainsInOrderMatcher"], ["goog.asserts","goog.labs.testing.Matcher","goog.string"]);
    53goog.addDependency("labs/testing/objectmatcher.js", ["goog.labs.testing.HasPropertyMatcher","goog.labs.testing.InstanceOfMatcher","goog.labs.testing.IsNullMatcher","goog.labs.testing.IsNullOrUndefinedMatcher","goog.labs.testing.IsUndefinedMatcher","goog.labs.testing.ObjectEqualsMatcher"], ["goog.labs.testing.Matcher","goog.string"]);
    54goog.addDependency("labs/testing/logicmatcher.js", ["goog.labs.testing.AllOfMatcher","goog.labs.testing.AnyOfMatcher","goog.labs.testing.IsNotMatcher"], ["goog.array","goog.labs.testing.Matcher"]);
    55goog.addDependency("labs/testing/assertthat.js", ["goog.labs.testing.MatcherError","goog.labs.testing.assertThat"], ["goog.asserts","goog.debug.Error","goog.labs.testing.Matcher"]);
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/dom/nodetype.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/dom/nodetype.js.src.html new file mode 100644 index 0000000..732b4ef --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/dom/nodetype.js.src.html @@ -0,0 +1 @@ +nodetype.js

    lib/goog/dom/nodetype.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Definition of goog.dom.NodeType.
    17 */
    18
    19goog.provide('goog.dom.NodeType');
    20
    21
    22/**
    23 * Constants for the nodeType attribute in the Node interface.
    24 *
    25 * These constants match those specified in the Node interface. These are
    26 * usually present on the Node object in recent browsers, but not in older
    27 * browsers (specifically, early IEs) and thus are given here.
    28 *
    29 * In some browsers (early IEs), these are not defined on the Node object,
    30 * so they are provided here.
    31 *
    32 * See http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247
    33 * @enum {number}
    34 */
    35goog.dom.NodeType = {
    36 ELEMENT: 1,
    37 ATTRIBUTE: 2,
    38 TEXT: 3,
    39 CDATA_SECTION: 4,
    40 ENTITY_REFERENCE: 5,
    41 ENTITY: 6,
    42 PROCESSING_INSTRUCTION: 7,
    43 COMMENT: 8,
    44 DOCUMENT: 9,
    45 DOCUMENT_TYPE: 10,
    46 DOCUMENT_FRAGMENT: 11,
    47 NOTATION: 12
    48};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/functions/functions.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/functions/functions.js.src.html new file mode 100644 index 0000000..eafedd6 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/functions/functions.js.src.html @@ -0,0 +1 @@ +functions.js

    lib/goog/functions/functions.js

    1// Copyright 2008 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Utilities for creating functions. Loosely inspired by the
    17 * java classes: http://goo.gl/GM0Hmu and http://goo.gl/6k7nI8.
    18 *
    19 * @author nicksantos@google.com (Nick Santos)
    20 */
    21
    22
    23goog.provide('goog.functions');
    24
    25
    26/**
    27 * Creates a function that always returns the same value.
    28 * @param {T} retValue The value to return.
    29 * @return {function():T} The new function.
    30 * @template T
    31 */
    32goog.functions.constant = function(retValue) {
    33 return function() {
    34 return retValue;
    35 };
    36};
    37
    38
    39/**
    40 * Always returns false.
    41 * @type {function(...): boolean}
    42 */
    43goog.functions.FALSE = goog.functions.constant(false);
    44
    45
    46/**
    47 * Always returns true.
    48 * @type {function(...): boolean}
    49 */
    50goog.functions.TRUE = goog.functions.constant(true);
    51
    52
    53/**
    54 * Always returns NULL.
    55 * @type {function(...): null}
    56 */
    57goog.functions.NULL = goog.functions.constant(null);
    58
    59
    60/**
    61 * A simple function that returns the first argument of whatever is passed
    62 * into it.
    63 * @param {T=} opt_returnValue The single value that will be returned.
    64 * @param {...*} var_args Optional trailing arguments. These are ignored.
    65 * @return {T} The first argument passed in, or undefined if nothing was passed.
    66 * @template T
    67 */
    68goog.functions.identity = function(opt_returnValue, var_args) {
    69 return opt_returnValue;
    70};
    71
    72
    73/**
    74 * Creates a function that always throws an error with the given message.
    75 * @param {string} message The error message.
    76 * @return {!Function} The error-throwing function.
    77 */
    78goog.functions.error = function(message) {
    79 return function() {
    80 throw Error(message);
    81 };
    82};
    83
    84
    85/**
    86 * Creates a function that throws the given object.
    87 * @param {*} err An object to be thrown.
    88 * @return {!Function} The error-throwing function.
    89 */
    90goog.functions.fail = function(err) {
    91 return function() {
    92 throw err;
    93 }
    94};
    95
    96
    97/**
    98 * Given a function, create a function that keeps opt_numArgs arguments and
    99 * silently discards all additional arguments.
    100 * @param {Function} f The original function.
    101 * @param {number=} opt_numArgs The number of arguments to keep. Defaults to 0.
    102 * @return {!Function} A version of f that only keeps the first opt_numArgs
    103 * arguments.
    104 */
    105goog.functions.lock = function(f, opt_numArgs) {
    106 opt_numArgs = opt_numArgs || 0;
    107 return function() {
    108 return f.apply(this, Array.prototype.slice.call(arguments, 0, opt_numArgs));
    109 };
    110};
    111
    112
    113/**
    114 * Creates a function that returns its nth argument.
    115 * @param {number} n The position of the return argument.
    116 * @return {!Function} A new function.
    117 */
    118goog.functions.nth = function(n) {
    119 return function() {
    120 return arguments[n];
    121 };
    122};
    123
    124
    125/**
    126 * Given a function, create a new function that swallows its return value
    127 * and replaces it with a new one.
    128 * @param {Function} f A function.
    129 * @param {T} retValue A new return value.
    130 * @return {function(...[?]):T} A new function.
    131 * @template T
    132 */
    133goog.functions.withReturnValue = function(f, retValue) {
    134 return goog.functions.sequence(f, goog.functions.constant(retValue));
    135};
    136
    137
    138/**
    139 * Creates the composition of the functions passed in.
    140 * For example, (goog.functions.compose(f, g))(a) is equivalent to f(g(a)).
    141 * @param {function(...[?]):T} fn The final function.
    142 * @param {...Function} var_args A list of functions.
    143 * @return {function(...[?]):T} The composition of all inputs.
    144 * @template T
    145 */
    146goog.functions.compose = function(fn, var_args) {
    147 var functions = arguments;
    148 var length = functions.length;
    149 return function() {
    150 var result;
    151 if (length) {
    152 result = functions[length - 1].apply(this, arguments);
    153 }
    154
    155 for (var i = length - 2; i >= 0; i--) {
    156 result = functions[i].call(this, result);
    157 }
    158 return result;
    159 };
    160};
    161
    162
    163/**
    164 * Creates a function that calls the functions passed in in sequence, and
    165 * returns the value of the last function. For example,
    166 * (goog.functions.sequence(f, g))(x) is equivalent to f(x),g(x).
    167 * @param {...Function} var_args A list of functions.
    168 * @return {!Function} A function that calls all inputs in sequence.
    169 */
    170goog.functions.sequence = function(var_args) {
    171 var functions = arguments;
    172 var length = functions.length;
    173 return function() {
    174 var result;
    175 for (var i = 0; i < length; i++) {
    176 result = functions[i].apply(this, arguments);
    177 }
    178 return result;
    179 };
    180};
    181
    182
    183/**
    184 * Creates a function that returns true if each of its components evaluates
    185 * to true. The components are evaluated in order, and the evaluation will be
    186 * short-circuited as soon as a function returns false.
    187 * For example, (goog.functions.and(f, g))(x) is equivalent to f(x) && g(x).
    188 * @param {...Function} var_args A list of functions.
    189 * @return {function(...[?]):boolean} A function that ANDs its component
    190 * functions.
    191 */
    192goog.functions.and = function(var_args) {
    193 var functions = arguments;
    194 var length = functions.length;
    195 return function() {
    196 for (var i = 0; i < length; i++) {
    197 if (!functions[i].apply(this, arguments)) {
    198 return false;
    199 }
    200 }
    201 return true;
    202 };
    203};
    204
    205
    206/**
    207 * Creates a function that returns true if any of its components evaluates
    208 * to true. The components are evaluated in order, and the evaluation will be
    209 * short-circuited as soon as a function returns true.
    210 * For example, (goog.functions.or(f, g))(x) is equivalent to f(x) || g(x).
    211 * @param {...Function} var_args A list of functions.
    212 * @return {function(...[?]):boolean} A function that ORs its component
    213 * functions.
    214 */
    215goog.functions.or = function(var_args) {
    216 var functions = arguments;
    217 var length = functions.length;
    218 return function() {
    219 for (var i = 0; i < length; i++) {
    220 if (functions[i].apply(this, arguments)) {
    221 return true;
    222 }
    223 }
    224 return false;
    225 };
    226};
    227
    228
    229/**
    230 * Creates a function that returns the Boolean opposite of a provided function.
    231 * For example, (goog.functions.not(f))(x) is equivalent to !f(x).
    232 * @param {!Function} f The original function.
    233 * @return {function(...[?]):boolean} A function that delegates to f and returns
    234 * opposite.
    235 */
    236goog.functions.not = function(f) {
    237 return function() {
    238 return !f.apply(this, arguments);
    239 };
    240};
    241
    242
    243/**
    244 * Generic factory function to construct an object given the constructor
    245 * and the arguments. Intended to be bound to create object factories.
    246 *
    247 * Callers should cast the result to the appropriate type for proper type
    248 * checking by the compiler.
    249 * @param {!Function} constructor The constructor for the Object.
    250 * @param {...*} var_args The arguments to be passed to the constructor.
    251 * @return {!Object} A new instance of the class given in {@code constructor}.
    252 */
    253goog.functions.create = function(constructor, var_args) {
    254 /**
    255 * @constructor
    256 * @final
    257 */
    258 var temp = function() {};
    259 temp.prototype = constructor.prototype;
    260
    261 // obj will have constructor's prototype in its chain and
    262 // 'obj instanceof constructor' will be true.
    263 var obj = new temp();
    264
    265 // obj is initialized by constructor.
    266 // arguments is only array-like so lacks shift(), but can be used with
    267 // the Array prototype function.
    268 constructor.apply(obj, Array.prototype.slice.call(arguments, 1));
    269 return obj;
    270};
    271
    272
    273/**
    274 * @define {boolean} Whether the return value cache should be used.
    275 * This should only be used to disable caches when testing.
    276 */
    277goog.define('goog.functions.CACHE_RETURN_VALUE', true);
    278
    279
    280/**
    281 * Gives a wrapper function that caches the return value of a parameterless
    282 * function when first called.
    283 *
    284 * When called for the first time, the given function is called and its
    285 * return value is cached (thus this is only appropriate for idempotent
    286 * functions). Subsequent calls will return the cached return value. This
    287 * allows the evaluation of expensive functions to be delayed until first used.
    288 *
    289 * To cache the return values of functions with parameters, see goog.memoize.
    290 *
    291 * @param {!function():T} fn A function to lazily evaluate.
    292 * @return {!function():T} A wrapped version the function.
    293 * @template T
    294 */
    295goog.functions.cacheReturnValue = function(fn) {
    296 var called = false;
    297 var value;
    298
    299 return function() {
    300 if (!goog.functions.CACHE_RETURN_VALUE) {
    301 return fn();
    302 }
    303
    304 if (!called) {
    305 value = fn();
    306 called = true;
    307 }
    308
    309 return value;
    310 }
    311};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/iter/iter.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/iter/iter.js.src.html new file mode 100644 index 0000000..73d326a --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/iter/iter.js.src.html @@ -0,0 +1 @@ +iter.js

    lib/goog/iter/iter.js

    1// Copyright 2007 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Python style iteration utilities.
    17 * @author arv@google.com (Erik Arvidsson)
    18 */
    19
    20
    21goog.provide('goog.iter');
    22goog.provide('goog.iter.Iterable');
    23goog.provide('goog.iter.Iterator');
    24goog.provide('goog.iter.StopIteration');
    25
    26goog.require('goog.array');
    27goog.require('goog.asserts');
    28goog.require('goog.functions');
    29goog.require('goog.math');
    30
    31
    32/**
    33 * @typedef {goog.iter.Iterator|{length:number}|{__iterator__}}
    34 */
    35goog.iter.Iterable;
    36
    37
    38// For script engines that already support iterators.
    39if ('StopIteration' in goog.global) {
    40 /**
    41 * Singleton Error object that is used to terminate iterations.
    42 * @type {Error}
    43 */
    44 goog.iter.StopIteration = goog.global['StopIteration'];
    45} else {
    46 /**
    47 * Singleton Error object that is used to terminate iterations.
    48 * @type {Error}
    49 * @suppress {duplicate}
    50 */
    51 goog.iter.StopIteration = Error('StopIteration');
    52}
    53
    54
    55
    56/**
    57 * Class/interface for iterators. An iterator needs to implement a {@code next}
    58 * method and it needs to throw a {@code goog.iter.StopIteration} when the
    59 * iteration passes beyond the end. Iterators have no {@code hasNext} method.
    60 * It is recommended to always use the helper functions to iterate over the
    61 * iterator or in case you are only targeting JavaScript 1.7 for in loops.
    62 * @constructor
    63 * @template VALUE
    64 */
    65goog.iter.Iterator = function() {};
    66
    67
    68/**
    69 * Returns the next value of the iteration. This will throw the object
    70 * {@see goog.iter#StopIteration} when the iteration passes the end.
    71 * @return {VALUE} Any object or value.
    72 */
    73goog.iter.Iterator.prototype.next = function() {
    74 throw goog.iter.StopIteration;
    75};
    76
    77
    78/**
    79 * Returns the {@code Iterator} object itself. This is used to implement
    80 * the iterator protocol in JavaScript 1.7
    81 * @param {boolean=} opt_keys Whether to return the keys or values. Default is
    82 * to only return the values. This is being used by the for-in loop (true)
    83 * and the for-each-in loop (false). Even though the param gives a hint
    84 * about what the iterator will return there is no guarantee that it will
    85 * return the keys when true is passed.
    86 * @return {!goog.iter.Iterator.<VALUE>} The object itself.
    87 */
    88goog.iter.Iterator.prototype.__iterator__ = function(opt_keys) {
    89 return this;
    90};
    91
    92
    93/**
    94 * Returns an iterator that knows how to iterate over the values in the object.
    95 * @param {goog.iter.Iterator.<VALUE>|goog.iter.Iterable} iterable If the
    96 * object is an iterator it will be returned as is. If the object has an
    97 * {@code __iterator__} method that will be called to get the value
    98 * iterator. If the object is an array-like object we create an iterator
    99 * for that.
    100 * @return {!goog.iter.Iterator.<VALUE>} An iterator that knows how to iterate
    101 * over the values in {@code iterable}.
    102 * @template VALUE
    103 */
    104goog.iter.toIterator = function(iterable) {
    105 if (iterable instanceof goog.iter.Iterator) {
    106 return iterable;
    107 }
    108 if (typeof iterable.__iterator__ == 'function') {
    109 return iterable.__iterator__(false);
    110 }
    111 if (goog.isArrayLike(iterable)) {
    112 var i = 0;
    113 var newIter = new goog.iter.Iterator;
    114 newIter.next = function() {
    115 while (true) {
    116 if (i >= iterable.length) {
    117 throw goog.iter.StopIteration;
    118 }
    119 // Don't include deleted elements.
    120 if (!(i in iterable)) {
    121 i++;
    122 continue;
    123 }
    124 return iterable[i++];
    125 }
    126 };
    127 return newIter;
    128 }
    129
    130
    131 // TODO(arv): Should we fall back on goog.structs.getValues()?
    132 throw Error('Not implemented');
    133};
    134
    135
    136/**
    137 * Calls a function for each element in the iterator with the element of the
    138 * iterator passed as argument.
    139 *
    140 * @param {goog.iter.Iterator.<VALUE>|goog.iter.Iterable} iterable The iterator
    141 * to iterate over. If the iterable is an object {@code toIterator} will be
    142 * called on it.
    143 * @param {function(this:THIS,VALUE,undefined,goog.iter.Iterator.<VALUE>)|
    144 * function(this:THIS,number,undefined,goog.iter.Iterator.<VALUE>)} f
    145 * The function to call for every element. This function takes 3 arguments
    146 * (the element, undefined, and the iterator) and the return value is
    147 * irrelevant. The reason for passing undefined as the second argument is
    148 * so that the same function can be used in {@see goog.array#forEach} as
    149 * well as others.
    150 * @param {THIS=} opt_obj The object to be used as the value of 'this' within
    151 * {@code f}.
    152 * @template THIS, VALUE
    153 */
    154goog.iter.forEach = function(iterable, f, opt_obj) {
    155 if (goog.isArrayLike(iterable)) {
    156 /** @preserveTry */
    157 try {
    158 // NOTES: this passes the index number to the second parameter
    159 // of the callback contrary to the documentation above.
    160 goog.array.forEach(/** @type {goog.array.ArrayLike} */(iterable), f,
    161 opt_obj);
    162 } catch (ex) {
    163 if (ex !== goog.iter.StopIteration) {
    164 throw ex;
    165 }
    166 }
    167 } else {
    168 iterable = goog.iter.toIterator(iterable);
    169 /** @preserveTry */
    170 try {
    171 while (true) {
    172 f.call(opt_obj, iterable.next(), undefined, iterable);
    173 }
    174 } catch (ex) {
    175 if (ex !== goog.iter.StopIteration) {
    176 throw ex;
    177 }
    178 }
    179 }
    180};
    181
    182
    183/**
    184 * Calls a function for every element in the iterator, and if the function
    185 * returns true adds the element to a new iterator.
    186 *
    187 * @param {goog.iter.Iterator.<VALUE>|goog.iter.Iterable} iterable The iterator
    188 * to iterate over.
    189 * @param {
    190 * function(this:THIS,VALUE,undefined,goog.iter.Iterator.<VALUE>):boolean} f
    191 * The function to call for every element. This function takes 3 arguments
    192 * (the element, undefined, and the iterator) and should return a boolean.
    193 * If the return value is true the element will be included in the returned
    194 * iterator. If it is false the element is not included.
    195 * @param {THIS=} opt_obj The object to be used as the value of 'this' within
    196 * {@code f}.
    197 * @return {!goog.iter.Iterator.<VALUE>} A new iterator in which only elements
    198 * that passed the test are present.
    199 * @template THIS, VALUE
    200 */
    201goog.iter.filter = function(iterable, f, opt_obj) {
    202 var iterator = goog.iter.toIterator(iterable);
    203 var newIter = new goog.iter.Iterator;
    204 newIter.next = function() {
    205 while (true) {
    206 var val = iterator.next();
    207 if (f.call(opt_obj, val, undefined, iterator)) {
    208 return val;
    209 }
    210 }
    211 };
    212 return newIter;
    213};
    214
    215
    216/**
    217 * Calls a function for every element in the iterator, and if the function
    218 * returns false adds the element to a new iterator.
    219 *
    220 * @param {goog.iter.Iterator.<VALUE>|goog.iter.Iterable} iterable The iterator
    221 * to iterate over.
    222 * @param {
    223 * function(this:THIS,VALUE,undefined,goog.iter.Iterator.<VALUE>):boolean} f
    224 * The function to call for every element. This function takes 3 arguments
    225 * (the element, undefined, and the iterator) and should return a boolean.
    226 * If the return value is false the element will be included in the returned
    227 * iterator. If it is true the element is not included.
    228 * @param {THIS=} opt_obj The object to be used as the value of 'this' within
    229 * {@code f}.
    230 * @return {!goog.iter.Iterator.<VALUE>} A new iterator in which only elements
    231 * that did not pass the test are present.
    232 * @template THIS, VALUE
    233 */
    234goog.iter.filterFalse = function(iterable, f, opt_obj) {
    235 return goog.iter.filter(iterable, goog.functions.not(f), opt_obj);
    236};
    237
    238
    239/**
    240 * Creates a new iterator that returns the values in a range. This function
    241 * can take 1, 2 or 3 arguments:
    242 * <pre>
    243 * range(5) same as range(0, 5, 1)
    244 * range(2, 5) same as range(2, 5, 1)
    245 * </pre>
    246 *
    247 * @param {number} startOrStop The stop value if only one argument is provided.
    248 * The start value if 2 or more arguments are provided. If only one
    249 * argument is used the start value is 0.
    250 * @param {number=} opt_stop The stop value. If left out then the first
    251 * argument is used as the stop value.
    252 * @param {number=} opt_step The number to increment with between each call to
    253 * next. This can be negative.
    254 * @return {!goog.iter.Iterator.<number>} A new iterator that returns the values
    255 * in the range.
    256 */
    257goog.iter.range = function(startOrStop, opt_stop, opt_step) {
    258 var start = 0;
    259 var stop = startOrStop;
    260 var step = opt_step || 1;
    261 if (arguments.length > 1) {
    262 start = startOrStop;
    263 stop = opt_stop;
    264 }
    265 if (step == 0) {
    266 throw Error('Range step argument must not be zero');
    267 }
    268
    269 var newIter = new goog.iter.Iterator;
    270 newIter.next = function() {
    271 if (step > 0 && start >= stop || step < 0 && start <= stop) {
    272 throw goog.iter.StopIteration;
    273 }
    274 var rv = start;
    275 start += step;
    276 return rv;
    277 };
    278 return newIter;
    279};
    280
    281
    282/**
    283 * Joins the values in a iterator with a delimiter.
    284 * @param {goog.iter.Iterator.<VALUE>|goog.iter.Iterable} iterable The iterator
    285 * to get the values from.
    286 * @param {string} deliminator The text to put between the values.
    287 * @return {string} The joined value string.
    288 * @template VALUE
    289 */
    290goog.iter.join = function(iterable, deliminator) {
    291 return goog.iter.toArray(iterable).join(deliminator);
    292};
    293
    294
    295/**
    296 * For every element in the iterator call a function and return a new iterator
    297 * with that value.
    298 *
    299 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    300 * iterator to iterate over.
    301 * @param {
    302 * function(this:THIS,VALUE,undefined,!goog.iter.Iterator.<VALUE>):RESULT} f
    303 * The function to call for every element. This function takes 3 arguments
    304 * (the element, undefined, and the iterator) and should return a new value.
    305 * @param {THIS=} opt_obj The object to be used as the value of 'this' within
    306 * {@code f}.
    307 * @return {!goog.iter.Iterator.<RESULT>} A new iterator that returns the
    308 * results of applying the function to each element in the original
    309 * iterator.
    310 * @template THIS, VALUE, RESULT
    311 */
    312goog.iter.map = function(iterable, f, opt_obj) {
    313 var iterator = goog.iter.toIterator(iterable);
    314 var newIter = new goog.iter.Iterator;
    315 newIter.next = function() {
    316 var val = iterator.next();
    317 return f.call(opt_obj, val, undefined, iterator);
    318 };
    319 return newIter;
    320};
    321
    322
    323/**
    324 * Passes every element of an iterator into a function and accumulates the
    325 * result.
    326 *
    327 * @param {goog.iter.Iterator.<VALUE>|goog.iter.Iterable} iterable The iterator
    328 * to iterate over.
    329 * @param {function(this:THIS,VALUE,VALUE):VALUE} f The function to call for
    330 * every element. This function takes 2 arguments (the function's previous
    331 * result or the initial value, and the value of the current element).
    332 * function(previousValue, currentElement) : newValue.
    333 * @param {VALUE} val The initial value to pass into the function on the first
    334 * call.
    335 * @param {THIS=} opt_obj The object to be used as the value of 'this' within
    336 * f.
    337 * @return {VALUE} Result of evaluating f repeatedly across the values of
    338 * the iterator.
    339 * @template THIS, VALUE
    340 */
    341goog.iter.reduce = function(iterable, f, val, opt_obj) {
    342 var rval = val;
    343 goog.iter.forEach(iterable, function(val) {
    344 rval = f.call(opt_obj, rval, val);
    345 });
    346 return rval;
    347};
    348
    349
    350/**
    351 * Goes through the values in the iterator. Calls f for each of these, and if
    352 * any of them returns true, this returns true (without checking the rest). If
    353 * all return false this will return false.
    354 *
    355 * @param {goog.iter.Iterator.<VALUE>|goog.iter.Iterable} iterable The iterator
    356 * object.
    357 * @param {
    358 * function(this:THIS,VALUE,undefined,goog.iter.Iterator.<VALUE>):boolean} f
    359 * The function to call for every value. This function takes 3 arguments
    360 * (the value, undefined, and the iterator) and should return a boolean.
    361 * @param {THIS=} opt_obj The object to be used as the value of 'this' within
    362 * {@code f}.
    363 * @return {boolean} true if any value passes the test.
    364 * @template THIS, VALUE
    365 */
    366goog.iter.some = function(iterable, f, opt_obj) {
    367 iterable = goog.iter.toIterator(iterable);
    368 /** @preserveTry */
    369 try {
    370 while (true) {
    371 if (f.call(opt_obj, iterable.next(), undefined, iterable)) {
    372 return true;
    373 }
    374 }
    375 } catch (ex) {
    376 if (ex !== goog.iter.StopIteration) {
    377 throw ex;
    378 }
    379 }
    380 return false;
    381};
    382
    383
    384/**
    385 * Goes through the values in the iterator. Calls f for each of these and if any
    386 * of them returns false this returns false (without checking the rest). If all
    387 * return true this will return true.
    388 *
    389 * @param {goog.iter.Iterator.<VALUE>|goog.iter.Iterable} iterable The iterator
    390 * object.
    391 * @param {
    392 * function(this:THIS,VALUE,undefined,goog.iter.Iterator.<VALUE>):boolean} f
    393 * The function to call for every value. This function takes 3 arguments
    394 * (the value, undefined, and the iterator) and should return a boolean.
    395 * @param {THIS=} opt_obj The object to be used as the value of 'this' within
    396 * {@code f}.
    397 * @return {boolean} true if every value passes the test.
    398 * @template THIS, VALUE
    399 */
    400goog.iter.every = function(iterable, f, opt_obj) {
    401 iterable = goog.iter.toIterator(iterable);
    402 /** @preserveTry */
    403 try {
    404 while (true) {
    405 if (!f.call(opt_obj, iterable.next(), undefined, iterable)) {
    406 return false;
    407 }
    408 }
    409 } catch (ex) {
    410 if (ex !== goog.iter.StopIteration) {
    411 throw ex;
    412 }
    413 }
    414 return true;
    415};
    416
    417
    418/**
    419 * Takes zero or more iterables and returns one iterator that will iterate over
    420 * them in the order chained.
    421 * @param {...!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} var_args Any
    422 * number of iterable objects.
    423 * @return {!goog.iter.Iterator.<VALUE>} Returns a new iterator that will
    424 * iterate over all the given iterables' contents.
    425 * @template VALUE
    426 */
    427goog.iter.chain = function(var_args) {
    428 var iterator = goog.iter.toIterator(arguments);
    429 var iter = new goog.iter.Iterator();
    430 var current = null;
    431
    432 iter.next = function() {
    433 while (true) {
    434 if (current == null) {
    435 var it = iterator.next();
    436 current = goog.iter.toIterator(it);
    437 }
    438 try {
    439 return current.next();
    440 } catch (ex) {
    441 if (ex !== goog.iter.StopIteration) {
    442 throw ex;
    443 }
    444 current = null;
    445 }
    446 }
    447 };
    448
    449 return iter;
    450};
    451
    452
    453/**
    454 * Takes a single iterable containing zero or more iterables and returns one
    455 * iterator that will iterate over each one in the order given.
    456 * @see http://docs.python.org/2/library/itertools.html#itertools.chain.from_iterable
    457 * @param {goog.iter.Iterable} iterable The iterable of iterables to chain.
    458 * @return {!goog.iter.Iterator.<VALUE>} Returns a new iterator that will
    459 * iterate over all the contents of the iterables contained within
    460 * {@code iterable}.
    461 * @template VALUE
    462 */
    463goog.iter.chainFromIterable = function(iterable) {
    464 return goog.iter.chain.apply(undefined, iterable);
    465};
    466
    467
    468/**
    469 * Builds a new iterator that iterates over the original, but skips elements as
    470 * long as a supplied function returns true.
    471 * @param {goog.iter.Iterator.<VALUE>|goog.iter.Iterable} iterable The iterator
    472 * object.
    473 * @param {
    474 * function(this:THIS,VALUE,undefined,goog.iter.Iterator.<VALUE>):boolean} f
    475 * The function to call for every value. This function takes 3 arguments
    476 * (the value, undefined, and the iterator) and should return a boolean.
    477 * @param {THIS=} opt_obj The object to be used as the value of 'this' within
    478 * {@code f}.
    479 * @return {!goog.iter.Iterator.<VALUE>} A new iterator that drops elements from
    480 * the original iterator as long as {@code f} is true.
    481 * @template THIS, VALUE
    482 */
    483goog.iter.dropWhile = function(iterable, f, opt_obj) {
    484 var iterator = goog.iter.toIterator(iterable);
    485 var newIter = new goog.iter.Iterator;
    486 var dropping = true;
    487 newIter.next = function() {
    488 while (true) {
    489 var val = iterator.next();
    490 if (dropping && f.call(opt_obj, val, undefined, iterator)) {
    491 continue;
    492 } else {
    493 dropping = false;
    494 }
    495 return val;
    496 }
    497 };
    498 return newIter;
    499};
    500
    501
    502/**
    503 * Builds a new iterator that iterates over the original, but only as long as a
    504 * supplied function returns true.
    505 * @param {goog.iter.Iterator.<VALUE>|goog.iter.Iterable} iterable The iterator
    506 * object.
    507 * @param {
    508 * function(this:THIS,VALUE,undefined,goog.iter.Iterator.<VALUE>):boolean} f
    509 * The function to call for every value. This function takes 3 arguments
    510 * (the value, undefined, and the iterator) and should return a boolean.
    511 * @param {THIS=} opt_obj This is used as the 'this' object in f when called.
    512 * @return {!goog.iter.Iterator.<VALUE>} A new iterator that keeps elements in
    513 * the original iterator as long as the function is true.
    514 * @template THIS, VALUE
    515 */
    516goog.iter.takeWhile = function(iterable, f, opt_obj) {
    517 var iterator = goog.iter.toIterator(iterable);
    518 var newIter = new goog.iter.Iterator;
    519 var taking = true;
    520 newIter.next = function() {
    521 while (true) {
    522 if (taking) {
    523 var val = iterator.next();
    524 if (f.call(opt_obj, val, undefined, iterator)) {
    525 return val;
    526 } else {
    527 taking = false;
    528 }
    529 } else {
    530 throw goog.iter.StopIteration;
    531 }
    532 }
    533 };
    534 return newIter;
    535};
    536
    537
    538/**
    539 * Converts the iterator to an array
    540 * @param {goog.iter.Iterator.<VALUE>|goog.iter.Iterable} iterable The iterator
    541 * to convert to an array.
    542 * @return {!Array.<VALUE>} An array of the elements the iterator iterates over.
    543 * @template VALUE
    544 */
    545goog.iter.toArray = function(iterable) {
    546 // Fast path for array-like.
    547 if (goog.isArrayLike(iterable)) {
    548 return goog.array.toArray(/** @type {!goog.array.ArrayLike} */(iterable));
    549 }
    550 iterable = goog.iter.toIterator(iterable);
    551 var array = [];
    552 goog.iter.forEach(iterable, function(val) {
    553 array.push(val);
    554 });
    555 return array;
    556};
    557
    558
    559/**
    560 * Iterates over two iterables and returns true if they contain the same
    561 * sequence of elements and have the same length.
    562 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable1 The first
    563 * iterable object.
    564 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable2 The second
    565 * iterable object.
    566 * @return {boolean} true if the iterables contain the same sequence of elements
    567 * and have the same length.
    568 * @template VALUE
    569 */
    570goog.iter.equals = function(iterable1, iterable2) {
    571 var fillValue = {};
    572 var pairs = goog.iter.zipLongest(fillValue, iterable1, iterable2);
    573 return goog.iter.every(pairs, function(pair) {
    574 return pair[0] == pair[1];
    575 });
    576};
    577
    578
    579/**
    580 * Advances the iterator to the next position, returning the given default value
    581 * instead of throwing an exception if the iterator has no more entries.
    582 * @param {goog.iter.Iterator.<VALUE>|goog.iter.Iterable} iterable The iterable
    583 * object.
    584 * @param {VALUE} defaultValue The value to return if the iterator is empty.
    585 * @return {VALUE} The next item in the iteration, or defaultValue if the
    586 * iterator was empty.
    587 * @template VALUE
    588 */
    589goog.iter.nextOrValue = function(iterable, defaultValue) {
    590 try {
    591 return goog.iter.toIterator(iterable).next();
    592 } catch (e) {
    593 if (e != goog.iter.StopIteration) {
    594 throw e;
    595 }
    596 return defaultValue;
    597 }
    598};
    599
    600
    601/**
    602 * Cartesian product of zero or more sets. Gives an iterator that gives every
    603 * combination of one element chosen from each set. For example,
    604 * ([1, 2], [3, 4]) gives ([1, 3], [1, 4], [2, 3], [2, 4]).
    605 * @see http://docs.python.org/library/itertools.html#itertools.product
    606 * @param {...!goog.array.ArrayLike.<VALUE>} var_args Zero or more sets, as
    607 * arrays.
    608 * @return {!goog.iter.Iterator.<!Array.<VALUE>>} An iterator that gives each
    609 * n-tuple (as an array).
    610 * @template VALUE
    611 */
    612goog.iter.product = function(var_args) {
    613 var someArrayEmpty = goog.array.some(arguments, function(arr) {
    614 return !arr.length;
    615 });
    616
    617 // An empty set in a cartesian product gives an empty set.
    618 if (someArrayEmpty || !arguments.length) {
    619 return new goog.iter.Iterator();
    620 }
    621
    622 var iter = new goog.iter.Iterator();
    623 var arrays = arguments;
    624
    625 // The first indices are [0, 0, ...]
    626 var indicies = goog.array.repeat(0, arrays.length);
    627
    628 iter.next = function() {
    629
    630 if (indicies) {
    631 var retVal = goog.array.map(indicies, function(valueIndex, arrayIndex) {
    632 return arrays[arrayIndex][valueIndex];
    633 });
    634
    635 // Generate the next-largest indices for the next call.
    636 // Increase the rightmost index. If it goes over, increase the next
    637 // rightmost (like carry-over addition).
    638 for (var i = indicies.length - 1; i >= 0; i--) {
    639 // Assertion prevents compiler warning below.
    640 goog.asserts.assert(indicies);
    641 if (indicies[i] < arrays[i].length - 1) {
    642 indicies[i]++;
    643 break;
    644 }
    645
    646 // We're at the last indices (the last element of every array), so
    647 // the iteration is over on the next call.
    648 if (i == 0) {
    649 indicies = null;
    650 break;
    651 }
    652 // Reset the index in this column and loop back to increment the
    653 // next one.
    654 indicies[i] = 0;
    655 }
    656 return retVal;
    657 }
    658
    659 throw goog.iter.StopIteration;
    660 };
    661
    662 return iter;
    663};
    664
    665
    666/**
    667 * Create an iterator to cycle over the iterable's elements indefinitely.
    668 * For example, ([1, 2, 3]) would return : 1, 2, 3, 1, 2, 3, ...
    669 * @see: http://docs.python.org/library/itertools.html#itertools.cycle.
    670 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    671 * iterable object.
    672 * @return {!goog.iter.Iterator.<VALUE>} An iterator that iterates indefinitely
    673 * over the values in {@code iterable}.
    674 * @template VALUE
    675 */
    676goog.iter.cycle = function(iterable) {
    677 var baseIterator = goog.iter.toIterator(iterable);
    678
    679 // We maintain a cache to store the iterable elements as we iterate
    680 // over them. The cache is used to return elements once we have
    681 // iterated over the iterable once.
    682 var cache = [];
    683 var cacheIndex = 0;
    684
    685 var iter = new goog.iter.Iterator();
    686
    687 // This flag is set after the iterable is iterated over once
    688 var useCache = false;
    689
    690 iter.next = function() {
    691 var returnElement = null;
    692
    693 // Pull elements off the original iterator if not using cache
    694 if (!useCache) {
    695 try {
    696 // Return the element from the iterable
    697 returnElement = baseIterator.next();
    698 cache.push(returnElement);
    699 return returnElement;
    700 } catch (e) {
    701 // If an exception other than StopIteration is thrown
    702 // or if there are no elements to iterate over (the iterable was empty)
    703 // throw an exception
    704 if (e != goog.iter.StopIteration || goog.array.isEmpty(cache)) {
    705 throw e;
    706 }
    707 // set useCache to true after we know that a 'StopIteration' exception
    708 // was thrown and the cache is not empty (to handle the 'empty iterable'
    709 // use case)
    710 useCache = true;
    711 }
    712 }
    713
    714 returnElement = cache[cacheIndex];
    715 cacheIndex = (cacheIndex + 1) % cache.length;
    716
    717 return returnElement;
    718 };
    719
    720 return iter;
    721};
    722
    723
    724/**
    725 * Creates an iterator that counts indefinitely from a starting value.
    726 * @see http://docs.python.org/2/library/itertools.html#itertools.count
    727 * @param {number=} opt_start The starting value. Default is 0.
    728 * @param {number=} opt_step The number to increment with between each call to
    729 * next. Negative and floating point numbers are allowed. Default is 1.
    730 * @return {!goog.iter.Iterator.<number>} A new iterator that returns the values
    731 * in the series.
    732 */
    733goog.iter.count = function(opt_start, opt_step) {
    734 var counter = opt_start || 0;
    735 var step = goog.isDef(opt_step) ? opt_step : 1;
    736 var iter = new goog.iter.Iterator();
    737
    738 iter.next = function() {
    739 var returnValue = counter;
    740 counter += step;
    741 return returnValue;
    742 };
    743
    744 return iter;
    745};
    746
    747
    748/**
    749 * Creates an iterator that returns the same object or value repeatedly.
    750 * @param {VALUE} value Any object or value to repeat.
    751 * @return {!goog.iter.Iterator.<VALUE>} A new iterator that returns the
    752 * repeated value.
    753 * @template VALUE
    754 */
    755goog.iter.repeat = function(value) {
    756 var iter = new goog.iter.Iterator();
    757
    758 iter.next = goog.functions.constant(value);
    759
    760 return iter;
    761};
    762
    763
    764/**
    765 * Creates an iterator that returns running totals from the numbers in
    766 * {@code iterable}. For example, the array {@code [1, 2, 3, 4, 5]} yields
    767 * {@code 1 -> 3 -> 6 -> 10 -> 15}.
    768 * @see http://docs.python.org/3.2/library/itertools.html#itertools.accumulate
    769 * @param {!goog.iter.Iterable.<number>} iterable The iterable of numbers to
    770 * accumulate.
    771 * @return {!goog.iter.Iterator.<number>} A new iterator that returns the
    772 * numbers in the series.
    773 */
    774goog.iter.accumulate = function(iterable) {
    775 var iterator = goog.iter.toIterator(iterable);
    776 var total = 0;
    777 var iter = new goog.iter.Iterator();
    778
    779 iter.next = function() {
    780 total += iterator.next();
    781 return total;
    782 };
    783
    784 return iter;
    785};
    786
    787
    788/**
    789 * Creates an iterator that returns arrays containing the ith elements from the
    790 * provided iterables. The returned arrays will be the same size as the number
    791 * of iterables given in {@code var_args}. Once the shortest iterable is
    792 * exhausted, subsequent calls to {@code next()} will throw
    793 * {@code goog.iter.StopIteration}.
    794 * @see http://docs.python.org/2/library/itertools.html#itertools.izip
    795 * @param {...!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} var_args Any
    796 * number of iterable objects.
    797 * @return {!goog.iter.Iterator.<!Array.<VALUE>>} A new iterator that returns
    798 * arrays of elements from the provided iterables.
    799 * @template VALUE
    800 */
    801goog.iter.zip = function(var_args) {
    802 var args = arguments;
    803 var iter = new goog.iter.Iterator();
    804
    805 if (args.length > 0) {
    806 var iterators = goog.array.map(args, goog.iter.toIterator);
    807 iter.next = function() {
    808 var arr = goog.array.map(iterators, function(it) {
    809 return it.next();
    810 });
    811 return arr;
    812 };
    813 }
    814
    815 return iter;
    816};
    817
    818
    819/**
    820 * Creates an iterator that returns arrays containing the ith elements from the
    821 * provided iterables. The returned arrays will be the same size as the number
    822 * of iterables given in {@code var_args}. Shorter iterables will be extended
    823 * with {@code fillValue}. Once the longest iterable is exhausted, subsequent
    824 * calls to {@code next()} will throw {@code goog.iter.StopIteration}.
    825 * @see http://docs.python.org/2/library/itertools.html#itertools.izip_longest
    826 * @param {VALUE} fillValue The object or value used to fill shorter iterables.
    827 * @param {...!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} var_args Any
    828 * number of iterable objects.
    829 * @return {!goog.iter.Iterator.<!Array.<VALUE>>} A new iterator that returns
    830 * arrays of elements from the provided iterables.
    831 * @template VALUE
    832 */
    833goog.iter.zipLongest = function(fillValue, var_args) {
    834 var args = goog.array.slice(arguments, 1);
    835 var iter = new goog.iter.Iterator();
    836
    837 if (args.length > 0) {
    838 var iterators = goog.array.map(args, goog.iter.toIterator);
    839
    840 iter.next = function() {
    841 var iteratorsHaveValues = false; // false when all iterators are empty.
    842 var arr = goog.array.map(iterators, function(it) {
    843 var returnValue;
    844 try {
    845 returnValue = it.next();
    846 // Iterator had a value, so we've not exhausted the iterators.
    847 // Set flag accordingly.
    848 iteratorsHaveValues = true;
    849 } catch (ex) {
    850 if (ex !== goog.iter.StopIteration) {
    851 throw ex;
    852 }
    853 returnValue = fillValue;
    854 }
    855 return returnValue;
    856 });
    857
    858 if (!iteratorsHaveValues) {
    859 throw goog.iter.StopIteration;
    860 }
    861 return arr;
    862 };
    863 }
    864
    865 return iter;
    866};
    867
    868
    869/**
    870 * Creates an iterator that filters {@code iterable} based on a series of
    871 * {@code selectors}. On each call to {@code next()}, one item is taken from
    872 * both the {@code iterable} and {@code selectors} iterators. If the item from
    873 * {@code selectors} evaluates to true, the item from {@code iterable} is given.
    874 * Otherwise, it is skipped. Once either {@code iterable} or {@code selectors}
    875 * is exhausted, subsequent calls to {@code next()} will throw
    876 * {@code goog.iter.StopIteration}.
    877 * @see http://docs.python.org/2/library/itertools.html#itertools.compress
    878 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    879 * iterable to filter.
    880 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} selectors An
    881 * iterable of items to be evaluated in a boolean context to determine if
    882 * the corresponding element in {@code iterable} should be included in the
    883 * result.
    884 * @return {!goog.iter.Iterator.<VALUE>} A new iterator that returns the
    885 * filtered values.
    886 * @template VALUE
    887 */
    888goog.iter.compress = function(iterable, selectors) {
    889 var selectorIterator = goog.iter.toIterator(selectors);
    890
    891 return goog.iter.filter(iterable, function() {
    892 return !!selectorIterator.next();
    893 });
    894};
    895
    896
    897
    898/**
    899 * Implements the {@code goog.iter.groupBy} iterator.
    900 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    901 * iterable to group.
    902 * @param {function(...[VALUE]): KEY=} opt_keyFunc Optional function for
    903 * determining the key value for each group in the {@code iterable}. Default
    904 * is the identity function.
    905 * @constructor
    906 * @extends {goog.iter.Iterator.<!Array>}
    907 * @template KEY, VALUE
    908 * @private
    909 */
    910goog.iter.GroupByIterator_ = function(iterable, opt_keyFunc) {
    911
    912 /**
    913 * The iterable to group, coerced to an iterator.
    914 * @type {!goog.iter.Iterator}
    915 */
    916 this.iterator = goog.iter.toIterator(iterable);
    917
    918 /**
    919 * A function for determining the key value for each element in the iterable.
    920 * If no function is provided, the identity function is used and returns the
    921 * element unchanged.
    922 * @type {function(...[VALUE]): KEY}
    923 */
    924 this.keyFunc = opt_keyFunc || goog.functions.identity;
    925
    926 /**
    927 * The target key for determining the start of a group.
    928 * @type {KEY}
    929 */
    930 this.targetKey;
    931
    932 /**
    933 * The current key visited during iteration.
    934 * @type {KEY}
    935 */
    936 this.currentKey;
    937
    938 /**
    939 * The current value being added to the group.
    940 * @type {VALUE}
    941 */
    942 this.currentValue;
    943};
    944goog.inherits(goog.iter.GroupByIterator_, goog.iter.Iterator);
    945
    946
    947/** @override */
    948goog.iter.GroupByIterator_.prototype.next = function() {
    949 while (this.currentKey == this.targetKey) {
    950 this.currentValue = this.iterator.next(); // Exits on StopIteration
    951 this.currentKey = this.keyFunc(this.currentValue);
    952 }
    953 this.targetKey = this.currentKey;
    954 return [this.currentKey, this.groupItems_(this.targetKey)];
    955};
    956
    957
    958/**
    959 * Performs the grouping of objects using the given key.
    960 * @param {KEY} targetKey The target key object for the group.
    961 * @return {!Array.<VALUE>} An array of grouped objects.
    962 * @private
    963 */
    964goog.iter.GroupByIterator_.prototype.groupItems_ = function(targetKey) {
    965 var arr = [];
    966 while (this.currentKey == targetKey) {
    967 arr.push(this.currentValue);
    968 try {
    969 this.currentValue = this.iterator.next();
    970 } catch (ex) {
    971 if (ex !== goog.iter.StopIteration) {
    972 throw ex;
    973 }
    974 break;
    975 }
    976 this.currentKey = this.keyFunc(this.currentValue);
    977 }
    978 return arr;
    979};
    980
    981
    982/**
    983 * Creates an iterator that returns arrays containing elements from the
    984 * {@code iterable} grouped by a key value. For iterables with repeated
    985 * elements (i.e. sorted according to a particular key function), this function
    986 * has a {@code uniq}-like effect. For example, grouping the array:
    987 * {@code [A, B, B, C, C, A]} produces
    988 * {@code [A, [A]], [B, [B, B]], [C, [C, C]], [A, [A]]}.
    989 * @see http://docs.python.org/2/library/itertools.html#itertools.groupby
    990 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    991 * iterable to group.
    992 * @param {function(...[VALUE]): KEY=} opt_keyFunc Optional function for
    993 * determining the key value for each group in the {@code iterable}. Default
    994 * is the identity function.
    995 * @return {!goog.iter.Iterator.<!Array>} A new iterator that returns arrays of
    996 * consecutive key and groups.
    997 * @template KEY, VALUE
    998 */
    999goog.iter.groupBy = function(iterable, opt_keyFunc) {
    1000 return new goog.iter.GroupByIterator_(iterable, opt_keyFunc);
    1001};
    1002
    1003
    1004/**
    1005 * Gives an iterator that gives the result of calling the given function
    1006 * <code>f</code> with the arguments taken from the next element from
    1007 * <code>iterable</code> (the elements are expected to also be iterables).
    1008 *
    1009 * Similar to {@see goog.iter#map} but allows the function to accept multiple
    1010 * arguments from the iterable.
    1011 *
    1012 * @param {!goog.iter.Iterable.<!goog.iter.Iterable>} iterable The iterable of
    1013 * iterables to iterate over.
    1014 * @param {function(this:THIS,...[*]):RESULT} f The function to call for every
    1015 * element. This function takes N+2 arguments, where N represents the
    1016 * number of items from the next element of the iterable. The two
    1017 * additional arguments passed to the function are undefined and the
    1018 * iterator itself. The function should return a new value.
    1019 * @param {THIS=} opt_obj The object to be used as the value of 'this' within
    1020 * {@code f}.
    1021 * @return {!goog.iter.Iterator.<RESULT>} A new iterator that returns the
    1022 * results of applying the function to each element in the original
    1023 * iterator.
    1024 * @template THIS, RESULT
    1025 */
    1026goog.iter.starMap = function(iterable, f, opt_obj) {
    1027 var iterator = goog.iter.toIterator(iterable);
    1028 var iter = new goog.iter.Iterator();
    1029
    1030 iter.next = function() {
    1031 var args = goog.iter.toArray(iterator.next());
    1032 return f.apply(opt_obj, goog.array.concat(args, undefined, iterator));
    1033 };
    1034
    1035 return iter;
    1036};
    1037
    1038
    1039/**
    1040 * Returns an array of iterators each of which can iterate over the values in
    1041 * {@code iterable} without advancing the others.
    1042 * @see http://docs.python.org/2/library/itertools.html#itertools.tee
    1043 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    1044 * iterable to tee.
    1045 * @param {number=} opt_num The number of iterators to create. Default is 2.
    1046 * @return {!Array.<goog.iter.Iterator.<VALUE>>} An array of iterators.
    1047 * @template VALUE
    1048 */
    1049goog.iter.tee = function(iterable, opt_num) {
    1050 var iterator = goog.iter.toIterator(iterable);
    1051 var num = goog.isNumber(opt_num) ? opt_num : 2;
    1052 var buffers = goog.array.map(goog.array.range(num), function() {
    1053 return [];
    1054 });
    1055
    1056 var addNextIteratorValueToBuffers = function() {
    1057 var val = iterator.next();
    1058 goog.array.forEach(buffers, function(buffer) {
    1059 buffer.push(val);
    1060 });
    1061 };
    1062
    1063 var createIterator = function(buffer) {
    1064 // Each tee'd iterator has an associated buffer (initially empty). When a
    1065 // tee'd iterator's buffer is empty, it calls
    1066 // addNextIteratorValueToBuffers(), adding the next value to all tee'd
    1067 // iterators' buffers, and then returns that value. This allows each
    1068 // iterator to be advanced independently.
    1069 var iter = new goog.iter.Iterator();
    1070
    1071 iter.next = function() {
    1072 if (goog.array.isEmpty(buffer)) {
    1073 addNextIteratorValueToBuffers();
    1074 }
    1075 goog.asserts.assert(!goog.array.isEmpty(buffer));
    1076 return buffer.shift();
    1077 };
    1078
    1079 return iter;
    1080 };
    1081
    1082 return goog.array.map(buffers, createIterator);
    1083};
    1084
    1085
    1086/**
    1087 * Creates an iterator that returns arrays containing a count and an element
    1088 * obtained from the given {@code iterable}.
    1089 * @see http://docs.python.org/2/library/functions.html#enumerate
    1090 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    1091 * iterable to enumerate.
    1092 * @param {number=} opt_start Optional starting value. Default is 0.
    1093 * @return {!goog.iter.Iterator.<!Array>} A new iterator containing count/item
    1094 * pairs.
    1095 * @template VALUE
    1096 */
    1097goog.iter.enumerate = function(iterable, opt_start) {
    1098 return goog.iter.zip(goog.iter.count(opt_start), iterable);
    1099};
    1100
    1101
    1102/**
    1103 * Creates an iterator that returns the first {@code limitSize} elements from an
    1104 * iterable. If this number is greater than the number of elements in the
    1105 * iterable, all the elements are returned.
    1106 * @see http://goo.gl/V0sihp Inspired by the limit iterator in Guava.
    1107 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    1108 * iterable to limit.
    1109 * @param {number} limitSize The maximum number of elements to return.
    1110 * @return {!goog.iter.Iterator.<VALUE>} A new iterator containing
    1111 * {@code limitSize} elements.
    1112 * @template VALUE
    1113 */
    1114goog.iter.limit = function(iterable, limitSize) {
    1115 goog.asserts.assert(goog.math.isInt(limitSize) && limitSize >= 0);
    1116
    1117 var iterator = goog.iter.toIterator(iterable);
    1118
    1119 var iter = new goog.iter.Iterator();
    1120 var remaining = limitSize;
    1121
    1122 iter.next = function() {
    1123 if (remaining-- > 0) {
    1124 return iterator.next();
    1125 }
    1126 throw goog.iter.StopIteration;
    1127 };
    1128
    1129 return iter;
    1130};
    1131
    1132
    1133/**
    1134 * Creates an iterator that is advanced {@code count} steps ahead. Consumed
    1135 * values are silently discarded. If {@code count} is greater than the number
    1136 * of elements in {@code iterable}, an empty iterator is returned. Subsequent
    1137 * calls to {@code next()} will throw {@code goog.iter.StopIteration}.
    1138 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    1139 * iterable to consume.
    1140 * @param {number} count The number of elements to consume from the iterator.
    1141 * @return {!goog.iter.Iterator.<VALUE>} An iterator advanced zero or more steps
    1142 * ahead.
    1143 * @template VALUE
    1144 */
    1145goog.iter.consume = function(iterable, count) {
    1146 goog.asserts.assert(goog.math.isInt(count) && count >= 0);
    1147
    1148 var iterator = goog.iter.toIterator(iterable);
    1149
    1150 while (count-- > 0) {
    1151 goog.iter.nextOrValue(iterator, null);
    1152 }
    1153
    1154 return iterator;
    1155};
    1156
    1157
    1158/**
    1159 * Creates an iterator that returns a range of elements from an iterable.
    1160 * Similar to {@see goog.array#slice} but does not support negative indexes.
    1161 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    1162 * iterable to slice.
    1163 * @param {number} start The index of the first element to return.
    1164 * @param {number=} opt_end The index after the last element to return. If
    1165 * defined, must be greater than or equal to {@code start}.
    1166 * @return {!goog.iter.Iterator.<VALUE>} A new iterator containing a slice of
    1167 * the original.
    1168 * @template VALUE
    1169 */
    1170goog.iter.slice = function(iterable, start, opt_end) {
    1171 goog.asserts.assert(goog.math.isInt(start) && start >= 0);
    1172
    1173 var iterator = goog.iter.consume(iterable, start);
    1174
    1175 if (goog.isNumber(opt_end)) {
    1176 goog.asserts.assert(
    1177 goog.math.isInt(/** @type {number} */ (opt_end)) && opt_end >= start);
    1178 iterator = goog.iter.limit(iterator, opt_end - start /* limitSize */);
    1179 }
    1180
    1181 return iterator;
    1182};
    1183
    1184
    1185/**
    1186 * Checks an array for duplicate elements.
    1187 * @param {Array.<VALUE>|goog.array.ArrayLike} arr The array to check for
    1188 * duplicates.
    1189 * @return {boolean} True, if the array contains duplicates, false otherwise.
    1190 * @private
    1191 * @template VALUE
    1192 */
    1193// TODO(user): Consider moving this into goog.array as a public function.
    1194goog.iter.hasDuplicates_ = function(arr) {
    1195 var deduped = [];
    1196 goog.array.removeDuplicates(arr, deduped);
    1197 return arr.length != deduped.length;
    1198};
    1199
    1200
    1201/**
    1202 * Creates an iterator that returns permutations of elements in
    1203 * {@code iterable}.
    1204 *
    1205 * Permutations are obtained by taking the Cartesian product of
    1206 * {@code opt_length} iterables and filtering out those with repeated
    1207 * elements. For example, the permutations of {@code [1,2,3]} are
    1208 * {@code [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]}.
    1209 * @see http://docs.python.org/2/library/itertools.html#itertools.permutations
    1210 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    1211 * iterable from which to generate permutations.
    1212 * @param {number=} opt_length Length of each permutation. If omitted, defaults
    1213 * to the length of {@code iterable}.
    1214 * @return {!goog.iter.Iterator.<!Array.<VALUE>>} A new iterator containing the
    1215 * permutations of {@code iterable}.
    1216 * @template VALUE
    1217 */
    1218goog.iter.permutations = function(iterable, opt_length) {
    1219 var elements = goog.iter.toArray(iterable);
    1220 var length = goog.isNumber(opt_length) ? opt_length : elements.length;
    1221
    1222 var sets = goog.array.repeat(elements, length);
    1223 var product = goog.iter.product.apply(undefined, sets);
    1224
    1225 return goog.iter.filter(product, function(arr) {
    1226 return !goog.iter.hasDuplicates_(arr);
    1227 });
    1228};
    1229
    1230
    1231/**
    1232 * Creates an iterator that returns combinations of elements from
    1233 * {@code iterable}.
    1234 *
    1235 * Combinations are obtained by taking the {@see goog.iter#permutations} of
    1236 * {@code iterable} and filtering those whose elements appear in the order they
    1237 * are encountered in {@code iterable}. For example, the 3-length combinations
    1238 * of {@code [0,1,2,3]} are {@code [[0,1,2], [0,1,3], [0,2,3], [1,2,3]]}.
    1239 * @see http://docs.python.org/2/library/itertools.html#itertools.combinations
    1240 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    1241 * iterable from which to generate combinations.
    1242 * @param {number} length The length of each combination.
    1243 * @return {!goog.iter.Iterator.<!Array.<VALUE>>} A new iterator containing
    1244 * combinations from the {@code iterable}.
    1245 * @template VALUE
    1246 */
    1247goog.iter.combinations = function(iterable, length) {
    1248 var elements = goog.iter.toArray(iterable);
    1249 var indexes = goog.iter.range(elements.length);
    1250 var indexIterator = goog.iter.permutations(indexes, length);
    1251 // sortedIndexIterator will now give arrays of with the given length that
    1252 // indicate what indexes into "elements" should be returned on each iteration.
    1253 var sortedIndexIterator = goog.iter.filter(indexIterator, function(arr) {
    1254 return goog.array.isSorted(arr);
    1255 });
    1256
    1257 var iter = new goog.iter.Iterator();
    1258
    1259 function getIndexFromElements(index) {
    1260 return elements[index];
    1261 }
    1262
    1263 iter.next = function() {
    1264 return goog.array.map(
    1265 /** @type {!Array.<number>} */
    1266 (sortedIndexIterator.next()), getIndexFromElements);
    1267 };
    1268
    1269 return iter;
    1270};
    1271
    1272
    1273/**
    1274 * Creates an iterator that returns combinations of elements from
    1275 * {@code iterable}, with repeated elements possible.
    1276 *
    1277 * Combinations are obtained by taking the Cartesian product of {@code length}
    1278 * iterables and filtering those whose elements appear in the order they are
    1279 * encountered in {@code iterable}. For example, the 2-length combinations of
    1280 * {@code [1,2,3]} are {@code [[1,1], [1,2], [1,3], [2,2], [2,3], [3,3]]}.
    1281 * @see http://docs.python.org/2/library/itertools.html#itertools.combinations_with_replacement
    1282 * @see http://en.wikipedia.org/wiki/Combination#Number_of_combinations_with_repetition
    1283 * @param {!goog.iter.Iterator.<VALUE>|!goog.iter.Iterable} iterable The
    1284 * iterable to combine.
    1285 * @param {number} length The length of each combination.
    1286 * @return {!goog.iter.Iterator.<!Array.<VALUE>>} A new iterator containing
    1287 * combinations from the {@code iterable}.
    1288 * @template VALUE
    1289 */
    1290goog.iter.combinationsWithReplacement = function(iterable, length) {
    1291 var elements = goog.iter.toArray(iterable);
    1292 var indexes = goog.array.range(elements.length);
    1293 var sets = goog.array.repeat(indexes, length);
    1294 var indexIterator = goog.iter.product.apply(undefined, sets);
    1295 // sortedIndexIterator will now give arrays of with the given length that
    1296 // indicate what indexes into "elements" should be returned on each iteration.
    1297 var sortedIndexIterator = goog.iter.filter(indexIterator, function(arr) {
    1298 return goog.array.isSorted(arr);
    1299 });
    1300
    1301 var iter = new goog.iter.Iterator();
    1302
    1303 function getIndexFromElements(index) {
    1304 return elements[index];
    1305 }
    1306
    1307 iter.next = function() {
    1308 return goog.array.map(
    1309 /** @type {!Array.<number>} */
    1310 (sortedIndexIterator.next()), getIndexFromElements);
    1311 };
    1312
    1313 return iter;
    1314};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/json/json.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/json/json.js.src.html new file mode 100644 index 0000000..8691161 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/json/json.js.src.html @@ -0,0 +1 @@ +json.js

    lib/goog/json/json.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview JSON utility functions.
    17 * @author arv@google.com (Erik Arvidsson)
    18 */
    19
    20
    21goog.provide('goog.json');
    22goog.provide('goog.json.Replacer');
    23goog.provide('goog.json.Reviver');
    24goog.provide('goog.json.Serializer');
    25
    26
    27/**
    28 * @define {boolean} If true, use the native JSON parsing API.
    29 * NOTE(user): EXPERIMENTAL, handle with care. Setting this to true might
    30 * break your code. The default {@code goog.json.parse} implementation is able
    31 * to handle invalid JSON, such as JSPB.
    32 */
    33goog.define('goog.json.USE_NATIVE_JSON', false);
    34
    35
    36/**
    37 * Tests if a string is an invalid JSON string. This only ensures that we are
    38 * not using any invalid characters
    39 * @param {string} s The string to test.
    40 * @return {boolean} True if the input is a valid JSON string.
    41 * @private
    42 */
    43goog.json.isValid_ = function(s) {
    44 // All empty whitespace is not valid.
    45 if (/^\s*$/.test(s)) {
    46 return false;
    47 }
    48
    49 // This is taken from http://www.json.org/json2.js which is released to the
    50 // public domain.
    51 // Changes: We dissallow \u2028 Line separator and \u2029 Paragraph separator
    52 // inside strings. We also treat \u2028 and \u2029 as whitespace which they
    53 // are in the RFC but IE and Safari does not match \s to these so we need to
    54 // include them in the reg exps in all places where whitespace is allowed.
    55 // We allowed \x7f inside strings because some tools don't escape it,
    56 // e.g. http://www.json.org/java/org/json/JSONObject.java
    57
    58 // Parsing happens in three stages. In the first stage, we run the text
    59 // against regular expressions that look for non-JSON patterns. We are
    60 // especially concerned with '()' and 'new' because they can cause invocation,
    61 // and '=' because it can cause mutation. But just to be safe, we want to
    62 // reject all unexpected forms.
    63
    64 // We split the first stage into 4 regexp operations in order to work around
    65 // crippling inefficiencies in IE's and Safari's regexp engines. First we
    66 // replace all backslash pairs with '@' (a non-JSON character). Second, we
    67 // replace all simple value tokens with ']' characters. Third, we delete all
    68 // open brackets that follow a colon or comma or that begin the text. Finally,
    69 // we look to see that the remaining characters are only whitespace or ']' or
    70 // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
    71
    72 // Don't make these static since they have the global flag.
    73 var backslashesRe = /\\["\\\/bfnrtu]/g;
    74 var simpleValuesRe =
    75 /"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
    76 var openBracketsRe = /(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g;
    77 var remainderRe = /^[\],:{}\s\u2028\u2029]*$/;
    78
    79 return remainderRe.test(s.replace(backslashesRe, '@').
    80 replace(simpleValuesRe, ']').
    81 replace(openBracketsRe, ''));
    82};
    83
    84
    85/**
    86 * Parses a JSON string and returns the result. This throws an exception if
    87 * the string is an invalid JSON string.
    88 *
    89 * Note that this is very slow on large strings. If you trust the source of
    90 * the string then you should use unsafeParse instead.
    91 *
    92 * @param {*} s The JSON string to parse.
    93 * @throws Error if s is invalid JSON.
    94 * @return {Object} The object generated from the JSON string, or null.
    95 */
    96goog.json.parse = goog.json.USE_NATIVE_JSON ?
    97 /** @type {function(*):Object} */ (goog.global['JSON']['parse']) :
    98 function(s) {
    99 var o = String(s);
    100 if (goog.json.isValid_(o)) {
    101 /** @preserveTry */
    102 try {
    103 return /** @type {Object} */ (eval('(' + o + ')'));
    104 } catch (ex) {
    105 }
    106 }
    107 throw Error('Invalid JSON string: ' + o);
    108 };
    109
    110
    111/**
    112 * Parses a JSON string and returns the result. This uses eval so it is open
    113 * to security issues and it should only be used if you trust the source.
    114 *
    115 * @param {string} s The JSON string to parse.
    116 * @return {Object} The object generated from the JSON string.
    117 */
    118goog.json.unsafeParse = goog.json.USE_NATIVE_JSON ?
    119 /** @type {function(string):Object} */ (goog.global['JSON']['parse']) :
    120 function(s) {
    121 return /** @type {Object} */ (eval('(' + s + ')'));
    122 };
    123
    124
    125/**
    126 * JSON replacer, as defined in Section 15.12.3 of the ES5 spec.
    127 * @see http://ecma-international.org/ecma-262/5.1/#sec-15.12.3
    128 *
    129 * TODO(nicksantos): Array should also be a valid replacer.
    130 *
    131 * @typedef {function(this:Object, string, *): *}
    132 */
    133goog.json.Replacer;
    134
    135
    136/**
    137 * JSON reviver, as defined in Section 15.12.2 of the ES5 spec.
    138 * @see http://ecma-international.org/ecma-262/5.1/#sec-15.12.3
    139 *
    140 * @typedef {function(this:Object, string, *): *}
    141 */
    142goog.json.Reviver;
    143
    144
    145/**
    146 * Serializes an object or a value to a JSON string.
    147 *
    148 * @param {*} object The object to serialize.
    149 * @param {?goog.json.Replacer=} opt_replacer A replacer function
    150 * called for each (key, value) pair that determines how the value
    151 * should be serialized. By defult, this just returns the value
    152 * and allows default serialization to kick in.
    153 * @throws Error if there are loops in the object graph.
    154 * @return {string} A JSON string representation of the input.
    155 */
    156goog.json.serialize = goog.json.USE_NATIVE_JSON ?
    157 /** @type {function(*, ?goog.json.Replacer=):string} */
    158 (goog.global['JSON']['stringify']) :
    159 function(object, opt_replacer) {
    160 // NOTE(nicksantos): Currently, we never use JSON.stringify.
    161 //
    162 // The last time I evaluated this, JSON.stringify had subtle bugs and
    163 // behavior differences on all browsers, and the performance win was not
    164 // large enough to justify all the issues. This may change in the future
    165 // as browser implementations get better.
    166 //
    167 // assertSerialize in json_test contains if branches for the cases
    168 // that fail.
    169 return new goog.json.Serializer(opt_replacer).serialize(object);
    170 };
    171
    172
    173
    174/**
    175 * Class that is used to serialize JSON objects to a string.
    176 * @param {?goog.json.Replacer=} opt_replacer Replacer.
    177 * @constructor
    178 */
    179goog.json.Serializer = function(opt_replacer) {
    180 /**
    181 * @type {goog.json.Replacer|null|undefined}
    182 * @private
    183 */
    184 this.replacer_ = opt_replacer;
    185};
    186
    187
    188/**
    189 * Serializes an object or a value to a JSON string.
    190 *
    191 * @param {*} object The object to serialize.
    192 * @throws Error if there are loops in the object graph.
    193 * @return {string} A JSON string representation of the input.
    194 */
    195goog.json.Serializer.prototype.serialize = function(object) {
    196 var sb = [];
    197 this.serializeInternal(object, sb);
    198 return sb.join('');
    199};
    200
    201
    202/**
    203 * Serializes a generic value to a JSON string
    204 * @protected
    205 * @param {*} object The object to serialize.
    206 * @param {Array} sb Array used as a string builder.
    207 * @throws Error if there are loops in the object graph.
    208 */
    209goog.json.Serializer.prototype.serializeInternal = function(object, sb) {
    210 switch (typeof object) {
    211 case 'string':
    212 this.serializeString_(/** @type {string} */ (object), sb);
    213 break;
    214 case 'number':
    215 this.serializeNumber_(/** @type {number} */ (object), sb);
    216 break;
    217 case 'boolean':
    218 sb.push(object);
    219 break;
    220 case 'undefined':
    221 sb.push('null');
    222 break;
    223 case 'object':
    224 if (object == null) {
    225 sb.push('null');
    226 break;
    227 }
    228 if (goog.isArray(object)) {
    229 this.serializeArray(/** @type {!Array} */ (object), sb);
    230 break;
    231 }
    232 // should we allow new String, new Number and new Boolean to be treated
    233 // as string, number and boolean? Most implementations do not and the
    234 // need is not very big
    235 this.serializeObject_(/** @type {Object} */ (object), sb);
    236 break;
    237 case 'function':
    238 // Skip functions.
    239 // TODO(user) Should we return something here?
    240 break;
    241 default:
    242 throw Error('Unknown type: ' + typeof object);
    243 }
    244};
    245
    246
    247/**
    248 * Character mappings used internally for goog.string.quote
    249 * @private
    250 * @type {!Object}
    251 */
    252goog.json.Serializer.charToJsonCharCache_ = {
    253 '\"': '\\"',
    254 '\\': '\\\\',
    255 '/': '\\/',
    256 '\b': '\\b',
    257 '\f': '\\f',
    258 '\n': '\\n',
    259 '\r': '\\r',
    260 '\t': '\\t',
    261
    262 '\x0B': '\\u000b' // '\v' is not supported in JScript
    263};
    264
    265
    266/**
    267 * Regular expression used to match characters that need to be replaced.
    268 * The S60 browser has a bug where unicode characters are not matched by
    269 * regular expressions. The condition below detects such behaviour and
    270 * adjusts the regular expression accordingly.
    271 * @private
    272 * @type {!RegExp}
    273 */
    274goog.json.Serializer.charsToReplace_ = /\uffff/.test('\uffff') ?
    275 /[\\\"\x00-\x1f\x7f-\uffff]/g : /[\\\"\x00-\x1f\x7f-\xff]/g;
    276
    277
    278/**
    279 * Serializes a string to a JSON string
    280 * @private
    281 * @param {string} s The string to serialize.
    282 * @param {Array} sb Array used as a string builder.
    283 */
    284goog.json.Serializer.prototype.serializeString_ = function(s, sb) {
    285 // The official JSON implementation does not work with international
    286 // characters.
    287 sb.push('"', s.replace(goog.json.Serializer.charsToReplace_, function(c) {
    288 // caching the result improves performance by a factor 2-3
    289 if (c in goog.json.Serializer.charToJsonCharCache_) {
    290 return goog.json.Serializer.charToJsonCharCache_[c];
    291 }
    292
    293 var cc = c.charCodeAt(0);
    294 var rv = '\\u';
    295 if (cc < 16) {
    296 rv += '000';
    297 } else if (cc < 256) {
    298 rv += '00';
    299 } else if (cc < 4096) { // \u1000
    300 rv += '0';
    301 }
    302 return goog.json.Serializer.charToJsonCharCache_[c] = rv + cc.toString(16);
    303 }), '"');
    304};
    305
    306
    307/**
    308 * Serializes a number to a JSON string
    309 * @private
    310 * @param {number} n The number to serialize.
    311 * @param {Array} sb Array used as a string builder.
    312 */
    313goog.json.Serializer.prototype.serializeNumber_ = function(n, sb) {
    314 sb.push(isFinite(n) && !isNaN(n) ? n : 'null');
    315};
    316
    317
    318/**
    319 * Serializes an array to a JSON string
    320 * @param {Array} arr The array to serialize.
    321 * @param {Array} sb Array used as a string builder.
    322 * @protected
    323 */
    324goog.json.Serializer.prototype.serializeArray = function(arr, sb) {
    325 var l = arr.length;
    326 sb.push('[');
    327 var sep = '';
    328 for (var i = 0; i < l; i++) {
    329 sb.push(sep);
    330
    331 var value = arr[i];
    332 this.serializeInternal(
    333 this.replacer_ ? this.replacer_.call(arr, String(i), value) : value,
    334 sb);
    335
    336 sep = ',';
    337 }
    338 sb.push(']');
    339};
    340
    341
    342/**
    343 * Serializes an object to a JSON string
    344 * @private
    345 * @param {Object} obj The object to serialize.
    346 * @param {Array} sb Array used as a string builder.
    347 */
    348goog.json.Serializer.prototype.serializeObject_ = function(obj, sb) {
    349 sb.push('{');
    350 var sep = '';
    351 for (var key in obj) {
    352 if (Object.prototype.hasOwnProperty.call(obj, key)) {
    353 var value = obj[key];
    354 // Skip functions.
    355 // TODO(ptucker) Should we return something for function properties?
    356 if (typeof value != 'function') {
    357 sb.push(sep);
    358 this.serializeString_(key, sb);
    359 sb.push(':');
    360
    361 this.serializeInternal(
    362 this.replacer_ ? this.replacer_.call(obj, key, value) : value,
    363 sb);
    364
    365 sep = ',';
    366 }
    367 }
    368 }
    369 sb.push('}');
    370};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/assertthat.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/assertthat.js.src.html new file mode 100644 index 0000000..fcb21e3 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/assertthat.js.src.html @@ -0,0 +1 @@ +assertthat.js

    lib/goog/labs/testing/assertthat.js

    1// Copyright 2012 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Provides main functionality of assertThat. assertThat calls the
    17 * matcher's matches method to test if a matcher matches assertThat's arguments.
    18 */
    19
    20
    21goog.provide('goog.labs.testing.MatcherError');
    22goog.provide('goog.labs.testing.assertThat');
    23
    24goog.require('goog.asserts');
    25goog.require('goog.debug.Error');
    26goog.require('goog.labs.testing.Matcher');
    27
    28
    29/**
    30 * Asserts that the actual value evaluated by the matcher is true.
    31 *
    32 * @param {*} actual The object to assert by the matcher.
    33 * @param {!goog.labs.testing.Matcher} matcher A matcher to verify values.
    34 * @param {string=} opt_reason Description of what is asserted.
    35 *
    36 */
    37goog.labs.testing.assertThat = function(actual, matcher, opt_reason) {
    38 if (!matcher.matches(actual)) {
    39 // Prefix the error description with a reason from the assert ?
    40 var prefix = opt_reason ? opt_reason + ': ' : '';
    41 var desc = prefix + matcher.describe(actual);
    42
    43 // some sort of failure here
    44 throw new goog.labs.testing.MatcherError(desc);
    45 }
    46};
    47
    48
    49
    50/**
    51 * Error thrown when a Matcher fails to match the input value.
    52 * @param {string=} opt_message The error message.
    53 * @constructor
    54 * @extends {goog.debug.Error}
    55 * @final
    56 */
    57goog.labs.testing.MatcherError = function(opt_message) {
    58 goog.labs.testing.MatcherError.base(this, 'constructor', opt_message);
    59};
    60goog.inherits(goog.labs.testing.MatcherError, goog.debug.Error);
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/logicmatcher.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/logicmatcher.js.src.html new file mode 100644 index 0000000..4266eff --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/logicmatcher.js.src.html @@ -0,0 +1 @@ +logicmatcher.js

    lib/goog/labs/testing/logicmatcher.js

    1// Copyright 2012 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Provides the built-in logic matchers: anyOf, allOf, and isNot.
    17 *
    18 */
    19
    20
    21goog.provide('goog.labs.testing.AllOfMatcher');
    22goog.provide('goog.labs.testing.AnyOfMatcher');
    23goog.provide('goog.labs.testing.IsNotMatcher');
    24
    25
    26goog.require('goog.array');
    27goog.require('goog.labs.testing.Matcher');
    28
    29
    30
    31/**
    32 * The AllOf matcher.
    33 *
    34 * @param {!Array.<!goog.labs.testing.Matcher>} matchers Input matchers.
    35 *
    36 * @constructor
    37 * @struct
    38 * @implements {goog.labs.testing.Matcher}
    39 * @final
    40 */
    41goog.labs.testing.AllOfMatcher = function(matchers) {
    42 /**
    43 * @type {!Array.<!goog.labs.testing.Matcher>}
    44 * @private
    45 */
    46 this.matchers_ = matchers;
    47};
    48
    49
    50/**
    51 * Determines if all of the matchers match the input value.
    52 *
    53 * @override
    54 */
    55goog.labs.testing.AllOfMatcher.prototype.matches = function(actualValue) {
    56 return goog.array.every(this.matchers_, function(matcher) {
    57 return matcher.matches(actualValue);
    58 });
    59};
    60
    61
    62/**
    63 * Describes why the matcher failed. The returned string is a concatenation of
    64 * all the failed matchers' error strings.
    65 *
    66 * @override
    67 */
    68goog.labs.testing.AllOfMatcher.prototype.describe =
    69 function(actualValue) {
    70 // TODO(user) : Optimize this to remove duplication with matches ?
    71 var errorString = '';
    72 goog.array.forEach(this.matchers_, function(matcher) {
    73 if (!matcher.matches(actualValue)) {
    74 errorString += matcher.describe(actualValue) + '\n';
    75 }
    76 });
    77 return errorString;
    78};
    79
    80
    81
    82/**
    83 * The AnyOf matcher.
    84 *
    85 * @param {!Array.<!goog.labs.testing.Matcher>} matchers Input matchers.
    86 *
    87 * @constructor
    88 * @struct
    89 * @implements {goog.labs.testing.Matcher}
    90 * @final
    91 */
    92goog.labs.testing.AnyOfMatcher = function(matchers) {
    93 /**
    94 * @type {!Array.<!goog.labs.testing.Matcher>}
    95 * @private
    96 */
    97 this.matchers_ = matchers;
    98};
    99
    100
    101/**
    102 * Determines if any of the matchers matches the input value.
    103 *
    104 * @override
    105 */
    106goog.labs.testing.AnyOfMatcher.prototype.matches = function(actualValue) {
    107 return goog.array.some(this.matchers_, function(matcher) {
    108 return matcher.matches(actualValue);
    109 });
    110};
    111
    112
    113/**
    114 * Describes why the matcher failed.
    115 *
    116 * @override
    117 */
    118goog.labs.testing.AnyOfMatcher.prototype.describe =
    119 function(actualValue) {
    120 // TODO(user) : Optimize this to remove duplication with matches ?
    121 var errorString = '';
    122 goog.array.forEach(this.matchers_, function(matcher) {
    123 if (!matcher.matches(actualValue)) {
    124 errorString += matcher.describe(actualValue) + '\n';
    125 }
    126 });
    127 return errorString;
    128};
    129
    130
    131
    132/**
    133 * The IsNot matcher.
    134 *
    135 * @param {!goog.labs.testing.Matcher} matcher The matcher to negate.
    136 *
    137 * @constructor
    138 * @struct
    139 * @implements {goog.labs.testing.Matcher}
    140 * @final
    141 */
    142goog.labs.testing.IsNotMatcher = function(matcher) {
    143 /**
    144 * @type {!goog.labs.testing.Matcher}
    145 * @private
    146 */
    147 this.matcher_ = matcher;
    148};
    149
    150
    151/**
    152 * Determines if the input value doesn't satisfy a matcher.
    153 *
    154 * @override
    155 */
    156goog.labs.testing.IsNotMatcher.prototype.matches = function(actualValue) {
    157 return !this.matcher_.matches(actualValue);
    158};
    159
    160
    161/**
    162 * Describes why the matcher failed.
    163 *
    164 * @override
    165 */
    166goog.labs.testing.IsNotMatcher.prototype.describe =
    167 function(actualValue) {
    168 return 'The following is false: ' + this.matcher_.describe(actualValue);
    169};
    170
    171
    172/**
    173 * Creates a matcher that will succeed only if all of the given matchers
    174 * succeed.
    175 *
    176 * @param {...goog.labs.testing.Matcher} var_args The matchers to test
    177 * against.
    178 *
    179 * @return {!goog.labs.testing.AllOfMatcher} The AllOf matcher.
    180 */
    181function allOf(var_args) {
    182 var matchers = goog.array.toArray(arguments);
    183 return new goog.labs.testing.AllOfMatcher(matchers);
    184}
    185
    186
    187/**
    188 * Accepts a set of matchers and returns a matcher which matches
    189 * values which satisfy the constraints of any of the given matchers.
    190 *
    191 * @param {...goog.labs.testing.Matcher} var_args The matchers to test
    192 * against.
    193 *
    194 * @return {!goog.labs.testing.AnyOfMatcher} The AnyOf matcher.
    195 */
    196function anyOf(var_args) {
    197 var matchers = goog.array.toArray(arguments);
    198 return new goog.labs.testing.AnyOfMatcher(matchers);
    199}
    200
    201
    202/**
    203 * Returns a matcher that negates the input matcher. The returned
    204 * matcher matches the values not matched by the input matcher and vice-versa.
    205 *
    206 * @param {!goog.labs.testing.Matcher} matcher The matcher to test against.
    207 *
    208 * @return {!goog.labs.testing.IsNotMatcher} The IsNot matcher.
    209 */
    210function isNot(matcher) {
    211 return new goog.labs.testing.IsNotMatcher(matcher);
    212}
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/matcher.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/matcher.js.src.html new file mode 100644 index 0000000..2de8387 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/matcher.js.src.html @@ -0,0 +1 @@ +matcher.js

    lib/goog/labs/testing/matcher.js

    1// Copyright 2012 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Provides the base Matcher interface. User code should use the
    17 * matchers through assertThat statements and not directly.
    18 */
    19
    20
    21goog.provide('goog.labs.testing.Matcher');
    22
    23
    24
    25/**
    26 * A matcher object to be used in assertThat statements.
    27 * @interface
    28 */
    29goog.labs.testing.Matcher = function() {};
    30
    31
    32/**
    33 * Determines whether a value matches the constraints of the match.
    34 *
    35 * @param {*} value The object to match.
    36 * @return {boolean} Whether the input value matches this matcher.
    37 */
    38goog.labs.testing.Matcher.prototype.matches = function(value) {};
    39
    40
    41/**
    42 * Describes why the matcher failed.
    43 *
    44 * @param {*} value The value that didn't match.
    45 * @param {string=} opt_description A partial description to which the reason
    46 * will be appended.
    47 *
    48 * @return {string} Description of why the matcher failed.
    49 */
    50goog.labs.testing.Matcher.prototype.describe =
    51 function(value, opt_description) {};
    52
    53
    54/**
    55 * Generates a Matcher from the ‘matches’ and ‘describe’ functions passed in.
    56 *
    57 * @param {!Function} matchesFunction The ‘matches’ function.
    58 * @param {Function=} opt_describeFunction The ‘describe’ function.
    59 * @return {!Function} The custom matcher.
    60 */
    61goog.labs.testing.Matcher.makeMatcher =
    62 function(matchesFunction, opt_describeFunction) {
    63
    64 /**
    65 * @constructor
    66 * @implements {goog.labs.testing.Matcher}
    67 * @final
    68 */
    69 var matcherConstructor = function() {};
    70
    71 /** @override */
    72 matcherConstructor.prototype.matches = matchesFunction;
    73
    74 if (opt_describeFunction) {
    75 /** @override */
    76 matcherConstructor.prototype.describe = opt_describeFunction;
    77 }
    78
    79 return matcherConstructor;
    80};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/numbermatcher.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/numbermatcher.js.src.html new file mode 100644 index 0000000..49f9190 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/numbermatcher.js.src.html @@ -0,0 +1 @@ +numbermatcher.js

    lib/goog/labs/testing/numbermatcher.js

    1// Copyright 2012 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Provides the built-in number matchers like lessThan,
    17 * greaterThan, etc.
    18 */
    19
    20
    21goog.provide('goog.labs.testing.CloseToMatcher');
    22goog.provide('goog.labs.testing.EqualToMatcher');
    23goog.provide('goog.labs.testing.GreaterThanEqualToMatcher');
    24goog.provide('goog.labs.testing.GreaterThanMatcher');
    25goog.provide('goog.labs.testing.LessThanEqualToMatcher');
    26goog.provide('goog.labs.testing.LessThanMatcher');
    27
    28
    29goog.require('goog.asserts');
    30goog.require('goog.labs.testing.Matcher');
    31
    32
    33
    34/**
    35 * The GreaterThan matcher.
    36 *
    37 * @param {number} value The value to compare.
    38 *
    39 * @constructor
    40 * @struct
    41 * @implements {goog.labs.testing.Matcher}
    42 * @final
    43 */
    44goog.labs.testing.GreaterThanMatcher = function(value) {
    45 /**
    46 * @type {number}
    47 * @private
    48 */
    49 this.value_ = value;
    50};
    51
    52
    53/**
    54 * Determines if input value is greater than the expected value.
    55 *
    56 * @override
    57 */
    58goog.labs.testing.GreaterThanMatcher.prototype.matches = function(actualValue) {
    59 goog.asserts.assertNumber(actualValue);
    60 return actualValue > this.value_;
    61};
    62
    63
    64/**
    65 * @override
    66 */
    67goog.labs.testing.GreaterThanMatcher.prototype.describe =
    68 function(actualValue) {
    69 goog.asserts.assertNumber(actualValue);
    70 return actualValue + ' is not greater than ' + this.value_;
    71};
    72
    73
    74
    75/**
    76 * The lessThan matcher.
    77 *
    78 * @param {number} value The value to compare.
    79 *
    80 * @constructor
    81 * @struct
    82 * @implements {goog.labs.testing.Matcher}
    83 * @final
    84 */
    85goog.labs.testing.LessThanMatcher = function(value) {
    86 /**
    87 * @type {number}
    88 * @private
    89 */
    90 this.value_ = value;
    91};
    92
    93
    94/**
    95 * Determines if the input value is less than the expected value.
    96 *
    97 * @override
    98 */
    99goog.labs.testing.LessThanMatcher.prototype.matches = function(actualValue) {
    100 goog.asserts.assertNumber(actualValue);
    101 return actualValue < this.value_;
    102};
    103
    104
    105/**
    106 * @override
    107 */
    108goog.labs.testing.LessThanMatcher.prototype.describe =
    109 function(actualValue) {
    110 goog.asserts.assertNumber(actualValue);
    111 return actualValue + ' is not less than ' + this.value_;
    112};
    113
    114
    115
    116/**
    117 * The GreaterThanEqualTo matcher.
    118 *
    119 * @param {number} value The value to compare.
    120 *
    121 * @constructor
    122 * @struct
    123 * @implements {goog.labs.testing.Matcher}
    124 * @final
    125 */
    126goog.labs.testing.GreaterThanEqualToMatcher = function(value) {
    127 /**
    128 * @type {number}
    129 * @private
    130 */
    131 this.value_ = value;
    132};
    133
    134
    135/**
    136 * Determines if the input value is greater than equal to the expected value.
    137 *
    138 * @override
    139 */
    140goog.labs.testing.GreaterThanEqualToMatcher.prototype.matches =
    141 function(actualValue) {
    142 goog.asserts.assertNumber(actualValue);
    143 return actualValue >= this.value_;
    144};
    145
    146
    147/**
    148 * @override
    149 */
    150goog.labs.testing.GreaterThanEqualToMatcher.prototype.describe =
    151 function(actualValue) {
    152 goog.asserts.assertNumber(actualValue);
    153 return actualValue + ' is not greater than equal to ' + this.value_;
    154};
    155
    156
    157
    158/**
    159 * The LessThanEqualTo matcher.
    160 *
    161 * @param {number} value The value to compare.
    162 *
    163 * @constructor
    164 * @struct
    165 * @implements {goog.labs.testing.Matcher}
    166 * @final
    167 */
    168goog.labs.testing.LessThanEqualToMatcher = function(value) {
    169 /**
    170 * @type {number}
    171 * @private
    172 */
    173 this.value_ = value;
    174};
    175
    176
    177/**
    178 * Determines if the input value is less than or equal to the expected value.
    179 *
    180 * @override
    181 */
    182goog.labs.testing.LessThanEqualToMatcher.prototype.matches =
    183 function(actualValue) {
    184 goog.asserts.assertNumber(actualValue);
    185 return actualValue <= this.value_;
    186};
    187
    188
    189/**
    190 * @override
    191 */
    192goog.labs.testing.LessThanEqualToMatcher.prototype.describe =
    193 function(actualValue) {
    194 goog.asserts.assertNumber(actualValue);
    195 return actualValue + ' is not less than equal to ' + this.value_;
    196};
    197
    198
    199
    200/**
    201 * The EqualTo matcher.
    202 *
    203 * @param {number} value The value to compare.
    204 *
    205 * @constructor
    206 * @struct
    207 * @implements {goog.labs.testing.Matcher}
    208 * @final
    209 */
    210goog.labs.testing.EqualToMatcher = function(value) {
    211 /**
    212 * @type {number}
    213 * @private
    214 */
    215 this.value_ = value;
    216};
    217
    218
    219/**
    220 * Determines if the input value is equal to the expected value.
    221 *
    222 * @override
    223 */
    224goog.labs.testing.EqualToMatcher.prototype.matches = function(actualValue) {
    225 goog.asserts.assertNumber(actualValue);
    226 return actualValue === this.value_;
    227};
    228
    229
    230/**
    231 * @override
    232 */
    233goog.labs.testing.EqualToMatcher.prototype.describe =
    234 function(actualValue) {
    235 goog.asserts.assertNumber(actualValue);
    236 return actualValue + ' is not equal to ' + this.value_;
    237};
    238
    239
    240
    241/**
    242 * The CloseTo matcher.
    243 *
    244 * @param {number} value The value to compare.
    245 * @param {number} range The range to check within.
    246 *
    247 * @constructor
    248 * @struct
    249 * @implements {goog.labs.testing.Matcher}
    250 * @final
    251 */
    252goog.labs.testing.CloseToMatcher = function(value, range) {
    253 /**
    254 * @type {number}
    255 * @private
    256 */
    257 this.value_ = value;
    258 /**
    259 * @type {number}
    260 * @private
    261 */
    262 this.range_ = range;
    263};
    264
    265
    266/**
    267 * Determines if input value is within a certain range of the expected value.
    268 *
    269 * @override
    270 */
    271goog.labs.testing.CloseToMatcher.prototype.matches = function(actualValue) {
    272 goog.asserts.assertNumber(actualValue);
    273 return Math.abs(this.value_ - actualValue) < this.range_;
    274};
    275
    276
    277/**
    278 * @override
    279 */
    280goog.labs.testing.CloseToMatcher.prototype.describe =
    281 function(actualValue) {
    282 goog.asserts.assertNumber(actualValue);
    283 return actualValue + ' is not close to(' + this.range_ + ') ' + this.value_;
    284};
    285
    286
    287/**
    288 * @param {number} value The expected value.
    289 *
    290 * @return {!goog.labs.testing.GreaterThanMatcher} A GreaterThanMatcher.
    291 */
    292function greaterThan(value) {
    293 return new goog.labs.testing.GreaterThanMatcher(value);
    294}
    295
    296
    297/**
    298 * @param {number} value The expected value.
    299 *
    300 * @return {!goog.labs.testing.GreaterThanEqualToMatcher} A
    301 * GreaterThanEqualToMatcher.
    302 */
    303function greaterThanEqualTo(value) {
    304 return new goog.labs.testing.GreaterThanEqualToMatcher(value);
    305}
    306
    307
    308/**
    309 * @param {number} value The expected value.
    310 *
    311 * @return {!goog.labs.testing.LessThanMatcher} A LessThanMatcher.
    312 */
    313function lessThan(value) {
    314 return new goog.labs.testing.LessThanMatcher(value);
    315}
    316
    317
    318/**
    319 * @param {number} value The expected value.
    320 *
    321 * @return {!goog.labs.testing.LessThanEqualToMatcher} A LessThanEqualToMatcher.
    322 */
    323function lessThanEqualTo(value) {
    324 return new goog.labs.testing.LessThanEqualToMatcher(value);
    325}
    326
    327
    328/**
    329 * @param {number} value The expected value.
    330 *
    331 * @return {!goog.labs.testing.EqualToMatcher} An EqualToMatcher.
    332 */
    333function equalTo(value) {
    334 return new goog.labs.testing.EqualToMatcher(value);
    335}
    336
    337
    338/**
    339 * @param {number} value The expected value.
    340 * @param {number} range The maximum allowed difference from the expected value.
    341 *
    342 * @return {!goog.labs.testing.CloseToMatcher} A CloseToMatcher.
    343 */
    344function closeTo(value, range) {
    345 return new goog.labs.testing.CloseToMatcher(value, range);
    346}
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/objectmatcher.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/objectmatcher.js.src.html new file mode 100644 index 0000000..f7b3ee9 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/objectmatcher.js.src.html @@ -0,0 +1 @@ +objectmatcher.js

    lib/goog/labs/testing/objectmatcher.js

    1// Copyright 2012 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Provides the built-in object matchers like equalsObject,
    17 * hasProperty, instanceOf, etc.
    18 */
    19
    20
    21
    22goog.provide('goog.labs.testing.HasPropertyMatcher');
    23goog.provide('goog.labs.testing.InstanceOfMatcher');
    24goog.provide('goog.labs.testing.IsNullMatcher');
    25goog.provide('goog.labs.testing.IsNullOrUndefinedMatcher');
    26goog.provide('goog.labs.testing.IsUndefinedMatcher');
    27goog.provide('goog.labs.testing.ObjectEqualsMatcher');
    28
    29
    30goog.require('goog.labs.testing.Matcher');
    31goog.require('goog.string');
    32
    33
    34
    35/**
    36 * The Equals matcher.
    37 *
    38 * @param {!Object} expectedObject The expected object.
    39 *
    40 * @constructor
    41 * @struct
    42 * @implements {goog.labs.testing.Matcher}
    43 * @final
    44 */
    45goog.labs.testing.ObjectEqualsMatcher = function(expectedObject) {
    46 /**
    47 * @type {!Object}
    48 * @private
    49 */
    50 this.object_ = expectedObject;
    51};
    52
    53
    54/**
    55 * Determines if two objects are the same.
    56 *
    57 * @override
    58 */
    59goog.labs.testing.ObjectEqualsMatcher.prototype.matches =
    60 function(actualObject) {
    61 return actualObject === this.object_;
    62};
    63
    64
    65/**
    66 * @override
    67 */
    68goog.labs.testing.ObjectEqualsMatcher.prototype.describe =
    69 function(actualObject) {
    70 return 'Input object is not the same as the expected object.';
    71};
    72
    73
    74
    75/**
    76 * The HasProperty matcher.
    77 *
    78 * @param {string} property Name of the property to test.
    79 *
    80 * @constructor
    81 * @struct
    82 * @implements {goog.labs.testing.Matcher}
    83 * @final
    84 */
    85goog.labs.testing.HasPropertyMatcher = function(property) {
    86 /**
    87 * @type {string}
    88 * @private
    89 */
    90 this.property_ = property;
    91};
    92
    93
    94/**
    95 * Determines if an object has a property.
    96 *
    97 * @override
    98 */
    99goog.labs.testing.HasPropertyMatcher.prototype.matches =
    100 function(actualObject) {
    101 return this.property_ in actualObject;
    102};
    103
    104
    105/**
    106 * @override
    107 */
    108goog.labs.testing.HasPropertyMatcher.prototype.describe =
    109 function(actualObject) {
    110 return 'Object does not have property: ' + this.property_;
    111};
    112
    113
    114
    115/**
    116 * The InstanceOf matcher.
    117 *
    118 * @param {!Object} object The expected class object.
    119 *
    120 * @constructor
    121 * @struct
    122 * @implements {goog.labs.testing.Matcher}
    123 * @final
    124 */
    125goog.labs.testing.InstanceOfMatcher = function(object) {
    126 /**
    127 * @type {!Object}
    128 * @private
    129 */
    130 this.object_ = object;
    131};
    132
    133
    134/**
    135 * Determines if an object is an instance of another object.
    136 *
    137 * @override
    138 */
    139goog.labs.testing.InstanceOfMatcher.prototype.matches =
    140 function(actualObject) {
    141 return actualObject instanceof this.object_;
    142};
    143
    144
    145/**
    146 * @override
    147 */
    148goog.labs.testing.InstanceOfMatcher.prototype.describe =
    149 function(actualObject) {
    150 return 'Input object is not an instance of the expected object';
    151};
    152
    153
    154
    155/**
    156 * The IsNullOrUndefined matcher.
    157 *
    158 * @constructor
    159 * @struct
    160 * @implements {goog.labs.testing.Matcher}
    161 * @final
    162 */
    163goog.labs.testing.IsNullOrUndefinedMatcher = function() {};
    164
    165
    166/**
    167 * Determines if input value is null or undefined.
    168 *
    169 * @override
    170 */
    171goog.labs.testing.IsNullOrUndefinedMatcher.prototype.matches =
    172 function(actualValue) {
    173 return !goog.isDefAndNotNull(actualValue);
    174};
    175
    176
    177/**
    178 * @override
    179 */
    180goog.labs.testing.IsNullOrUndefinedMatcher.prototype.describe =
    181 function(actualValue) {
    182 return actualValue + ' is not null or undefined.';
    183};
    184
    185
    186
    187/**
    188 * The IsNull matcher.
    189 *
    190 * @constructor
    191 * @struct
    192 * @implements {goog.labs.testing.Matcher}
    193 * @final
    194 */
    195goog.labs.testing.IsNullMatcher = function() {};
    196
    197
    198/**
    199 * Determines if input value is null.
    200 *
    201 * @override
    202 */
    203goog.labs.testing.IsNullMatcher.prototype.matches =
    204 function(actualValue) {
    205 return goog.isNull(actualValue);
    206};
    207
    208
    209/**
    210 * @override
    211 */
    212goog.labs.testing.IsNullMatcher.prototype.describe =
    213 function(actualValue) {
    214 return actualValue + ' is not null.';
    215};
    216
    217
    218
    219/**
    220 * The IsUndefined matcher.
    221 *
    222 * @constructor
    223 * @struct
    224 * @implements {goog.labs.testing.Matcher}
    225 * @final
    226 */
    227goog.labs.testing.IsUndefinedMatcher = function() {};
    228
    229
    230/**
    231 * Determines if input value is undefined.
    232 *
    233 * @override
    234 */
    235goog.labs.testing.IsUndefinedMatcher.prototype.matches =
    236 function(actualValue) {
    237 return !goog.isDef(actualValue);
    238};
    239
    240
    241/**
    242 * @override
    243 */
    244goog.labs.testing.IsUndefinedMatcher.prototype.describe =
    245 function(actualValue) {
    246 return actualValue + ' is not undefined.';
    247};
    248
    249
    250/**
    251 * Returns a matcher that matches objects that are equal to the input object.
    252 * Equality in this case means the two objects are references to the same
    253 * object.
    254 *
    255 * @param {!Object} object The expected object.
    256 *
    257 * @return {!goog.labs.testing.ObjectEqualsMatcher} A
    258 * ObjectEqualsMatcher.
    259 */
    260function equalsObject(object) {
    261 return new goog.labs.testing.ObjectEqualsMatcher(object);
    262}
    263
    264
    265/**
    266 * Returns a matcher that matches objects that contain the input property.
    267 *
    268 * @param {string} property The property name to check.
    269 *
    270 * @return {!goog.labs.testing.HasPropertyMatcher} A HasPropertyMatcher.
    271 */
    272function hasProperty(property) {
    273 return new goog.labs.testing.HasPropertyMatcher(property);
    274}
    275
    276
    277/**
    278 * Returns a matcher that matches instances of the input class.
    279 *
    280 * @param {!Object} object The class object.
    281 *
    282 * @return {!goog.labs.testing.InstanceOfMatcher} A
    283 * InstanceOfMatcher.
    284 */
    285function instanceOfClass(object) {
    286 return new goog.labs.testing.InstanceOfMatcher(object);
    287}
    288
    289
    290/**
    291 * Returns a matcher that matches all null values.
    292 *
    293 * @return {!goog.labs.testing.IsNullMatcher} A IsNullMatcher.
    294 */
    295function isNull() {
    296 return new goog.labs.testing.IsNullMatcher();
    297}
    298
    299
    300/**
    301 * Returns a matcher that matches all null and undefined values.
    302 *
    303 * @return {!goog.labs.testing.IsNullOrUndefinedMatcher} A
    304 * IsNullOrUndefinedMatcher.
    305 */
    306function isNullOrUndefined() {
    307 return new goog.labs.testing.IsNullOrUndefinedMatcher();
    308}
    309
    310
    311/**
    312 * Returns a matcher that matches undefined values.
    313 *
    314 * @return {!goog.labs.testing.IsUndefinedMatcher} A IsUndefinedMatcher.
    315 */
    316function isUndefined() {
    317 return new goog.labs.testing.IsUndefinedMatcher();
    318}
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/stringmatcher.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/stringmatcher.js.src.html new file mode 100644 index 0000000..da868e8 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/testing/stringmatcher.js.src.html @@ -0,0 +1 @@ +stringmatcher.js

    lib/goog/labs/testing/stringmatcher.js

    1// Copyright 2012 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Provides the built-in string matchers like containsString,
    17 * startsWith, endsWith, etc.
    18 */
    19
    20
    21goog.provide('goog.labs.testing.ContainsStringMatcher');
    22goog.provide('goog.labs.testing.EndsWithMatcher');
    23goog.provide('goog.labs.testing.EqualToIgnoringCaseMatcher');
    24goog.provide('goog.labs.testing.EqualToIgnoringWhitespaceMatcher');
    25goog.provide('goog.labs.testing.EqualsMatcher');
    26goog.provide('goog.labs.testing.RegexMatcher');
    27goog.provide('goog.labs.testing.StartsWithMatcher');
    28goog.provide('goog.labs.testing.StringContainsInOrderMatcher');
    29
    30
    31goog.require('goog.asserts');
    32goog.require('goog.labs.testing.Matcher');
    33goog.require('goog.string');
    34
    35
    36
    37/**
    38 * The ContainsString matcher.
    39 *
    40 * @param {string} value The expected string.
    41 *
    42 * @constructor
    43 * @struct
    44 * @implements {goog.labs.testing.Matcher}
    45 * @final
    46 */
    47goog.labs.testing.ContainsStringMatcher = function(value) {
    48 /**
    49 * @type {string}
    50 * @private
    51 */
    52 this.value_ = value;
    53};
    54
    55
    56/**
    57 * Determines if input string contains the expected string.
    58 *
    59 * @override
    60 */
    61goog.labs.testing.ContainsStringMatcher.prototype.matches =
    62 function(actualValue) {
    63 goog.asserts.assertString(actualValue);
    64 return goog.string.contains(actualValue, this.value_);
    65};
    66
    67
    68/**
    69 * @override
    70 */
    71goog.labs.testing.ContainsStringMatcher.prototype.describe =
    72 function(actualValue) {
    73 return actualValue + ' does not contain ' + this.value_;
    74};
    75
    76
    77
    78/**
    79 * The EndsWith matcher.
    80 *
    81 * @param {string} value The expected string.
    82 *
    83 * @constructor
    84 * @struct
    85 * @implements {goog.labs.testing.Matcher}
    86 * @final
    87 */
    88goog.labs.testing.EndsWithMatcher = function(value) {
    89 /**
    90 * @type {string}
    91 * @private
    92 */
    93 this.value_ = value;
    94};
    95
    96
    97/**
    98 * Determines if input string ends with the expected string.
    99 *
    100 * @override
    101 */
    102goog.labs.testing.EndsWithMatcher.prototype.matches = function(actualValue) {
    103 goog.asserts.assertString(actualValue);
    104 return goog.string.endsWith(actualValue, this.value_);
    105};
    106
    107
    108/**
    109 * @override
    110 */
    111goog.labs.testing.EndsWithMatcher.prototype.describe =
    112 function(actualValue) {
    113 return actualValue + ' does not end with ' + this.value_;
    114};
    115
    116
    117
    118/**
    119 * The EqualToIgnoringWhitespace matcher.
    120 *
    121 * @param {string} value The expected string.
    122 *
    123 * @constructor
    124 * @struct
    125 * @implements {goog.labs.testing.Matcher}
    126 * @final
    127 */
    128goog.labs.testing.EqualToIgnoringWhitespaceMatcher = function(value) {
    129 /**
    130 * @type {string}
    131 * @private
    132 */
    133 this.value_ = value;
    134};
    135
    136
    137/**
    138 * Determines if input string contains the expected string.
    139 *
    140 * @override
    141 */
    142goog.labs.testing.EqualToIgnoringWhitespaceMatcher.prototype.matches =
    143 function(actualValue) {
    144 goog.asserts.assertString(actualValue);
    145 var string1 = goog.string.collapseWhitespace(actualValue);
    146
    147 return goog.string.caseInsensitiveCompare(this.value_, string1) === 0;
    148};
    149
    150
    151/**
    152 * @override
    153 */
    154goog.labs.testing.EqualToIgnoringWhitespaceMatcher.prototype.describe =
    155 function(actualValue) {
    156 return actualValue + ' is not equal(ignoring whitespace) to ' + this.value_;
    157};
    158
    159
    160
    161/**
    162 * The Equals matcher.
    163 *
    164 * @param {string} value The expected string.
    165 *
    166 * @constructor
    167 * @struct
    168 * @implements {goog.labs.testing.Matcher}
    169 * @final
    170 */
    171goog.labs.testing.EqualsMatcher = function(value) {
    172 /**
    173 * @type {string}
    174 * @private
    175 */
    176 this.value_ = value;
    177};
    178
    179
    180/**
    181 * Determines if input string is equal to the expected string.
    182 *
    183 * @override
    184 */
    185goog.labs.testing.EqualsMatcher.prototype.matches = function(actualValue) {
    186 goog.asserts.assertString(actualValue);
    187 return this.value_ === actualValue;
    188};
    189
    190
    191/**
    192 * @override
    193 */
    194goog.labs.testing.EqualsMatcher.prototype.describe =
    195 function(actualValue) {
    196 return actualValue + ' is not equal to ' + this.value_;
    197};
    198
    199
    200
    201/**
    202 * The MatchesRegex matcher.
    203 *
    204 * @param {!RegExp} regex The expected regex.
    205 *
    206 * @constructor
    207 * @struct
    208 * @implements {goog.labs.testing.Matcher}
    209 * @final
    210 */
    211goog.labs.testing.RegexMatcher = function(regex) {
    212 /**
    213 * @type {!RegExp}
    214 * @private
    215 */
    216 this.regex_ = regex;
    217};
    218
    219
    220/**
    221 * Determines if input string is equal to the expected string.
    222 *
    223 * @override
    224 */
    225goog.labs.testing.RegexMatcher.prototype.matches = function(
    226 actualValue) {
    227 goog.asserts.assertString(actualValue);
    228 return this.regex_.test(actualValue);
    229};
    230
    231
    232/**
    233 * @override
    234 */
    235goog.labs.testing.RegexMatcher.prototype.describe =
    236 function(actualValue) {
    237 return actualValue + ' does not match ' + this.regex_;
    238};
    239
    240
    241
    242/**
    243 * The StartsWith matcher.
    244 *
    245 * @param {string} value The expected string.
    246 *
    247 * @constructor
    248 * @struct
    249 * @implements {goog.labs.testing.Matcher}
    250 * @final
    251 */
    252goog.labs.testing.StartsWithMatcher = function(value) {
    253 /**
    254 * @type {string}
    255 * @private
    256 */
    257 this.value_ = value;
    258};
    259
    260
    261/**
    262 * Determines if input string starts with the expected string.
    263 *
    264 * @override
    265 */
    266goog.labs.testing.StartsWithMatcher.prototype.matches = function(actualValue) {
    267 goog.asserts.assertString(actualValue);
    268 return goog.string.startsWith(actualValue, this.value_);
    269};
    270
    271
    272/**
    273 * @override
    274 */
    275goog.labs.testing.StartsWithMatcher.prototype.describe =
    276 function(actualValue) {
    277 return actualValue + ' does not start with ' + this.value_;
    278};
    279
    280
    281
    282/**
    283 * The StringContainsInOrdermatcher.
    284 *
    285 * @param {Array.<string>} values The expected string values.
    286 *
    287 * @constructor
    288 * @struct
    289 * @implements {goog.labs.testing.Matcher}
    290 * @final
    291 */
    292goog.labs.testing.StringContainsInOrderMatcher = function(values) {
    293 /**
    294 * @type {Array.<string>}
    295 * @private
    296 */
    297 this.values_ = values;
    298};
    299
    300
    301/**
    302 * Determines if input string contains, in order, the expected array of strings.
    303 *
    304 * @override
    305 */
    306goog.labs.testing.StringContainsInOrderMatcher.prototype.matches =
    307 function(actualValue) {
    308 goog.asserts.assertString(actualValue);
    309 var currentIndex, previousIndex = 0;
    310 for (var i = 0; i < this.values_.length; i++) {
    311 currentIndex = goog.string.contains(actualValue, this.values_[i]);
    312 if (currentIndex < 0 || currentIndex < previousIndex) {
    313 return false;
    314 }
    315 previousIndex = currentIndex;
    316 }
    317 return true;
    318};
    319
    320
    321/**
    322 * @override
    323 */
    324goog.labs.testing.StringContainsInOrderMatcher.prototype.describe =
    325 function(actualValue) {
    326 return actualValue + ' does not contain the expected values in order.';
    327};
    328
    329
    330/**
    331 * Matches a string containing the given string.
    332 *
    333 * @param {string} value The expected value.
    334 *
    335 * @return {!goog.labs.testing.ContainsStringMatcher} A
    336 * ContainsStringMatcher.
    337 */
    338function containsString(value) {
    339 return new goog.labs.testing.ContainsStringMatcher(value);
    340}
    341
    342
    343/**
    344 * Matches a string that ends with the given string.
    345 *
    346 * @param {string} value The expected value.
    347 *
    348 * @return {!goog.labs.testing.EndsWithMatcher} A
    349 * EndsWithMatcher.
    350 */
    351function endsWith(value) {
    352 return new goog.labs.testing.EndsWithMatcher(value);
    353}
    354
    355
    356/**
    357 * Matches a string that equals (ignoring whitespace) the given string.
    358 *
    359 * @param {string} value The expected value.
    360 *
    361 * @return {!goog.labs.testing.EqualToIgnoringWhitespaceMatcher} A
    362 * EqualToIgnoringWhitespaceMatcher.
    363 */
    364function equalToIgnoringWhitespace(value) {
    365 return new goog.labs.testing.EqualToIgnoringWhitespaceMatcher(value);
    366}
    367
    368
    369/**
    370 * Matches a string that equals the given string.
    371 *
    372 * @param {string} value The expected value.
    373 *
    374 * @return {!goog.labs.testing.EqualsMatcher} A EqualsMatcher.
    375 */
    376function equals(value) {
    377 return new goog.labs.testing.EqualsMatcher(value);
    378}
    379
    380
    381/**
    382 * Matches a string against a regular expression.
    383 *
    384 * @param {!RegExp} regex The expected regex.
    385 *
    386 * @return {!goog.labs.testing.RegexMatcher} A RegexMatcher.
    387 */
    388function matchesRegex(regex) {
    389 return new goog.labs.testing.RegexMatcher(regex);
    390}
    391
    392
    393/**
    394 * Matches a string that starts with the given string.
    395 *
    396 * @param {string} value The expected value.
    397 *
    398 * @return {!goog.labs.testing.StartsWithMatcher} A
    399 * StartsWithMatcher.
    400 */
    401function startsWith(value) {
    402 return new goog.labs.testing.StartsWithMatcher(value);
    403}
    404
    405
    406/**
    407 * Matches a string that contains the given strings in order.
    408 *
    409 * @param {Array.<string>} values The expected value.
    410 *
    411 * @return {!goog.labs.testing.StringContainsInOrderMatcher} A
    412 * StringContainsInOrderMatcher.
    413 */
    414function stringContainsInOrder(values) {
    415 return new goog.labs.testing.StringContainsInOrderMatcher(values);
    416}
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/labs/useragent/browser.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/useragent/browser.js.src.html new file mode 100644 index 0000000..db262b0 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/useragent/browser.js.src.html @@ -0,0 +1 @@ +browser.js

    lib/goog/labs/useragent/browser.js

    1// Copyright 2013 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Closure user agent detection (Browser).
    17 * @see <a href="http://www.useragentstring.com/">User agent strings</a>
    18 * For more information on rendering engine, platform, or device see the other
    19 * sub-namespaces in goog.labs.userAgent, goog.labs.userAgent.platform,
    20 * goog.labs.userAgent.device respectively.)
    21 *
    22 */
    23
    24goog.provide('goog.labs.userAgent.browser');
    25
    26goog.require('goog.array');
    27goog.require('goog.asserts');
    28goog.require('goog.labs.userAgent.util');
    29goog.require('goog.string');
    30
    31
    32/**
    33 * @return {boolean} Whether the user's browser is Opera.
    34 * @private
    35 */
    36goog.labs.userAgent.browser.matchOpera_ = function() {
    37 return goog.labs.userAgent.util.matchUserAgent('Opera') ||
    38 goog.labs.userAgent.util.matchUserAgent('OPR');
    39};
    40
    41
    42/**
    43 * @return {boolean} Whether the user's browser is IE.
    44 * @private
    45 */
    46goog.labs.userAgent.browser.matchIE_ = function() {
    47 return goog.labs.userAgent.util.matchUserAgent('Trident') ||
    48 goog.labs.userAgent.util.matchUserAgent('MSIE');
    49};
    50
    51
    52/**
    53 * @return {boolean} Whether the user's browser is Firefox.
    54 * @private
    55 */
    56goog.labs.userAgent.browser.matchFirefox_ = function() {
    57 return goog.labs.userAgent.util.matchUserAgent('Firefox');
    58};
    59
    60
    61/**
    62 * @return {boolean} Whether the user's browser is Safari.
    63 * @private
    64 */
    65goog.labs.userAgent.browser.matchSafari_ = function() {
    66 return goog.labs.userAgent.util.matchUserAgent('Safari') &&
    67 !goog.labs.userAgent.util.matchUserAgent('Chrome') &&
    68 !goog.labs.userAgent.util.matchUserAgent('CriOS') &&
    69 !goog.labs.userAgent.util.matchUserAgent('Android');
    70};
    71
    72
    73/**
    74 * @return {boolean} Whether the user's browser is Chrome.
    75 * @private
    76 */
    77goog.labs.userAgent.browser.matchChrome_ = function() {
    78 return goog.labs.userAgent.util.matchUserAgent('Chrome') ||
    79 goog.labs.userAgent.util.matchUserAgent('CriOS');
    80};
    81
    82
    83/**
    84 * @return {boolean} Whether the user's browser is the Android browser.
    85 * @private
    86 */
    87goog.labs.userAgent.browser.matchAndroidBrowser_ = function() {
    88 return goog.labs.userAgent.util.matchUserAgent('Android') &&
    89 !goog.labs.userAgent.util.matchUserAgent('Chrome') &&
    90 !goog.labs.userAgent.util.matchUserAgent('CriOS');
    91};
    92
    93
    94/**
    95 * @return {boolean} Whether the user's browser is Opera.
    96 */
    97goog.labs.userAgent.browser.isOpera = goog.labs.userAgent.browser.matchOpera_;
    98
    99
    100/**
    101 * @return {boolean} Whether the user's browser is IE.
    102 */
    103goog.labs.userAgent.browser.isIE = goog.labs.userAgent.browser.matchIE_;
    104
    105
    106/**
    107 * @return {boolean} Whether the user's browser is Firefox.
    108 */
    109goog.labs.userAgent.browser.isFirefox =
    110 goog.labs.userAgent.browser.matchFirefox_;
    111
    112
    113/**
    114 * @return {boolean} Whether the user's browser is Safari.
    115 */
    116goog.labs.userAgent.browser.isSafari =
    117 goog.labs.userAgent.browser.matchSafari_;
    118
    119
    120/**
    121 * @return {boolean} Whether the user's browser is Chrome.
    122 */
    123goog.labs.userAgent.browser.isChrome =
    124 goog.labs.userAgent.browser.matchChrome_;
    125
    126
    127/**
    128 * @return {boolean} Whether the user's browser is the Android browser.
    129 */
    130goog.labs.userAgent.browser.isAndroidBrowser =
    131 goog.labs.userAgent.browser.matchAndroidBrowser_;
    132
    133
    134/**
    135 * For more information, see:
    136 * http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html
    137 * @return {boolean} Whether the user's browser is Silk.
    138 */
    139goog.labs.userAgent.browser.isSilk = function() {
    140 return goog.labs.userAgent.util.matchUserAgent('Silk');
    141};
    142
    143
    144/**
    145 * @return {string} The browser version or empty string if version cannot be
    146 * determined. Note that for Internet Explorer, this returns the version of
    147 * the browser, not the version of the rendering engine. (IE 8 in
    148 * compatibility mode will return 8.0 rather than 7.0. To determine the
    149 * rendering engine version, look at document.documentMode instead. See
    150 * http://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx for more
    151 * details.)
    152 */
    153goog.labs.userAgent.browser.getVersion = function() {
    154 var userAgentString = goog.labs.userAgent.util.getUserAgent();
    155 // Special case IE since IE's version is inside the parenthesis and
    156 // without the '/'.
    157 if (goog.labs.userAgent.browser.isIE()) {
    158 return goog.labs.userAgent.browser.getIEVersion_(userAgentString);
    159 }
    160
    161 if (goog.labs.userAgent.browser.isOpera()) {
    162 return goog.labs.userAgent.browser.getOperaVersion_(userAgentString);
    163 }
    164
    165 var versionTuples =
    166 goog.labs.userAgent.util.extractVersionTuples(userAgentString);
    167 return goog.labs.userAgent.browser.getVersionFromTuples_(versionTuples);
    168};
    169
    170
    171/**
    172 * @param {string|number} version The version to check.
    173 * @return {boolean} Whether the browser version is higher or the same as the
    174 * given version.
    175 */
    176goog.labs.userAgent.browser.isVersionOrHigher = function(version) {
    177 return goog.string.compareVersions(goog.labs.userAgent.browser.getVersion(),
    178 version) >= 0;
    179};
    180
    181
    182/**
    183 * Determines IE version. More information:
    184 * http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx#uaString
    185 * http://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx
    186 * http://blogs.msdn.com/b/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx
    187 * http://blogs.msdn.com/b/ie/archive/2009/01/09/the-internet-explorer-8-user-agent-string-updated-edition.aspx
    188 *
    189 * @param {string} userAgent the User-Agent.
    190 * @return {string}
    191 * @private
    192 */
    193goog.labs.userAgent.browser.getIEVersion_ = function(userAgent) {
    194 // IE11 may identify itself as MSIE 9.0 or MSIE 10.0 due to an IE 11 upgrade
    195 // bug. Example UA:
    196 // Mozilla/5.0 (MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; rv:11.0)
    197 // like Gecko.
    198 // See http://www.whatismybrowser.com/developers/unknown-user-agent-fragments.
    199 var rv = /rv: *([\d\.]*)/.exec(userAgent);
    200 if (rv && rv[1]) {
    201 return rv[1];
    202 }
    203
    204 var version = '';
    205 var msie = /MSIE +([\d\.]+)/.exec(userAgent);
    206 if (msie && msie[1]) {
    207 // IE in compatibility mode usually identifies itself as MSIE 7.0; in this
    208 // case, use the Trident version to determine the version of IE. For more
    209 // details, see the links above.
    210 var tridentVersion = /Trident\/(\d.\d)/.exec(userAgent);
    211 if (msie[1] == '7.0') {
    212 if (tridentVersion && tridentVersion[1]) {
    213 switch (tridentVersion[1]) {
    214 case '4.0':
    215 version = '8.0';
    216 break;
    217 case '5.0':
    218 version = '9.0';
    219 break;
    220 case '6.0':
    221 version = '10.0';
    222 break;
    223 case '7.0':
    224 version = '11.0';
    225 break;
    226 }
    227 } else {
    228 version = '7.0';
    229 }
    230 } else {
    231 version = msie[1];
    232 }
    233 }
    234 return version;
    235};
    236
    237
    238/**
    239 * Determines Opera version. More information:
    240 * http://my.opera.com/ODIN/blog/2013/07/15/opera-user-agent-strings-opera-15-and-beyond
    241 *
    242 * @param {string} userAgent The User-Agent.
    243 * @return {string}
    244 * @private
    245 */
    246goog.labs.userAgent.browser.getOperaVersion_ = function(userAgent) {
    247 var versionTuples =
    248 goog.labs.userAgent.util.extractVersionTuples(userAgent);
    249 var lastTuple = goog.array.peek(versionTuples);
    250 if (lastTuple[0] == 'OPR' && lastTuple[1]) {
    251 return lastTuple[1];
    252 }
    253
    254 return goog.labs.userAgent.browser.getVersionFromTuples_(versionTuples);
    255};
    256
    257
    258/**
    259 * Nearly all User-Agents start with Mozilla/N.0. This looks at the second tuple
    260 * for the actual browser version number.
    261 * @param {!Array.<!Array.<string>>} versionTuples
    262 * @return {string} The version or empty string if it cannot be determined.
    263 * @private
    264 */
    265goog.labs.userAgent.browser.getVersionFromTuples_ = function(versionTuples) {
    266 // versionTuples[2] (The first X/Y tuple after the parenthesis) contains the
    267 // browser version number.
    268 goog.asserts.assert(versionTuples.length > 2,
    269 'Couldn\'t extract version tuple from user agent string');
    270 return versionTuples[2] && versionTuples[2][1] ? versionTuples[2][1] : '';
    271};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/labs/useragent/engine.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/useragent/engine.js.src.html new file mode 100644 index 0000000..c03eabb --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/useragent/engine.js.src.html @@ -0,0 +1 @@ +engine.js

    lib/goog/labs/useragent/engine.js

    1// Copyright 2013 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Closure user agent detection.
    17 * @see http://en.wikipedia.org/wiki/User_agent
    18 * For more information on browser brand, platform, or device see the other
    19 * sub-namespaces in goog.labs.userAgent (browser, platform, and device).
    20 *
    21 */
    22
    23goog.provide('goog.labs.userAgent.engine');
    24
    25goog.require('goog.array');
    26goog.require('goog.labs.userAgent.util');
    27goog.require('goog.string');
    28
    29
    30/**
    31 * @return {boolean} Whether the rendering engine is Presto.
    32 */
    33goog.labs.userAgent.engine.isPresto = function() {
    34 return goog.labs.userAgent.util.matchUserAgent('Presto');
    35};
    36
    37
    38/**
    39 * @return {boolean} Whether the rendering engine is Trident.
    40 */
    41goog.labs.userAgent.engine.isTrident = function() {
    42 // IE only started including the Trident token in IE8.
    43 return goog.labs.userAgent.util.matchUserAgent('Trident') ||
    44 goog.labs.userAgent.util.matchUserAgent('MSIE');
    45};
    46
    47
    48/**
    49 * @return {boolean} Whether the rendering engine is WebKit.
    50 */
    51goog.labs.userAgent.engine.isWebKit = function() {
    52 return goog.labs.userAgent.util.matchUserAgentIgnoreCase('WebKit');
    53};
    54
    55
    56/**
    57 * @return {boolean} Whether the rendering engine is Gecko.
    58 */
    59goog.labs.userAgent.engine.isGecko = function() {
    60 return goog.labs.userAgent.util.matchUserAgent('Gecko') &&
    61 !goog.labs.userAgent.engine.isWebKit() &&
    62 !goog.labs.userAgent.engine.isTrident();
    63};
    64
    65
    66/**
    67 * @return {string} The rendering engine's version or empty string if version
    68 * can't be determined.
    69 */
    70goog.labs.userAgent.engine.getVersion = function() {
    71 var userAgentString = goog.labs.userAgent.util.getUserAgent();
    72 if (userAgentString) {
    73 var tuples = goog.labs.userAgent.util.extractVersionTuples(
    74 userAgentString);
    75
    76 var engineTuple = tuples[1];
    77 if (engineTuple) {
    78 // In Gecko, the version string is either in the browser info or the
    79 // Firefox version. See Gecko user agent string reference:
    80 // http://goo.gl/mULqa
    81 if (engineTuple[0] == 'Gecko') {
    82 return goog.labs.userAgent.engine.getVersionForKey_(
    83 tuples, 'Firefox');
    84 }
    85
    86 return engineTuple[1];
    87 }
    88
    89 // IE has only one version identifier, and the Trident version is
    90 // specified in the parenthetical.
    91 var browserTuple = tuples[0];
    92 var info;
    93 if (browserTuple && (info = browserTuple[2])) {
    94 var match = /Trident\/([^\s;]+)/.exec(info);
    95 if (match) {
    96 return match[1];
    97 }
    98 }
    99 }
    100 return '';
    101};
    102
    103
    104/**
    105 * @param {string|number} version The version to check.
    106 * @return {boolean} Whether the rendering engine version is higher or the same
    107 * as the given version.
    108 */
    109goog.labs.userAgent.engine.isVersionOrHigher = function(version) {
    110 return goog.string.compareVersions(goog.labs.userAgent.engine.getVersion(),
    111 version) >= 0;
    112};
    113
    114
    115/**
    116 * @param {!Array.<!Array.<string>>} tuples Version tuples.
    117 * @param {string} key The key to look for.
    118 * @return {string} The version string of the given key, if present.
    119 * Otherwise, the empty string.
    120 * @private
    121 */
    122goog.labs.userAgent.engine.getVersionForKey_ = function(tuples, key) {
    123 // TODO(nnaze): Move to util if useful elsewhere.
    124
    125 var pair = goog.array.find(tuples, function(pair) {
    126 return key == pair[0];
    127 });
    128
    129 return pair && pair[1] || '';
    130};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/labs/useragent/util.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/useragent/util.js.src.html new file mode 100644 index 0000000..40bff36 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/labs/useragent/util.js.src.html @@ -0,0 +1 @@ +util.js

    lib/goog/labs/useragent/util.js

    1// Copyright 2013 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Utilities used by goog.labs.userAgent tools. These functions
    17 * should not be used outside of goog.labs.userAgent.*.
    18 *
    19 * @visibility {//closure/goog/bin/sizetests:__pkg__}
    20 * @visibility {//closure/goog/dom:__subpackages__}
    21 * @visibility {//closure/goog/style:__pkg__}
    22 * @visibility {//closure/goog/testing:__pkg__}
    23 * @visibility {//closure/goog/useragent:__subpackages__}
    24 * @visibility {//testing/puppet/modules:__pkg__} *
    25 *
    26 * @author nnaze@google.com (Nathan Naze)
    27 */
    28
    29goog.provide('goog.labs.userAgent.util');
    30
    31goog.require('goog.string');
    32
    33
    34/**
    35 * Gets the native userAgent string from navigator if it exists.
    36 * If navigator or navigator.userAgent string is missing, returns an empty
    37 * string.
    38 * @return {string}
    39 * @private
    40 */
    41goog.labs.userAgent.util.getNativeUserAgentString_ = function() {
    42 var navigator = goog.labs.userAgent.util.getNavigator_();
    43 if (navigator) {
    44 var userAgent = navigator.userAgent;
    45 if (userAgent) {
    46 return userAgent;
    47 }
    48 }
    49 return '';
    50};
    51
    52
    53/**
    54 * Getter for the native navigator.
    55 * This is a separate function so it can be stubbed out in testing.
    56 * @return {Navigator}
    57 * @private
    58 */
    59goog.labs.userAgent.util.getNavigator_ = function() {
    60 return goog.global.navigator;
    61};
    62
    63
    64/**
    65 * A possible override for applications which wish to not check
    66 * navigator.userAgent but use a specified value for detection instead.
    67 * @private {string}
    68 */
    69goog.labs.userAgent.util.userAgent_ =
    70 goog.labs.userAgent.util.getNativeUserAgentString_();
    71
    72
    73/**
    74 * Applications may override browser detection on the built in
    75 * navigator.userAgent object by setting this string. Set to null to use the
    76 * browser object instead.
    77 * @param {?string=} opt_userAgent The User-Agent override.
    78 */
    79goog.labs.userAgent.util.setUserAgent = function(opt_userAgent) {
    80 goog.labs.userAgent.util.userAgent_ = opt_userAgent ||
    81 goog.labs.userAgent.util.getNativeUserAgentString_();
    82};
    83
    84
    85/**
    86 * @return {string} The user agent string.
    87 */
    88goog.labs.userAgent.util.getUserAgent = function() {
    89 return goog.labs.userAgent.util.userAgent_;
    90};
    91
    92
    93/**
    94 * @param {string} str
    95 * @return {boolean} Whether the user agent contains the given string, ignoring
    96 * case.
    97 */
    98goog.labs.userAgent.util.matchUserAgent = function(str) {
    99 var userAgent = goog.labs.userAgent.util.getUserAgent();
    100 return goog.string.contains(userAgent, str);
    101};
    102
    103
    104/**
    105 * @param {string} str
    106 * @return {boolean} Whether the user agent contains the given string.
    107 */
    108goog.labs.userAgent.util.matchUserAgentIgnoreCase = function(str) {
    109 var userAgent = goog.labs.userAgent.util.getUserAgent();
    110 return goog.string.caseInsensitiveContains(userAgent, str);
    111};
    112
    113
    114/**
    115 * Parses the user agent into tuples for each section.
    116 * @param {string} userAgent
    117 * @return {!Array.<!Array.<string>>} Tuples of key, version, and the contents
    118 * of the parenthetical.
    119 */
    120goog.labs.userAgent.util.extractVersionTuples = function(userAgent) {
    121 // Matches each section of a user agent string.
    122 // Example UA:
    123 // Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us)
    124 // AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405
    125 // This has three version tuples: Mozilla, AppleWebKit, and Mobile.
    126
    127 var versionRegExp = new RegExp(
    128 // Key. Note that a key may have a space.
    129 // (i.e. 'Mobile Safari' in 'Mobile Safari/5.0')
    130 '(\\w[\\w ]+)' +
    131
    132 '/' + // slash
    133 '([^\\s]+)' + // version (i.e. '5.0b')
    134 '\\s*' + // whitespace
    135 '(?:\\((.*?)\\))?', // parenthetical info. parentheses not matched.
    136 'g');
    137
    138 var data = [];
    139 var match;
    140
    141 // Iterate and collect the version tuples. Each iteration will be the
    142 // next regex match.
    143 while (match = versionRegExp.exec(userAgent)) {
    144 data.push([
    145 match[1], // key
    146 match[2], // value
    147 // || undefined as this is not undefined in IE7 and IE8
    148 match[3] || undefined // info
    149 ]);
    150 }
    151
    152 return data;
    153};
    154
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/math/math.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/math/math.js.src.html new file mode 100644 index 0000000..605957d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/math/math.js.src.html @@ -0,0 +1 @@ +math.js

    lib/goog/math/math.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Additional mathematical functions.
    17 */
    18
    19goog.provide('goog.math');
    20
    21goog.require('goog.array');
    22goog.require('goog.asserts');
    23
    24
    25/**
    26 * Returns a random integer greater than or equal to 0 and less than {@code a}.
    27 * @param {number} a The upper bound for the random integer (exclusive).
    28 * @return {number} A random integer N such that 0 <= N < a.
    29 */
    30goog.math.randomInt = function(a) {
    31 return Math.floor(Math.random() * a);
    32};
    33
    34
    35/**
    36 * Returns a random number greater than or equal to {@code a} and less than
    37 * {@code b}.
    38 * @param {number} a The lower bound for the random number (inclusive).
    39 * @param {number} b The upper bound for the random number (exclusive).
    40 * @return {number} A random number N such that a <= N < b.
    41 */
    42goog.math.uniformRandom = function(a, b) {
    43 return a + Math.random() * (b - a);
    44};
    45
    46
    47/**
    48 * Takes a number and clamps it to within the provided bounds.
    49 * @param {number} value The input number.
    50 * @param {number} min The minimum value to return.
    51 * @param {number} max The maximum value to return.
    52 * @return {number} The input number if it is within bounds, or the nearest
    53 * number within the bounds.
    54 */
    55goog.math.clamp = function(value, min, max) {
    56 return Math.min(Math.max(value, min), max);
    57};
    58
    59
    60/**
    61 * The % operator in JavaScript returns the remainder of a / b, but differs from
    62 * some other languages in that the result will have the same sign as the
    63 * dividend. For example, -1 % 8 == -1, whereas in some other languages
    64 * (such as Python) the result would be 7. This function emulates the more
    65 * correct modulo behavior, which is useful for certain applications such as
    66 * calculating an offset index in a circular list.
    67 *
    68 * @param {number} a The dividend.
    69 * @param {number} b The divisor.
    70 * @return {number} a % b where the result is between 0 and b (either 0 <= x < b
    71 * or b < x <= 0, depending on the sign of b).
    72 */
    73goog.math.modulo = function(a, b) {
    74 var r = a % b;
    75 // If r and b differ in sign, add b to wrap the result to the correct sign.
    76 return (r * b < 0) ? r + b : r;
    77};
    78
    79
    80/**
    81 * Performs linear interpolation between values a and b. Returns the value
    82 * between a and b proportional to x (when x is between 0 and 1. When x is
    83 * outside this range, the return value is a linear extrapolation).
    84 * @param {number} a A number.
    85 * @param {number} b A number.
    86 * @param {number} x The proportion between a and b.
    87 * @return {number} The interpolated value between a and b.
    88 */
    89goog.math.lerp = function(a, b, x) {
    90 return a + x * (b - a);
    91};
    92
    93
    94/**
    95 * Tests whether the two values are equal to each other, within a certain
    96 * tolerance to adjust for floating point errors.
    97 * @param {number} a A number.
    98 * @param {number} b A number.
    99 * @param {number=} opt_tolerance Optional tolerance range. Defaults
    100 * to 0.000001. If specified, should be greater than 0.
    101 * @return {boolean} Whether {@code a} and {@code b} are nearly equal.
    102 */
    103goog.math.nearlyEquals = function(a, b, opt_tolerance) {
    104 return Math.abs(a - b) <= (opt_tolerance || 0.000001);
    105};
    106
    107
    108// TODO(user): Rename to normalizeAngle, retaining old name as deprecated
    109// alias.
    110/**
    111 * Normalizes an angle to be in range [0-360). Angles outside this range will
    112 * be normalized to be the equivalent angle with that range.
    113 * @param {number} angle Angle in degrees.
    114 * @return {number} Standardized angle.
    115 */
    116goog.math.standardAngle = function(angle) {
    117 return goog.math.modulo(angle, 360);
    118};
    119
    120
    121/**
    122 * Normalizes an angle to be in range [0-2*PI). Angles outside this range will
    123 * be normalized to be the equivalent angle with that range.
    124 * @param {number} angle Angle in radians.
    125 * @return {number} Standardized angle.
    126 */
    127goog.math.standardAngleInRadians = function(angle) {
    128 return goog.math.modulo(angle, 2 * Math.PI);
    129};
    130
    131
    132/**
    133 * Converts degrees to radians.
    134 * @param {number} angleDegrees Angle in degrees.
    135 * @return {number} Angle in radians.
    136 */
    137goog.math.toRadians = function(angleDegrees) {
    138 return angleDegrees * Math.PI / 180;
    139};
    140
    141
    142/**
    143 * Converts radians to degrees.
    144 * @param {number} angleRadians Angle in radians.
    145 * @return {number} Angle in degrees.
    146 */
    147goog.math.toDegrees = function(angleRadians) {
    148 return angleRadians * 180 / Math.PI;
    149};
    150
    151
    152/**
    153 * For a given angle and radius, finds the X portion of the offset.
    154 * @param {number} degrees Angle in degrees (zero points in +X direction).
    155 * @param {number} radius Radius.
    156 * @return {number} The x-distance for the angle and radius.
    157 */
    158goog.math.angleDx = function(degrees, radius) {
    159 return radius * Math.cos(goog.math.toRadians(degrees));
    160};
    161
    162
    163/**
    164 * For a given angle and radius, finds the Y portion of the offset.
    165 * @param {number} degrees Angle in degrees (zero points in +X direction).
    166 * @param {number} radius Radius.
    167 * @return {number} The y-distance for the angle and radius.
    168 */
    169goog.math.angleDy = function(degrees, radius) {
    170 return radius * Math.sin(goog.math.toRadians(degrees));
    171};
    172
    173
    174/**
    175 * Computes the angle between two points (x1,y1) and (x2,y2).
    176 * Angle zero points in the +X direction, 90 degrees points in the +Y
    177 * direction (down) and from there we grow clockwise towards 360 degrees.
    178 * @param {number} x1 x of first point.
    179 * @param {number} y1 y of first point.
    180 * @param {number} x2 x of second point.
    181 * @param {number} y2 y of second point.
    182 * @return {number} Standardized angle in degrees of the vector from
    183 * x1,y1 to x2,y2.
    184 */
    185goog.math.angle = function(x1, y1, x2, y2) {
    186 return goog.math.standardAngle(goog.math.toDegrees(Math.atan2(y2 - y1,
    187 x2 - x1)));
    188};
    189
    190
    191/**
    192 * Computes the difference between startAngle and endAngle (angles in degrees).
    193 * @param {number} startAngle Start angle in degrees.
    194 * @param {number} endAngle End angle in degrees.
    195 * @return {number} The number of degrees that when added to
    196 * startAngle will result in endAngle. Positive numbers mean that the
    197 * direction is clockwise. Negative numbers indicate a counter-clockwise
    198 * direction.
    199 * The shortest route (clockwise vs counter-clockwise) between the angles
    200 * is used.
    201 * When the difference is 180 degrees, the function returns 180 (not -180)
    202 * angleDifference(30, 40) is 10, and angleDifference(40, 30) is -10.
    203 * angleDifference(350, 10) is 20, and angleDifference(10, 350) is -20.
    204 */
    205goog.math.angleDifference = function(startAngle, endAngle) {
    206 var d = goog.math.standardAngle(endAngle) -
    207 goog.math.standardAngle(startAngle);
    208 if (d > 180) {
    209 d = d - 360;
    210 } else if (d <= -180) {
    211 d = 360 + d;
    212 }
    213 return d;
    214};
    215
    216
    217/**
    218 * Returns the sign of a number as per the "sign" or "signum" function.
    219 * @param {number} x The number to take the sign of.
    220 * @return {number} -1 when negative, 1 when positive, 0 when 0.
    221 */
    222goog.math.sign = function(x) {
    223 return x == 0 ? 0 : (x < 0 ? -1 : 1);
    224};
    225
    226
    227/**
    228 * JavaScript implementation of Longest Common Subsequence problem.
    229 * http://en.wikipedia.org/wiki/Longest_common_subsequence
    230 *
    231 * Returns the longest possible array that is subarray of both of given arrays.
    232 *
    233 * @param {Array.<Object>} array1 First array of objects.
    234 * @param {Array.<Object>} array2 Second array of objects.
    235 * @param {Function=} opt_compareFn Function that acts as a custom comparator
    236 * for the array ojects. Function should return true if objects are equal,
    237 * otherwise false.
    238 * @param {Function=} opt_collectorFn Function used to decide what to return
    239 * as a result subsequence. It accepts 2 arguments: index of common element
    240 * in the first array and index in the second. The default function returns
    241 * element from the first array.
    242 * @return {!Array.<Object>} A list of objects that are common to both arrays
    243 * such that there is no common subsequence with size greater than the
    244 * length of the list.
    245 */
    246goog.math.longestCommonSubsequence = function(
    247 array1, array2, opt_compareFn, opt_collectorFn) {
    248
    249 var compare = opt_compareFn || function(a, b) {
    250 return a == b;
    251 };
    252
    253 var collect = opt_collectorFn || function(i1, i2) {
    254 return array1[i1];
    255 };
    256
    257 var length1 = array1.length;
    258 var length2 = array2.length;
    259
    260 var arr = [];
    261 for (var i = 0; i < length1 + 1; i++) {
    262 arr[i] = [];
    263 arr[i][0] = 0;
    264 }
    265
    266 for (var j = 0; j < length2 + 1; j++) {
    267 arr[0][j] = 0;
    268 }
    269
    270 for (i = 1; i <= length1; i++) {
    271 for (j = 1; j <= length2; j++) {
    272 if (compare(array1[i - 1], array2[j - 1])) {
    273 arr[i][j] = arr[i - 1][j - 1] + 1;
    274 } else {
    275 arr[i][j] = Math.max(arr[i - 1][j], arr[i][j - 1]);
    276 }
    277 }
    278 }
    279
    280 // Backtracking
    281 var result = [];
    282 var i = length1, j = length2;
    283 while (i > 0 && j > 0) {
    284 if (compare(array1[i - 1], array2[j - 1])) {
    285 result.unshift(collect(i - 1, j - 1));
    286 i--;
    287 j--;
    288 } else {
    289 if (arr[i - 1][j] > arr[i][j - 1]) {
    290 i--;
    291 } else {
    292 j--;
    293 }
    294 }
    295 }
    296
    297 return result;
    298};
    299
    300
    301/**
    302 * Returns the sum of the arguments.
    303 * @param {...number} var_args Numbers to add.
    304 * @return {number} The sum of the arguments (0 if no arguments were provided,
    305 * {@code NaN} if any of the arguments is not a valid number).
    306 */
    307goog.math.sum = function(var_args) {
    308 return /** @type {number} */ (goog.array.reduce(arguments,
    309 function(sum, value) {
    310 return sum + value;
    311 }, 0));
    312};
    313
    314
    315/**
    316 * Returns the arithmetic mean of the arguments.
    317 * @param {...number} var_args Numbers to average.
    318 * @return {number} The average of the arguments ({@code NaN} if no arguments
    319 * were provided or any of the arguments is not a valid number).
    320 */
    321goog.math.average = function(var_args) {
    322 return goog.math.sum.apply(null, arguments) / arguments.length;
    323};
    324
    325
    326/**
    327 * Returns the unbiased sample variance of the arguments. For a definition,
    328 * see e.g. http://en.wikipedia.org/wiki/Variance
    329 * @param {...number} var_args Number samples to analyze.
    330 * @return {number} The unbiased sample variance of the arguments (0 if fewer
    331 * than two samples were provided, or {@code NaN} if any of the samples is
    332 * not a valid number).
    333 */
    334goog.math.sampleVariance = function(var_args) {
    335 var sampleSize = arguments.length;
    336 if (sampleSize < 2) {
    337 return 0;
    338 }
    339
    340 var mean = goog.math.average.apply(null, arguments);
    341 var variance = goog.math.sum.apply(null, goog.array.map(arguments,
    342 function(val) {
    343 return Math.pow(val - mean, 2);
    344 })) / (sampleSize - 1);
    345
    346 return variance;
    347};
    348
    349
    350/**
    351 * Returns the sample standard deviation of the arguments. For a definition of
    352 * sample standard deviation, see e.g.
    353 * http://en.wikipedia.org/wiki/Standard_deviation
    354 * @param {...number} var_args Number samples to analyze.
    355 * @return {number} The sample standard deviation of the arguments (0 if fewer
    356 * than two samples were provided, or {@code NaN} if any of the samples is
    357 * not a valid number).
    358 */
    359goog.math.standardDeviation = function(var_args) {
    360 return Math.sqrt(goog.math.sampleVariance.apply(null, arguments));
    361};
    362
    363
    364/**
    365 * Returns whether the supplied number represents an integer, i.e. that is has
    366 * no fractional component. No range-checking is performed on the number.
    367 * @param {number} num The number to test.
    368 * @return {boolean} Whether {@code num} is an integer.
    369 */
    370goog.math.isInt = function(num) {
    371 return isFinite(num) && num % 1 == 0;
    372};
    373
    374
    375/**
    376 * Returns whether the supplied number is finite and not NaN.
    377 * @param {number} num The number to test.
    378 * @return {boolean} Whether {@code num} is a finite number.
    379 */
    380goog.math.isFiniteNumber = function(num) {
    381 return isFinite(num) && !isNaN(num);
    382};
    383
    384
    385/**
    386 * Returns the precise value of floor(log10(num)).
    387 * Simpler implementations didn't work because of floating point rounding
    388 * errors. For example
    389 * <ul>
    390 * <li>Math.floor(Math.log(num) / Math.LN10) is off by one for num == 1e+3.
    391 * <li>Math.floor(Math.log(num) * Math.LOG10E) is off by one for num == 1e+15.
    392 * <li>Math.floor(Math.log10(num)) is off by one for num == 1e+15 - 1.
    393 * </ul>
    394 * @param {number} num A floating point number.
    395 * @return {number} Its logarithm to base 10 rounded down to the nearest
    396 * integer if num > 0. -Infinity if num == 0. NaN if num < 0.
    397 */
    398goog.math.log10Floor = function(num) {
    399 if (num > 0) {
    400 var x = Math.round(Math.log(num) * Math.LOG10E);
    401 return x - (parseFloat('1e' + x) > num);
    402 }
    403 return num == 0 ? -Infinity : NaN;
    404};
    405
    406
    407/**
    408 * A tweaked variant of {@code Math.floor} which tolerates if the passed number
    409 * is infinitesimally smaller than the closest integer. It often happens with
    410 * the results of floating point calculations because of the finite precision
    411 * of the intermediate results. For example {@code Math.floor(Math.log(1000) /
    412 * Math.LN10) == 2}, not 3 as one would expect.
    413 * @param {number} num A number.
    414 * @param {number=} opt_epsilon An infinitesimally small positive number, the
    415 * rounding error to tolerate.
    416 * @return {number} The largest integer less than or equal to {@code num}.
    417 */
    418goog.math.safeFloor = function(num, opt_epsilon) {
    419 goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0);
    420 return Math.floor(num + (opt_epsilon || 2e-15));
    421};
    422
    423
    424/**
    425 * A tweaked variant of {@code Math.ceil}. See {@code goog.math.safeFloor} for
    426 * details.
    427 * @param {number} num A number.
    428 * @param {number=} opt_epsilon An infinitesimally small positive number, the
    429 * rounding error to tolerate.
    430 * @return {number} The smallest integer greater than or equal to {@code num}.
    431 */
    432goog.math.safeCeil = function(num, opt_epsilon) {
    433 goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0);
    434 return Math.ceil(num - (opt_epsilon || 2e-15));
    435};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html new file mode 100644 index 0000000..e59447a --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html @@ -0,0 +1 @@ +wrapperxmlhttpfactory.js

    lib/goog/net/wrapperxmlhttpfactory.js

    1// Copyright 2010 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Implementation of XmlHttpFactory which allows construction from
    17 * simple factory methods.
    18 * @author dbk@google.com (David Barrett-Kahn)
    19 */
    20
    21goog.provide('goog.net.WrapperXmlHttpFactory');
    22
    23/** @suppress {extraRequire} Typedef. */
    24goog.require('goog.net.XhrLike');
    25goog.require('goog.net.XmlHttpFactory');
    26
    27
    28
    29/**
    30 * An xhr factory subclass which can be constructed using two factory methods.
    31 * This exists partly to allow the preservation of goog.net.XmlHttp.setFactory()
    32 * with an unchanged signature.
    33 * @param {function():!goog.net.XhrLike.OrNative} xhrFactory
    34 * A function which returns a new XHR object.
    35 * @param {function():!Object} optionsFactory A function which returns the
    36 * options associated with xhr objects from this factory.
    37 * @extends {goog.net.XmlHttpFactory}
    38 * @constructor
    39 * @final
    40 */
    41goog.net.WrapperXmlHttpFactory = function(xhrFactory, optionsFactory) {
    42 goog.net.XmlHttpFactory.call(this);
    43
    44 /**
    45 * XHR factory method.
    46 * @type {function() : !goog.net.XhrLike.OrNative}
    47 * @private
    48 */
    49 this.xhrFactory_ = xhrFactory;
    50
    51 /**
    52 * Options factory method.
    53 * @type {function() : !Object}
    54 * @private
    55 */
    56 this.optionsFactory_ = optionsFactory;
    57};
    58goog.inherits(goog.net.WrapperXmlHttpFactory, goog.net.XmlHttpFactory);
    59
    60
    61/** @override */
    62goog.net.WrapperXmlHttpFactory.prototype.createInstance = function() {
    63 return this.xhrFactory_();
    64};
    65
    66
    67/** @override */
    68goog.net.WrapperXmlHttpFactory.prototype.getOptions = function() {
    69 return this.optionsFactory_();
    70};
    71
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/net/xhrlike.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/net/xhrlike.js.src.html new file mode 100644 index 0000000..09b2494 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/net/xhrlike.js.src.html @@ -0,0 +1 @@ +xhrlike.js

    lib/goog/net/xhrlike.js

    1// Copyright 2013 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15goog.provide('goog.net.XhrLike');
    16
    17
    18
    19/**
    20 * Interface for the common parts of XMLHttpRequest.
    21 *
    22 * Mostly copied from externs/w3c_xml.js.
    23 *
    24 * @interface
    25 * @see http://www.w3.org/TR/XMLHttpRequest/
    26 */
    27goog.net.XhrLike = function() {};
    28
    29
    30/**
    31 * Typedef that refers to either native or custom-implemented XHR objects.
    32 * @typedef {!goog.net.XhrLike|!XMLHttpRequest}
    33 */
    34goog.net.XhrLike.OrNative;
    35
    36
    37/**
    38 * @type {function()|null|undefined}
    39 * @see http://www.w3.org/TR/XMLHttpRequest/#handler-xhr-onreadystatechange
    40 */
    41goog.net.XhrLike.prototype.onreadystatechange;
    42
    43
    44/**
    45 * @type {string}
    46 * @see http://www.w3.org/TR/XMLHttpRequest/#the-responsetext-attribute
    47 */
    48goog.net.XhrLike.prototype.responseText;
    49
    50
    51/**
    52 * @type {Document}
    53 * @see http://www.w3.org/TR/XMLHttpRequest/#the-responsexml-attribute
    54 */
    55goog.net.XhrLike.prototype.responseXML;
    56
    57
    58/**
    59 * @type {number}
    60 * @see http://www.w3.org/TR/XMLHttpRequest/#readystate
    61 */
    62goog.net.XhrLike.prototype.readyState;
    63
    64
    65/**
    66 * @type {number}
    67 * @see http://www.w3.org/TR/XMLHttpRequest/#status
    68 */
    69goog.net.XhrLike.prototype.status;
    70
    71
    72/**
    73 * @type {string}
    74 * @see http://www.w3.org/TR/XMLHttpRequest/#statustext
    75 */
    76goog.net.XhrLike.prototype.statusText;
    77
    78
    79/**
    80 * @param {string} method
    81 * @param {string} url
    82 * @param {?boolean=} opt_async
    83 * @param {?string=} opt_user
    84 * @param {?string=} opt_password
    85 * @see http://www.w3.org/TR/XMLHttpRequest/#the-open()-method
    86 */
    87goog.net.XhrLike.prototype.open = function(method, url, opt_async, opt_user,
    88 opt_password) {};
    89
    90
    91/**
    92 * @param {ArrayBuffer|ArrayBufferView|Blob|Document|FormData|string=} opt_data
    93 * @see http://www.w3.org/TR/XMLHttpRequest/#the-send()-method
    94 */
    95goog.net.XhrLike.prototype.send = function(opt_data) {};
    96
    97
    98/**
    99 * @see http://www.w3.org/TR/XMLHttpRequest/#the-abort()-method
    100 */
    101goog.net.XhrLike.prototype.abort = function() {};
    102
    103
    104/**
    105 * @param {string} header
    106 * @param {string} value
    107 * @see http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method
    108 */
    109goog.net.XhrLike.prototype.setRequestHeader = function(header, value) {};
    110
    111
    112/**
    113 * @param {string} header
    114 * @return {string}
    115 * @see http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
    116 */
    117goog.net.XhrLike.prototype.getResponseHeader = function(header) {};
    118
    119
    120/**
    121 * @return {string}
    122 * @see http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method
    123 */
    124goog.net.XhrLike.prototype.getAllResponseHeaders = function() {};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/net/xmlhttp.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/net/xmlhttp.js.src.html new file mode 100644 index 0000000..2388c37 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/net/xmlhttp.js.src.html @@ -0,0 +1 @@ +xmlhttp.js

    lib/goog/net/xmlhttp.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Low level handling of XMLHttpRequest.
    17 * @author arv@google.com (Erik Arvidsson)
    18 * @author dbk@google.com (David Barrett-Kahn)
    19 */
    20
    21goog.provide('goog.net.DefaultXmlHttpFactory');
    22goog.provide('goog.net.XmlHttp');
    23goog.provide('goog.net.XmlHttp.OptionType');
    24goog.provide('goog.net.XmlHttp.ReadyState');
    25goog.provide('goog.net.XmlHttpDefines');
    26
    27goog.require('goog.asserts');
    28goog.require('goog.net.WrapperXmlHttpFactory');
    29goog.require('goog.net.XmlHttpFactory');
    30
    31
    32/**
    33 * Static class for creating XMLHttpRequest objects.
    34 * @return {!goog.net.XhrLike.OrNative} A new XMLHttpRequest object.
    35 */
    36goog.net.XmlHttp = function() {
    37 return goog.net.XmlHttp.factory_.createInstance();
    38};
    39
    40
    41/**
    42 * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to
    43 * true bypasses the ActiveX probing code.
    44 * NOTE(user): Due to the way JSCompiler works, this define *will not* strip
    45 * out the ActiveX probing code from binaries. To achieve this, use
    46 * {@code goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR} instead.
    47 * TODO(user): Collapse both defines.
    48 */
    49goog.define('goog.net.XmlHttp.ASSUME_NATIVE_XHR', false);
    50
    51
    52/** @const */
    53goog.net.XmlHttpDefines = {};
    54
    55
    56/**
    57 * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to
    58 * true eliminates the ActiveX probing code.
    59 */
    60goog.define('goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR', false);
    61
    62
    63/**
    64 * Gets the options to use with the XMLHttpRequest objects obtained using
    65 * the static methods.
    66 * @return {Object} The options.
    67 */
    68goog.net.XmlHttp.getOptions = function() {
    69 return goog.net.XmlHttp.factory_.getOptions();
    70};
    71
    72
    73/**
    74 * Type of options that an XmlHttp object can have.
    75 * @enum {number}
    76 */
    77goog.net.XmlHttp.OptionType = {
    78 /**
    79 * Whether a goog.nullFunction should be used to clear the onreadystatechange
    80 * handler instead of null.
    81 */
    82 USE_NULL_FUNCTION: 0,
    83
    84 /**
    85 * NOTE(user): In IE if send() errors on a *local* request the readystate
    86 * is still changed to COMPLETE. We need to ignore it and allow the
    87 * try/catch around send() to pick up the error.
    88 */
    89 LOCAL_REQUEST_ERROR: 1
    90};
    91
    92
    93/**
    94 * Status constants for XMLHTTP, matches:
    95 * http://msdn.microsoft.com/library/default.asp?url=/library/
    96 * en-us/xmlsdk/html/0e6a34e4-f90c-489d-acff-cb44242fafc6.asp
    97 * @enum {number}
    98 */
    99goog.net.XmlHttp.ReadyState = {
    100 /**
    101 * Constant for when xmlhttprequest.readyState is uninitialized
    102 */
    103 UNINITIALIZED: 0,
    104
    105 /**
    106 * Constant for when xmlhttprequest.readyState is loading.
    107 */
    108 LOADING: 1,
    109
    110 /**
    111 * Constant for when xmlhttprequest.readyState is loaded.
    112 */
    113 LOADED: 2,
    114
    115 /**
    116 * Constant for when xmlhttprequest.readyState is in an interactive state.
    117 */
    118 INTERACTIVE: 3,
    119
    120 /**
    121 * Constant for when xmlhttprequest.readyState is completed
    122 */
    123 COMPLETE: 4
    124};
    125
    126
    127/**
    128 * The global factory instance for creating XMLHttpRequest objects.
    129 * @type {goog.net.XmlHttpFactory}
    130 * @private
    131 */
    132goog.net.XmlHttp.factory_;
    133
    134
    135/**
    136 * Sets the factories for creating XMLHttpRequest objects and their options.
    137 * @param {Function} factory The factory for XMLHttpRequest objects.
    138 * @param {Function} optionsFactory The factory for options.
    139 * @deprecated Use setGlobalFactory instead.
    140 */
    141goog.net.XmlHttp.setFactory = function(factory, optionsFactory) {
    142 goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory(
    143 goog.asserts.assert(factory),
    144 goog.asserts.assert(optionsFactory)));
    145};
    146
    147
    148/**
    149 * Sets the global factory object.
    150 * @param {!goog.net.XmlHttpFactory} factory New global factory object.
    151 */
    152goog.net.XmlHttp.setGlobalFactory = function(factory) {
    153 goog.net.XmlHttp.factory_ = factory;
    154};
    155
    156
    157
    158/**
    159 * Default factory to use when creating xhr objects. You probably shouldn't be
    160 * instantiating this directly, but rather using it via goog.net.XmlHttp.
    161 * @extends {goog.net.XmlHttpFactory}
    162 * @constructor
    163 */
    164goog.net.DefaultXmlHttpFactory = function() {
    165 goog.net.XmlHttpFactory.call(this);
    166};
    167goog.inherits(goog.net.DefaultXmlHttpFactory, goog.net.XmlHttpFactory);
    168
    169
    170/** @override */
    171goog.net.DefaultXmlHttpFactory.prototype.createInstance = function() {
    172 var progId = this.getProgId_();
    173 if (progId) {
    174 return new ActiveXObject(progId);
    175 } else {
    176 return new XMLHttpRequest();
    177 }
    178};
    179
    180
    181/** @override */
    182goog.net.DefaultXmlHttpFactory.prototype.internalGetOptions = function() {
    183 var progId = this.getProgId_();
    184 var options = {};
    185 if (progId) {
    186 options[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] = true;
    187 options[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] = true;
    188 }
    189 return options;
    190};
    191
    192
    193/**
    194 * The ActiveX PROG ID string to use to create xhr's in IE. Lazily initialized.
    195 * @type {string|undefined}
    196 * @private
    197 */
    198goog.net.DefaultXmlHttpFactory.prototype.ieProgId_;
    199
    200
    201/**
    202 * Initialize the private state used by other functions.
    203 * @return {string} The ActiveX PROG ID string to use to create xhr's in IE.
    204 * @private
    205 */
    206goog.net.DefaultXmlHttpFactory.prototype.getProgId_ = function() {
    207 if (goog.net.XmlHttp.ASSUME_NATIVE_XHR ||
    208 goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR) {
    209 return '';
    210 }
    211
    212 // The following blog post describes what PROG IDs to use to create the
    213 // XMLHTTP object in Internet Explorer:
    214 // http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
    215 // However we do not (yet) fully trust that this will be OK for old versions
    216 // of IE on Win9x so we therefore keep the last 2.
    217 if (!this.ieProgId_ && typeof XMLHttpRequest == 'undefined' &&
    218 typeof ActiveXObject != 'undefined') {
    219 // Candidate Active X types.
    220 var ACTIVE_X_IDENTS = ['MSXML2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.3.0',
    221 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
    222 for (var i = 0; i < ACTIVE_X_IDENTS.length; i++) {
    223 var candidate = ACTIVE_X_IDENTS[i];
    224 /** @preserveTry */
    225 try {
    226 new ActiveXObject(candidate);
    227 // NOTE(user): cannot assign progid and return candidate in one line
    228 // because JSCompiler complaings: BUG 658126
    229 this.ieProgId_ = candidate;
    230 return candidate;
    231 } catch (e) {
    232 // do nothing; try next choice
    233 }
    234 }
    235
    236 // couldn't find any matches
    237 throw Error('Could not create ActiveXObject. ActiveX might be disabled,' +
    238 ' or MSXML might not be installed');
    239 }
    240
    241 return /** @type {string} */ (this.ieProgId_);
    242};
    243
    244
    245//Set the global factory to an instance of the default factory.
    246goog.net.XmlHttp.setGlobalFactory(new goog.net.DefaultXmlHttpFactory());
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/net/xmlhttpfactory.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/net/xmlhttpfactory.js.src.html new file mode 100644 index 0000000..7a261c2 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/net/xmlhttpfactory.js.src.html @@ -0,0 +1 @@ +xmlhttpfactory.js

    lib/goog/net/xmlhttpfactory.js

    1// Copyright 2010 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Interface for a factory for creating XMLHttpRequest objects
    17 * and metadata about them.
    18 * @author dbk@google.com (David Barrett-Kahn)
    19 */
    20
    21goog.provide('goog.net.XmlHttpFactory');
    22
    23/** @suppress {extraRequire} Typedef. */
    24goog.require('goog.net.XhrLike');
    25
    26
    27
    28/**
    29 * Abstract base class for an XmlHttpRequest factory.
    30 * @constructor
    31 */
    32goog.net.XmlHttpFactory = function() {
    33};
    34
    35
    36/**
    37 * Cache of options - we only actually call internalGetOptions once.
    38 * @type {Object}
    39 * @private
    40 */
    41goog.net.XmlHttpFactory.prototype.cachedOptions_ = null;
    42
    43
    44/**
    45 * @return {!goog.net.XhrLike.OrNative} A new XhrLike instance.
    46 */
    47goog.net.XmlHttpFactory.prototype.createInstance = goog.abstractMethod;
    48
    49
    50/**
    51 * @return {Object} Options describing how xhr objects obtained from this
    52 * factory should be used.
    53 */
    54goog.net.XmlHttpFactory.prototype.getOptions = function() {
    55 return this.cachedOptions_ ||
    56 (this.cachedOptions_ = this.internalGetOptions());
    57};
    58
    59
    60/**
    61 * Override this method in subclasses to preserve the caching offered by
    62 * getOptions().
    63 * @return {Object} Options describing how xhr objects obtained from this
    64 * factory should be used.
    65 * @protected
    66 */
    67goog.net.XmlHttpFactory.prototype.internalGetOptions = goog.abstractMethod;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/object/object.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/object/object.js.src.html new file mode 100644 index 0000000..668f1a5 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/object/object.js.src.html @@ -0,0 +1 @@ +object.js

    lib/goog/object/object.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Utilities for manipulating objects/maps/hashes.
    17 */
    18
    19goog.provide('goog.object');
    20
    21
    22/**
    23 * Calls a function for each element in an object/map/hash.
    24 *
    25 * @param {Object.<K,V>} obj The object over which to iterate.
    26 * @param {function(this:T,V,?,Object.<K,V>):?} f The function to call
    27 * for every element. This function takes 3 arguments (the element, the
    28 * index and the object) and the return value is ignored.
    29 * @param {T=} opt_obj This is used as the 'this' object within f.
    30 * @template T,K,V
    31 */
    32goog.object.forEach = function(obj, f, opt_obj) {
    33 for (var key in obj) {
    34 f.call(opt_obj, obj[key], key, obj);
    35 }
    36};
    37
    38
    39/**
    40 * Calls a function for each element in an object/map/hash. If that call returns
    41 * true, adds the element to a new object.
    42 *
    43 * @param {Object.<K,V>} obj The object over which to iterate.
    44 * @param {function(this:T,V,?,Object.<K,V>):boolean} f The function to call
    45 * for every element. This
    46 * function takes 3 arguments (the element, the index and the object)
    47 * and should return a boolean. If the return value is true the
    48 * element is added to the result object. If it is false the
    49 * element is not included.
    50 * @param {T=} opt_obj This is used as the 'this' object within f.
    51 * @return {!Object.<K,V>} a new object in which only elements that passed the
    52 * test are present.
    53 * @template T,K,V
    54 */
    55goog.object.filter = function(obj, f, opt_obj) {
    56 var res = {};
    57 for (var key in obj) {
    58 if (f.call(opt_obj, obj[key], key, obj)) {
    59 res[key] = obj[key];
    60 }
    61 }
    62 return res;
    63};
    64
    65
    66/**
    67 * For every element in an object/map/hash calls a function and inserts the
    68 * result into a new object.
    69 *
    70 * @param {Object.<K,V>} obj The object over which to iterate.
    71 * @param {function(this:T,V,?,Object.<K,V>):R} f The function to call
    72 * for every element. This function
    73 * takes 3 arguments (the element, the index and the object)
    74 * and should return something. The result will be inserted
    75 * into a new object.
    76 * @param {T=} opt_obj This is used as the 'this' object within f.
    77 * @return {!Object.<K,R>} a new object with the results from f.
    78 * @template T,K,V,R
    79 */
    80goog.object.map = function(obj, f, opt_obj) {
    81 var res = {};
    82 for (var key in obj) {
    83 res[key] = f.call(opt_obj, obj[key], key, obj);
    84 }
    85 return res;
    86};
    87
    88
    89/**
    90 * Calls a function for each element in an object/map/hash. If any
    91 * call returns true, returns true (without checking the rest). If
    92 * all calls return false, returns false.
    93 *
    94 * @param {Object.<K,V>} obj The object to check.
    95 * @param {function(this:T,V,?,Object.<K,V>):boolean} f The function to
    96 * call for every element. This function
    97 * takes 3 arguments (the element, the index and the object) and should
    98 * return a boolean.
    99 * @param {T=} opt_obj This is used as the 'this' object within f.
    100 * @return {boolean} true if any element passes the test.
    101 * @template T,K,V
    102 */
    103goog.object.some = function(obj, f, opt_obj) {
    104 for (var key in obj) {
    105 if (f.call(opt_obj, obj[key], key, obj)) {
    106 return true;
    107 }
    108 }
    109 return false;
    110};
    111
    112
    113/**
    114 * Calls a function for each element in an object/map/hash. If
    115 * all calls return true, returns true. If any call returns false, returns
    116 * false at this point and does not continue to check the remaining elements.
    117 *
    118 * @param {Object.<K,V>} obj The object to check.
    119 * @param {?function(this:T,V,?,Object.<K,V>):boolean} f The function to
    120 * call for every element. This function
    121 * takes 3 arguments (the element, the index and the object) and should
    122 * return a boolean.
    123 * @param {T=} opt_obj This is used as the 'this' object within f.
    124 * @return {boolean} false if any element fails the test.
    125 * @template T,K,V
    126 */
    127goog.object.every = function(obj, f, opt_obj) {
    128 for (var key in obj) {
    129 if (!f.call(opt_obj, obj[key], key, obj)) {
    130 return false;
    131 }
    132 }
    133 return true;
    134};
    135
    136
    137/**
    138 * Returns the number of key-value pairs in the object map.
    139 *
    140 * @param {Object} obj The object for which to get the number of key-value
    141 * pairs.
    142 * @return {number} The number of key-value pairs in the object map.
    143 */
    144goog.object.getCount = function(obj) {
    145 // JS1.5 has __count__ but it has been deprecated so it raises a warning...
    146 // in other words do not use. Also __count__ only includes the fields on the
    147 // actual object and not in the prototype chain.
    148 var rv = 0;
    149 for (var key in obj) {
    150 rv++;
    151 }
    152 return rv;
    153};
    154
    155
    156/**
    157 * Returns one key from the object map, if any exists.
    158 * For map literals the returned key will be the first one in most of the
    159 * browsers (a know exception is Konqueror).
    160 *
    161 * @param {Object} obj The object to pick a key from.
    162 * @return {string|undefined} The key or undefined if the object is empty.
    163 */
    164goog.object.getAnyKey = function(obj) {
    165 for (var key in obj) {
    166 return key;
    167 }
    168};
    169
    170
    171/**
    172 * Returns one value from the object map, if any exists.
    173 * For map literals the returned value will be the first one in most of the
    174 * browsers (a know exception is Konqueror).
    175 *
    176 * @param {Object.<K,V>} obj The object to pick a value from.
    177 * @return {V|undefined} The value or undefined if the object is empty.
    178 * @template K,V
    179 */
    180goog.object.getAnyValue = function(obj) {
    181 for (var key in obj) {
    182 return obj[key];
    183 }
    184};
    185
    186
    187/**
    188 * Whether the object/hash/map contains the given object as a value.
    189 * An alias for goog.object.containsValue(obj, val).
    190 *
    191 * @param {Object.<K,V>} obj The object in which to look for val.
    192 * @param {V} val The object for which to check.
    193 * @return {boolean} true if val is present.
    194 * @template K,V
    195 */
    196goog.object.contains = function(obj, val) {
    197 return goog.object.containsValue(obj, val);
    198};
    199
    200
    201/**
    202 * Returns the values of the object/map/hash.
    203 *
    204 * @param {Object.<K,V>} obj The object from which to get the values.
    205 * @return {!Array.<V>} The values in the object/map/hash.
    206 * @template K,V
    207 */
    208goog.object.getValues = function(obj) {
    209 var res = [];
    210 var i = 0;
    211 for (var key in obj) {
    212 res[i++] = obj[key];
    213 }
    214 return res;
    215};
    216
    217
    218/**
    219 * Returns the keys of the object/map/hash.
    220 *
    221 * @param {Object} obj The object from which to get the keys.
    222 * @return {!Array.<string>} Array of property keys.
    223 */
    224goog.object.getKeys = function(obj) {
    225 var res = [];
    226 var i = 0;
    227 for (var key in obj) {
    228 res[i++] = key;
    229 }
    230 return res;
    231};
    232
    233
    234/**
    235 * Get a value from an object multiple levels deep. This is useful for
    236 * pulling values from deeply nested objects, such as JSON responses.
    237 * Example usage: getValueByKeys(jsonObj, 'foo', 'entries', 3)
    238 *
    239 * @param {!Object} obj An object to get the value from. Can be array-like.
    240 * @param {...(string|number|!Array.<number|string>)} var_args A number of keys
    241 * (as strings, or numbers, for array-like objects). Can also be
    242 * specified as a single array of keys.
    243 * @return {*} The resulting value. If, at any point, the value for a key
    244 * is undefined, returns undefined.
    245 */
    246goog.object.getValueByKeys = function(obj, var_args) {
    247 var isArrayLike = goog.isArrayLike(var_args);
    248 var keys = isArrayLike ? var_args : arguments;
    249
    250 // Start with the 2nd parameter for the variable parameters syntax.
    251 for (var i = isArrayLike ? 0 : 1; i < keys.length; i++) {
    252 obj = obj[keys[i]];
    253 if (!goog.isDef(obj)) {
    254 break;
    255 }
    256 }
    257
    258 return obj;
    259};
    260
    261
    262/**
    263 * Whether the object/map/hash contains the given key.
    264 *
    265 * @param {Object} obj The object in which to look for key.
    266 * @param {*} key The key for which to check.
    267 * @return {boolean} true If the map contains the key.
    268 */
    269goog.object.containsKey = function(obj, key) {
    270 return key in obj;
    271};
    272
    273
    274/**
    275 * Whether the object/map/hash contains the given value. This is O(n).
    276 *
    277 * @param {Object.<K,V>} obj The object in which to look for val.
    278 * @param {V} val The value for which to check.
    279 * @return {boolean} true If the map contains the value.
    280 * @template K,V
    281 */
    282goog.object.containsValue = function(obj, val) {
    283 for (var key in obj) {
    284 if (obj[key] == val) {
    285 return true;
    286 }
    287 }
    288 return false;
    289};
    290
    291
    292/**
    293 * Searches an object for an element that satisfies the given condition and
    294 * returns its key.
    295 * @param {Object.<K,V>} obj The object to search in.
    296 * @param {function(this:T,V,string,Object.<K,V>):boolean} f The
    297 * function to call for every element. Takes 3 arguments (the value,
    298 * the key and the object) and should return a boolean.
    299 * @param {T=} opt_this An optional "this" context for the function.
    300 * @return {string|undefined} The key of an element for which the function
    301 * returns true or undefined if no such element is found.
    302 * @template T,K,V
    303 */
    304goog.object.findKey = function(obj, f, opt_this) {
    305 for (var key in obj) {
    306 if (f.call(opt_this, obj[key], key, obj)) {
    307 return key;
    308 }
    309 }
    310 return undefined;
    311};
    312
    313
    314/**
    315 * Searches an object for an element that satisfies the given condition and
    316 * returns its value.
    317 * @param {Object.<K,V>} obj The object to search in.
    318 * @param {function(this:T,V,string,Object.<K,V>):boolean} f The function
    319 * to call for every element. Takes 3 arguments (the value, the key
    320 * and the object) and should return a boolean.
    321 * @param {T=} opt_this An optional "this" context for the function.
    322 * @return {V} The value of an element for which the function returns true or
    323 * undefined if no such element is found.
    324 * @template T,K,V
    325 */
    326goog.object.findValue = function(obj, f, opt_this) {
    327 var key = goog.object.findKey(obj, f, opt_this);
    328 return key && obj[key];
    329};
    330
    331
    332/**
    333 * Whether the object/map/hash is empty.
    334 *
    335 * @param {Object} obj The object to test.
    336 * @return {boolean} true if obj is empty.
    337 */
    338goog.object.isEmpty = function(obj) {
    339 for (var key in obj) {
    340 return false;
    341 }
    342 return true;
    343};
    344
    345
    346/**
    347 * Removes all key value pairs from the object/map/hash.
    348 *
    349 * @param {Object} obj The object to clear.
    350 */
    351goog.object.clear = function(obj) {
    352 for (var i in obj) {
    353 delete obj[i];
    354 }
    355};
    356
    357
    358/**
    359 * Removes a key-value pair based on the key.
    360 *
    361 * @param {Object} obj The object from which to remove the key.
    362 * @param {*} key The key to remove.
    363 * @return {boolean} Whether an element was removed.
    364 */
    365goog.object.remove = function(obj, key) {
    366 var rv;
    367 if ((rv = key in obj)) {
    368 delete obj[key];
    369 }
    370 return rv;
    371};
    372
    373
    374/**
    375 * Adds a key-value pair to the object. Throws an exception if the key is
    376 * already in use. Use set if you want to change an existing pair.
    377 *
    378 * @param {Object.<K,V>} obj The object to which to add the key-value pair.
    379 * @param {string} key The key to add.
    380 * @param {V} val The value to add.
    381 * @template K,V
    382 */
    383goog.object.add = function(obj, key, val) {
    384 if (key in obj) {
    385 throw Error('The object already contains the key "' + key + '"');
    386 }
    387 goog.object.set(obj, key, val);
    388};
    389
    390
    391/**
    392 * Returns the value for the given key.
    393 *
    394 * @param {Object.<K,V>} obj The object from which to get the value.
    395 * @param {string} key The key for which to get the value.
    396 * @param {R=} opt_val The value to return if no item is found for the given
    397 * key (default is undefined).
    398 * @return {V|R|undefined} The value for the given key.
    399 * @template K,V,R
    400 */
    401goog.object.get = function(obj, key, opt_val) {
    402 if (key in obj) {
    403 return obj[key];
    404 }
    405 return opt_val;
    406};
    407
    408
    409/**
    410 * Adds a key-value pair to the object/map/hash.
    411 *
    412 * @param {Object.<K,V>} obj The object to which to add the key-value pair.
    413 * @param {string} key The key to add.
    414 * @param {V} value The value to add.
    415 * @template K,V
    416 */
    417goog.object.set = function(obj, key, value) {
    418 obj[key] = value;
    419};
    420
    421
    422/**
    423 * Adds a key-value pair to the object/map/hash if it doesn't exist yet.
    424 *
    425 * @param {Object.<K,V>} obj The object to which to add the key-value pair.
    426 * @param {string} key The key to add.
    427 * @param {V} value The value to add if the key wasn't present.
    428 * @return {V} The value of the entry at the end of the function.
    429 * @template K,V
    430 */
    431goog.object.setIfUndefined = function(obj, key, value) {
    432 return key in obj ? obj[key] : (obj[key] = value);
    433};
    434
    435
    436/**
    437 * Does a flat clone of the object.
    438 *
    439 * @param {Object.<K,V>} obj Object to clone.
    440 * @return {!Object.<K,V>} Clone of the input object.
    441 * @template K,V
    442 */
    443goog.object.clone = function(obj) {
    444 // We cannot use the prototype trick because a lot of methods depend on where
    445 // the actual key is set.
    446
    447 var res = {};
    448 for (var key in obj) {
    449 res[key] = obj[key];
    450 }
    451 return res;
    452 // We could also use goog.mixin but I wanted this to be independent from that.
    453};
    454
    455
    456/**
    457 * Clones a value. The input may be an Object, Array, or basic type. Objects and
    458 * arrays will be cloned recursively.
    459 *
    460 * WARNINGS:
    461 * <code>goog.object.unsafeClone</code> does not detect reference loops. Objects
    462 * that refer to themselves will cause infinite recursion.
    463 *
    464 * <code>goog.object.unsafeClone</code> is unaware of unique identifiers, and
    465 * copies UIDs created by <code>getUid</code> into cloned results.
    466 *
    467 * @param {*} obj The value to clone.
    468 * @return {*} A clone of the input value.
    469 */
    470goog.object.unsafeClone = function(obj) {
    471 var type = goog.typeOf(obj);
    472 if (type == 'object' || type == 'array') {
    473 if (obj.clone) {
    474 return obj.clone();
    475 }
    476 var clone = type == 'array' ? [] : {};
    477 for (var key in obj) {
    478 clone[key] = goog.object.unsafeClone(obj[key]);
    479 }
    480 return clone;
    481 }
    482
    483 return obj;
    484};
    485
    486
    487/**
    488 * Returns a new object in which all the keys and values are interchanged
    489 * (keys become values and values become keys). If multiple keys map to the
    490 * same value, the chosen transposed value is implementation-dependent.
    491 *
    492 * @param {Object} obj The object to transpose.
    493 * @return {!Object} The transposed object.
    494 */
    495goog.object.transpose = function(obj) {
    496 var transposed = {};
    497 for (var key in obj) {
    498 transposed[obj[key]] = key;
    499 }
    500 return transposed;
    501};
    502
    503
    504/**
    505 * The names of the fields that are defined on Object.prototype.
    506 * @type {Array.<string>}
    507 * @private
    508 */
    509goog.object.PROTOTYPE_FIELDS_ = [
    510 'constructor',
    511 'hasOwnProperty',
    512 'isPrototypeOf',
    513 'propertyIsEnumerable',
    514 'toLocaleString',
    515 'toString',
    516 'valueOf'
    517];
    518
    519
    520/**
    521 * Extends an object with another object.
    522 * This operates 'in-place'; it does not create a new Object.
    523 *
    524 * Example:
    525 * var o = {};
    526 * goog.object.extend(o, {a: 0, b: 1});
    527 * o; // {a: 0, b: 1}
    528 * goog.object.extend(o, {b: 2, c: 3});
    529 * o; // {a: 0, b: 2, c: 3}
    530 *
    531 * @param {Object} target The object to modify. Existing properties will be
    532 * overwritten if they are also present in one of the objects in
    533 * {@code var_args}.
    534 * @param {...Object} var_args The objects from which values will be copied.
    535 */
    536goog.object.extend = function(target, var_args) {
    537 var key, source;
    538 for (var i = 1; i < arguments.length; i++) {
    539 source = arguments[i];
    540 for (key in source) {
    541 target[key] = source[key];
    542 }
    543
    544 // For IE the for-in-loop does not contain any properties that are not
    545 // enumerable on the prototype object (for example isPrototypeOf from
    546 // Object.prototype) and it will also not include 'replace' on objects that
    547 // extend String and change 'replace' (not that it is common for anyone to
    548 // extend anything except Object).
    549
    550 for (var j = 0; j < goog.object.PROTOTYPE_FIELDS_.length; j++) {
    551 key = goog.object.PROTOTYPE_FIELDS_[j];
    552 if (Object.prototype.hasOwnProperty.call(source, key)) {
    553 target[key] = source[key];
    554 }
    555 }
    556 }
    557};
    558
    559
    560/**
    561 * Creates a new object built from the key-value pairs provided as arguments.
    562 * @param {...*} var_args If only one argument is provided and it is an array
    563 * then this is used as the arguments, otherwise even arguments are used as
    564 * the property names and odd arguments are used as the property values.
    565 * @return {!Object} The new object.
    566 * @throws {Error} If there are uneven number of arguments or there is only one
    567 * non array argument.
    568 */
    569goog.object.create = function(var_args) {
    570 var argLength = arguments.length;
    571 if (argLength == 1 && goog.isArray(arguments[0])) {
    572 return goog.object.create.apply(null, arguments[0]);
    573 }
    574
    575 if (argLength % 2) {
    576 throw Error('Uneven number of arguments');
    577 }
    578
    579 var rv = {};
    580 for (var i = 0; i < argLength; i += 2) {
    581 rv[arguments[i]] = arguments[i + 1];
    582 }
    583 return rv;
    584};
    585
    586
    587/**
    588 * Creates a new object where the property names come from the arguments but
    589 * the value is always set to true
    590 * @param {...*} var_args If only one argument is provided and it is an array
    591 * then this is used as the arguments, otherwise the arguments are used
    592 * as the property names.
    593 * @return {!Object} The new object.
    594 */
    595goog.object.createSet = function(var_args) {
    596 var argLength = arguments.length;
    597 if (argLength == 1 && goog.isArray(arguments[0])) {
    598 return goog.object.createSet.apply(null, arguments[0]);
    599 }
    600
    601 var rv = {};
    602 for (var i = 0; i < argLength; i++) {
    603 rv[arguments[i]] = true;
    604 }
    605 return rv;
    606};
    607
    608
    609/**
    610 * Creates an immutable view of the underlying object, if the browser
    611 * supports immutable objects.
    612 *
    613 * In default mode, writes to this view will fail silently. In strict mode,
    614 * they will throw an error.
    615 *
    616 * @param {!Object.<K,V>} obj An object.
    617 * @return {!Object.<K,V>} An immutable view of that object, or the
    618 * original object if this browser does not support immutables.
    619 * @template K,V
    620 */
    621goog.object.createImmutableView = function(obj) {
    622 var result = obj;
    623 if (Object.isFrozen && !Object.isFrozen(obj)) {
    624 result = Object.create(obj);
    625 Object.freeze(result);
    626 }
    627 return result;
    628};
    629
    630
    631/**
    632 * @param {!Object} obj An object.
    633 * @return {boolean} Whether this is an immutable view of the object.
    634 */
    635goog.object.isImmutableView = function(obj) {
    636 return !!Object.isFrozen && Object.isFrozen(obj);
    637};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/string/string.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/string/string.js.src.html new file mode 100644 index 0000000..2f743d5 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/string/string.js.src.html @@ -0,0 +1 @@ +string.js

    lib/goog/string/string.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Utilities for string manipulation.
    17 */
    18
    19
    20/**
    21 * Namespace for string utilities
    22 */
    23goog.provide('goog.string');
    24goog.provide('goog.string.Unicode');
    25
    26
    27/**
    28 * @define {boolean} Enables HTML escaping of lowercase letter "e" which helps
    29 * with detection of double-escaping as this letter is frequently used.
    30 */
    31goog.define('goog.string.DETECT_DOUBLE_ESCAPING', false);
    32
    33
    34/**
    35 * Common Unicode string characters.
    36 * @enum {string}
    37 */
    38goog.string.Unicode = {
    39 NBSP: '\xa0'
    40};
    41
    42
    43/**
    44 * Fast prefix-checker.
    45 * @param {string} str The string to check.
    46 * @param {string} prefix A string to look for at the start of {@code str}.
    47 * @return {boolean} True if {@code str} begins with {@code prefix}.
    48 */
    49goog.string.startsWith = function(str, prefix) {
    50 return str.lastIndexOf(prefix, 0) == 0;
    51};
    52
    53
    54/**
    55 * Fast suffix-checker.
    56 * @param {string} str The string to check.
    57 * @param {string} suffix A string to look for at the end of {@code str}.
    58 * @return {boolean} True if {@code str} ends with {@code suffix}.
    59 */
    60goog.string.endsWith = function(str, suffix) {
    61 var l = str.length - suffix.length;
    62 return l >= 0 && str.indexOf(suffix, l) == l;
    63};
    64
    65
    66/**
    67 * Case-insensitive prefix-checker.
    68 * @param {string} str The string to check.
    69 * @param {string} prefix A string to look for at the end of {@code str}.
    70 * @return {boolean} True if {@code str} begins with {@code prefix} (ignoring
    71 * case).
    72 */
    73goog.string.caseInsensitiveStartsWith = function(str, prefix) {
    74 return goog.string.caseInsensitiveCompare(
    75 prefix, str.substr(0, prefix.length)) == 0;
    76};
    77
    78
    79/**
    80 * Case-insensitive suffix-checker.
    81 * @param {string} str The string to check.
    82 * @param {string} suffix A string to look for at the end of {@code str}.
    83 * @return {boolean} True if {@code str} ends with {@code suffix} (ignoring
    84 * case).
    85 */
    86goog.string.caseInsensitiveEndsWith = function(str, suffix) {
    87 return goog.string.caseInsensitiveCompare(
    88 suffix, str.substr(str.length - suffix.length, suffix.length)) == 0;
    89};
    90
    91
    92/**
    93 * Case-insensitive equality checker.
    94 * @param {string} str1 First string to check.
    95 * @param {string} str2 Second string to check.
    96 * @return {boolean} True if {@code str1} and {@code str2} are the same string,
    97 * ignoring case.
    98 */
    99goog.string.caseInsensitiveEquals = function(str1, str2) {
    100 return str1.toLowerCase() == str2.toLowerCase();
    101};
    102
    103
    104/**
    105 * Does simple python-style string substitution.
    106 * subs("foo%s hot%s", "bar", "dog") becomes "foobar hotdog".
    107 * @param {string} str The string containing the pattern.
    108 * @param {...*} var_args The items to substitute into the pattern.
    109 * @return {string} A copy of {@code str} in which each occurrence of
    110 * {@code %s} has been replaced an argument from {@code var_args}.
    111 */
    112goog.string.subs = function(str, var_args) {
    113 var splitParts = str.split('%s');
    114 var returnString = '';
    115
    116 var subsArguments = Array.prototype.slice.call(arguments, 1);
    117 while (subsArguments.length &&
    118 // Replace up to the last split part. We are inserting in the
    119 // positions between split parts.
    120 splitParts.length > 1) {
    121 returnString += splitParts.shift() + subsArguments.shift();
    122 }
    123
    124 return returnString + splitParts.join('%s'); // Join unused '%s'
    125};
    126
    127
    128/**
    129 * Converts multiple whitespace chars (spaces, non-breaking-spaces, new lines
    130 * and tabs) to a single space, and strips leading and trailing whitespace.
    131 * @param {string} str Input string.
    132 * @return {string} A copy of {@code str} with collapsed whitespace.
    133 */
    134goog.string.collapseWhitespace = function(str) {
    135 // Since IE doesn't include non-breaking-space (0xa0) in their \s character
    136 // class (as required by section 7.2 of the ECMAScript spec), we explicitly
    137 // include it in the regexp to enforce consistent cross-browser behavior.
    138 return str.replace(/[\s\xa0]+/g, ' ').replace(/^\s+|\s+$/g, '');
    139};
    140
    141
    142/**
    143 * Checks if a string is empty or contains only whitespaces.
    144 * @param {string} str The string to check.
    145 * @return {boolean} True if {@code str} is empty or whitespace only.
    146 */
    147goog.string.isEmpty = function(str) {
    148 // testing length == 0 first is actually slower in all browsers (about the
    149 // same in Opera).
    150 // Since IE doesn't include non-breaking-space (0xa0) in their \s character
    151 // class (as required by section 7.2 of the ECMAScript spec), we explicitly
    152 // include it in the regexp to enforce consistent cross-browser behavior.
    153 return /^[\s\xa0]*$/.test(str);
    154};
    155
    156
    157/**
    158 * Checks if a string is null, undefined, empty or contains only whitespaces.
    159 * @param {*} str The string to check.
    160 * @return {boolean} True if{@code str} is null, undefined, empty, or
    161 * whitespace only.
    162 */
    163goog.string.isEmptySafe = function(str) {
    164 return goog.string.isEmpty(goog.string.makeSafe(str));
    165};
    166
    167
    168/**
    169 * Checks if a string is all breaking whitespace.
    170 * @param {string} str The string to check.
    171 * @return {boolean} Whether the string is all breaking whitespace.
    172 */
    173goog.string.isBreakingWhitespace = function(str) {
    174 return !/[^\t\n\r ]/.test(str);
    175};
    176
    177
    178/**
    179 * Checks if a string contains all letters.
    180 * @param {string} str string to check.
    181 * @return {boolean} True if {@code str} consists entirely of letters.
    182 */
    183goog.string.isAlpha = function(str) {
    184 return !/[^a-zA-Z]/.test(str);
    185};
    186
    187
    188/**
    189 * Checks if a string contains only numbers.
    190 * @param {*} str string to check. If not a string, it will be
    191 * casted to one.
    192 * @return {boolean} True if {@code str} is numeric.
    193 */
    194goog.string.isNumeric = function(str) {
    195 return !/[^0-9]/.test(str);
    196};
    197
    198
    199/**
    200 * Checks if a string contains only numbers or letters.
    201 * @param {string} str string to check.
    202 * @return {boolean} True if {@code str} is alphanumeric.
    203 */
    204goog.string.isAlphaNumeric = function(str) {
    205 return !/[^a-zA-Z0-9]/.test(str);
    206};
    207
    208
    209/**
    210 * Checks if a character is a space character.
    211 * @param {string} ch Character to check.
    212 * @return {boolean} True if {code ch} is a space.
    213 */
    214goog.string.isSpace = function(ch) {
    215 return ch == ' ';
    216};
    217
    218
    219/**
    220 * Checks if a character is a valid unicode character.
    221 * @param {string} ch Character to check.
    222 * @return {boolean} True if {code ch} is a valid unicode character.
    223 */
    224goog.string.isUnicodeChar = function(ch) {
    225 return ch.length == 1 && ch >= ' ' && ch <= '~' ||
    226 ch >= '\u0080' && ch <= '\uFFFD';
    227};
    228
    229
    230/**
    231 * Takes a string and replaces newlines with a space. Multiple lines are
    232 * replaced with a single space.
    233 * @param {string} str The string from which to strip newlines.
    234 * @return {string} A copy of {@code str} stripped of newlines.
    235 */
    236goog.string.stripNewlines = function(str) {
    237 return str.replace(/(\r\n|\r|\n)+/g, ' ');
    238};
    239
    240
    241/**
    242 * Replaces Windows and Mac new lines with unix style: \r or \r\n with \n.
    243 * @param {string} str The string to in which to canonicalize newlines.
    244 * @return {string} {@code str} A copy of {@code} with canonicalized newlines.
    245 */
    246goog.string.canonicalizeNewlines = function(str) {
    247 return str.replace(/(\r\n|\r|\n)/g, '\n');
    248};
    249
    250
    251/**
    252 * Normalizes whitespace in a string, replacing all whitespace chars with
    253 * a space.
    254 * @param {string} str The string in which to normalize whitespace.
    255 * @return {string} A copy of {@code str} with all whitespace normalized.
    256 */
    257goog.string.normalizeWhitespace = function(str) {
    258 return str.replace(/\xa0|\s/g, ' ');
    259};
    260
    261
    262/**
    263 * Normalizes spaces in a string, replacing all consecutive spaces and tabs
    264 * with a single space. Replaces non-breaking space with a space.
    265 * @param {string} str The string in which to normalize spaces.
    266 * @return {string} A copy of {@code str} with all consecutive spaces and tabs
    267 * replaced with a single space.
    268 */
    269goog.string.normalizeSpaces = function(str) {
    270 return str.replace(/\xa0|[ \t]+/g, ' ');
    271};
    272
    273
    274/**
    275 * Removes the breaking spaces from the left and right of the string and
    276 * collapses the sequences of breaking spaces in the middle into single spaces.
    277 * The original and the result strings render the same way in HTML.
    278 * @param {string} str A string in which to collapse spaces.
    279 * @return {string} Copy of the string with normalized breaking spaces.
    280 */
    281goog.string.collapseBreakingSpaces = function(str) {
    282 return str.replace(/[\t\r\n ]+/g, ' ').replace(
    283 /^[\t\r\n ]+|[\t\r\n ]+$/g, '');
    284};
    285
    286
    287/**
    288 * Trims white spaces to the left and right of a string.
    289 * @param {string} str The string to trim.
    290 * @return {string} A trimmed copy of {@code str}.
    291 */
    292goog.string.trim = function(str) {
    293 // Since IE doesn't include non-breaking-space (0xa0) in their \s character
    294 // class (as required by section 7.2 of the ECMAScript spec), we explicitly
    295 // include it in the regexp to enforce consistent cross-browser behavior.
    296 return str.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
    297};
    298
    299
    300/**
    301 * Trims whitespaces at the left end of a string.
    302 * @param {string} str The string to left trim.
    303 * @return {string} A trimmed copy of {@code str}.
    304 */
    305goog.string.trimLeft = function(str) {
    306 // Since IE doesn't include non-breaking-space (0xa0) in their \s character
    307 // class (as required by section 7.2 of the ECMAScript spec), we explicitly
    308 // include it in the regexp to enforce consistent cross-browser behavior.
    309 return str.replace(/^[\s\xa0]+/, '');
    310};
    311
    312
    313/**
    314 * Trims whitespaces at the right end of a string.
    315 * @param {string} str The string to right trim.
    316 * @return {string} A trimmed copy of {@code str}.
    317 */
    318goog.string.trimRight = function(str) {
    319 // Since IE doesn't include non-breaking-space (0xa0) in their \s character
    320 // class (as required by section 7.2 of the ECMAScript spec), we explicitly
    321 // include it in the regexp to enforce consistent cross-browser behavior.
    322 return str.replace(/[\s\xa0]+$/, '');
    323};
    324
    325
    326/**
    327 * A string comparator that ignores case.
    328 * -1 = str1 less than str2
    329 * 0 = str1 equals str2
    330 * 1 = str1 greater than str2
    331 *
    332 * @param {string} str1 The string to compare.
    333 * @param {string} str2 The string to compare {@code str1} to.
    334 * @return {number} The comparator result, as described above.
    335 */
    336goog.string.caseInsensitiveCompare = function(str1, str2) {
    337 var test1 = String(str1).toLowerCase();
    338 var test2 = String(str2).toLowerCase();
    339
    340 if (test1 < test2) {
    341 return -1;
    342 } else if (test1 == test2) {
    343 return 0;
    344 } else {
    345 return 1;
    346 }
    347};
    348
    349
    350/**
    351 * Regular expression used for splitting a string into substrings of fractional
    352 * numbers, integers, and non-numeric characters.
    353 * @type {RegExp}
    354 * @private
    355 */
    356goog.string.numerateCompareRegExp_ = /(\.\d+)|(\d+)|(\D+)/g;
    357
    358
    359/**
    360 * String comparison function that handles numbers in a way humans might expect.
    361 * Using this function, the string "File 2.jpg" sorts before "File 10.jpg". The
    362 * comparison is mostly case-insensitive, though strings that are identical
    363 * except for case are sorted with the upper-case strings before lower-case.
    364 *
    365 * This comparison function is significantly slower (about 500x) than either
    366 * the default or the case-insensitive compare. It should not be used in
    367 * time-critical code, but should be fast enough to sort several hundred short
    368 * strings (like filenames) with a reasonable delay.
    369 *
    370 * @param {string} str1 The string to compare in a numerically sensitive way.
    371 * @param {string} str2 The string to compare {@code str1} to.
    372 * @return {number} less than 0 if str1 < str2, 0 if str1 == str2, greater than
    373 * 0 if str1 > str2.
    374 */
    375goog.string.numerateCompare = function(str1, str2) {
    376 if (str1 == str2) {
    377 return 0;
    378 }
    379 if (!str1) {
    380 return -1;
    381 }
    382 if (!str2) {
    383 return 1;
    384 }
    385
    386 // Using match to split the entire string ahead of time turns out to be faster
    387 // for most inputs than using RegExp.exec or iterating over each character.
    388 var tokens1 = str1.toLowerCase().match(goog.string.numerateCompareRegExp_);
    389 var tokens2 = str2.toLowerCase().match(goog.string.numerateCompareRegExp_);
    390
    391 var count = Math.min(tokens1.length, tokens2.length);
    392
    393 for (var i = 0; i < count; i++) {
    394 var a = tokens1[i];
    395 var b = tokens2[i];
    396
    397 // Compare pairs of tokens, returning if one token sorts before the other.
    398 if (a != b) {
    399
    400 // Only if both tokens are integers is a special comparison required.
    401 // Decimal numbers are sorted as strings (e.g., '.09' < '.1').
    402 var num1 = parseInt(a, 10);
    403 if (!isNaN(num1)) {
    404 var num2 = parseInt(b, 10);
    405 if (!isNaN(num2) && num1 - num2) {
    406 return num1 - num2;
    407 }
    408 }
    409 return a < b ? -1 : 1;
    410 }
    411 }
    412
    413 // If one string is a substring of the other, the shorter string sorts first.
    414 if (tokens1.length != tokens2.length) {
    415 return tokens1.length - tokens2.length;
    416 }
    417
    418 // The two strings must be equivalent except for case (perfect equality is
    419 // tested at the head of the function.) Revert to default ASCII-betical string
    420 // comparison to stablize the sort.
    421 return str1 < str2 ? -1 : 1;
    422};
    423
    424
    425/**
    426 * URL-encodes a string
    427 * @param {*} str The string to url-encode.
    428 * @return {string} An encoded copy of {@code str} that is safe for urls.
    429 * Note that '#', ':', and other characters used to delimit portions
    430 * of URLs *will* be encoded.
    431 */
    432goog.string.urlEncode = function(str) {
    433 return encodeURIComponent(String(str));
    434};
    435
    436
    437/**
    438 * URL-decodes the string. We need to specially handle '+'s because
    439 * the javascript library doesn't convert them to spaces.
    440 * @param {string} str The string to url decode.
    441 * @return {string} The decoded {@code str}.
    442 */
    443goog.string.urlDecode = function(str) {
    444 return decodeURIComponent(str.replace(/\+/g, ' '));
    445};
    446
    447
    448/**
    449 * Converts \n to <br>s or <br />s.
    450 * @param {string} str The string in which to convert newlines.
    451 * @param {boolean=} opt_xml Whether to use XML compatible tags.
    452 * @return {string} A copy of {@code str} with converted newlines.
    453 */
    454goog.string.newLineToBr = function(str, opt_xml) {
    455 return str.replace(/(\r\n|\r|\n)/g, opt_xml ? '<br />' : '<br>');
    456};
    457
    458
    459/**
    460 * Escapes double quote '"' and single quote '\'' characters in addition to
    461 * '&', '<', and '>' so that a string can be included in an HTML tag attribute
    462 * value within double or single quotes.
    463 *
    464 * It should be noted that > doesn't need to be escaped for the HTML or XML to
    465 * be valid, but it has been decided to escape it for consistency with other
    466 * implementations.
    467 *
    468 * With goog.string.DETECT_DOUBLE_ESCAPING, this function escapes also the
    469 * lowercase letter "e".
    470 *
    471 * NOTE(user):
    472 * HtmlEscape is often called during the generation of large blocks of HTML.
    473 * Using statics for the regular expressions and strings is an optimization
    474 * that can more than half the amount of time IE spends in this function for
    475 * large apps, since strings and regexes both contribute to GC allocations.
    476 *
    477 * Testing for the presence of a character before escaping increases the number
    478 * of function calls, but actually provides a speed increase for the average
    479 * case -- since the average case often doesn't require the escaping of all 4
    480 * characters and indexOf() is much cheaper than replace().
    481 * The worst case does suffer slightly from the additional calls, therefore the
    482 * opt_isLikelyToContainHtmlChars option has been included for situations
    483 * where all 4 HTML entities are very likely to be present and need escaping.
    484 *
    485 * Some benchmarks (times tended to fluctuate +-0.05ms):
    486 * FireFox IE6
    487 * (no chars / average (mix of cases) / all 4 chars)
    488 * no checks 0.13 / 0.22 / 0.22 0.23 / 0.53 / 0.80
    489 * indexOf 0.08 / 0.17 / 0.26 0.22 / 0.54 / 0.84
    490 * indexOf + re test 0.07 / 0.17 / 0.28 0.19 / 0.50 / 0.85
    491 *
    492 * An additional advantage of checking if replace actually needs to be called
    493 * is a reduction in the number of object allocations, so as the size of the
    494 * application grows the difference between the various methods would increase.
    495 *
    496 * @param {string} str string to be escaped.
    497 * @param {boolean=} opt_isLikelyToContainHtmlChars Don't perform a check to see
    498 * if the character needs replacing - use this option if you expect each of
    499 * the characters to appear often. Leave false if you expect few html
    500 * characters to occur in your strings, such as if you are escaping HTML.
    501 * @return {string} An escaped copy of {@code str}.
    502 */
    503goog.string.htmlEscape = function(str, opt_isLikelyToContainHtmlChars) {
    504
    505 if (opt_isLikelyToContainHtmlChars) {
    506 str = str.replace(goog.string.AMP_RE_, '&amp;')
    507 .replace(goog.string.LT_RE_, '&lt;')
    508 .replace(goog.string.GT_RE_, '&gt;')
    509 .replace(goog.string.QUOT_RE_, '&quot;')
    510 .replace(goog.string.SINGLE_QUOTE_RE_, '&#39;')
    511 .replace(goog.string.NULL_RE_, '&#0;');
    512 if (goog.string.DETECT_DOUBLE_ESCAPING) {
    513 str = str.replace(goog.string.E_RE_, '&#101;');
    514 }
    515 return str;
    516
    517 } else {
    518 // quick test helps in the case when there are no chars to replace, in
    519 // worst case this makes barely a difference to the time taken
    520 if (!goog.string.ALL_RE_.test(str)) return str;
    521
    522 // str.indexOf is faster than regex.test in this case
    523 if (str.indexOf('&') != -1) {
    524 str = str.replace(goog.string.AMP_RE_, '&amp;');
    525 }
    526 if (str.indexOf('<') != -1) {
    527 str = str.replace(goog.string.LT_RE_, '&lt;');
    528 }
    529 if (str.indexOf('>') != -1) {
    530 str = str.replace(goog.string.GT_RE_, '&gt;');
    531 }
    532 if (str.indexOf('"') != -1) {
    533 str = str.replace(goog.string.QUOT_RE_, '&quot;');
    534 }
    535 if (str.indexOf('\'') != -1) {
    536 str = str.replace(goog.string.SINGLE_QUOTE_RE_, '&#39;');
    537 }
    538 if (str.indexOf('\x00') != -1) {
    539 str = str.replace(goog.string.NULL_RE_, '&#0;');
    540 }
    541 if (goog.string.DETECT_DOUBLE_ESCAPING && str.indexOf('e') != -1) {
    542 str = str.replace(goog.string.E_RE_, '&#101;');
    543 }
    544 return str;
    545 }
    546};
    547
    548
    549/**
    550 * Regular expression that matches an ampersand, for use in escaping.
    551 * @const {!RegExp}
    552 * @private
    553 */
    554goog.string.AMP_RE_ = /&/g;
    555
    556
    557/**
    558 * Regular expression that matches a less than sign, for use in escaping.
    559 * @const {!RegExp}
    560 * @private
    561 */
    562goog.string.LT_RE_ = /</g;
    563
    564
    565/**
    566 * Regular expression that matches a greater than sign, for use in escaping.
    567 * @const {!RegExp}
    568 * @private
    569 */
    570goog.string.GT_RE_ = />/g;
    571
    572
    573/**
    574 * Regular expression that matches a double quote, for use in escaping.
    575 * @const {!RegExp}
    576 * @private
    577 */
    578goog.string.QUOT_RE_ = /"/g;
    579
    580
    581/**
    582 * Regular expression that matches a single quote, for use in escaping.
    583 * @const {!RegExp}
    584 * @private
    585 */
    586goog.string.SINGLE_QUOTE_RE_ = /'/g;
    587
    588
    589/**
    590 * Regular expression that matches null character, for use in escaping.
    591 * @const {!RegExp}
    592 * @private
    593 */
    594goog.string.NULL_RE_ = /\x00/g;
    595
    596
    597/**
    598 * Regular expression that matches a lowercase letter "e", for use in escaping.
    599 * @const {!RegExp}
    600 * @private
    601 */
    602goog.string.E_RE_ = /e/g;
    603
    604
    605/**
    606 * Regular expression that matches any character that needs to be escaped.
    607 * @const {!RegExp}
    608 * @private
    609 */
    610goog.string.ALL_RE_ = (goog.string.DETECT_DOUBLE_ESCAPING ?
    611 /[\x00&<>"'e]/ :
    612 /[\x00&<>"']/);
    613
    614
    615/**
    616 * Unescapes an HTML string.
    617 *
    618 * @param {string} str The string to unescape.
    619 * @return {string} An unescaped copy of {@code str}.
    620 */
    621goog.string.unescapeEntities = function(str) {
    622 if (goog.string.contains(str, '&')) {
    623 // We are careful not to use a DOM if we do not have one. We use the []
    624 // notation so that the JSCompiler will not complain about these objects and
    625 // fields in the case where we have no DOM.
    626 if ('document' in goog.global) {
    627 return goog.string.unescapeEntitiesUsingDom_(str);
    628 } else {
    629 // Fall back on pure XML entities
    630 return goog.string.unescapePureXmlEntities_(str);
    631 }
    632 }
    633 return str;
    634};
    635
    636
    637/**
    638 * Unescapes a HTML string using the provided document.
    639 *
    640 * @param {string} str The string to unescape.
    641 * @param {!Document} document A document to use in escaping the string.
    642 * @return {string} An unescaped copy of {@code str}.
    643 */
    644goog.string.unescapeEntitiesWithDocument = function(str, document) {
    645 if (goog.string.contains(str, '&')) {
    646 return goog.string.unescapeEntitiesUsingDom_(str, document);
    647 }
    648 return str;
    649};
    650
    651
    652/**
    653 * Unescapes an HTML string using a DOM to resolve non-XML, non-numeric
    654 * entities. This function is XSS-safe and whitespace-preserving.
    655 * @private
    656 * @param {string} str The string to unescape.
    657 * @param {Document=} opt_document An optional document to use for creating
    658 * elements. If this is not specified then the default window.document
    659 * will be used.
    660 * @return {string} The unescaped {@code str} string.
    661 */
    662goog.string.unescapeEntitiesUsingDom_ = function(str, opt_document) {
    663 var seen = {'&amp;': '&', '&lt;': '<', '&gt;': '>', '&quot;': '"'};
    664 var div;
    665 if (opt_document) {
    666 div = opt_document.createElement('div');
    667 } else {
    668 div = goog.global.document.createElement('div');
    669 }
    670 // Match as many valid entity characters as possible. If the actual entity
    671 // happens to be shorter, it will still work as innerHTML will return the
    672 // trailing characters unchanged. Since the entity characters do not include
    673 // open angle bracket, there is no chance of XSS from the innerHTML use.
    674 // Since no whitespace is passed to innerHTML, whitespace is preserved.
    675 return str.replace(goog.string.HTML_ENTITY_PATTERN_, function(s, entity) {
    676 // Check for cached entity.
    677 var value = seen[s];
    678 if (value) {
    679 return value;
    680 }
    681 // Check for numeric entity.
    682 if (entity.charAt(0) == '#') {
    683 // Prefix with 0 so that hex entities (e.g. &#x10) parse as hex numbers.
    684 var n = Number('0' + entity.substr(1));
    685 if (!isNaN(n)) {
    686 value = String.fromCharCode(n);
    687 }
    688 }
    689 // Fall back to innerHTML otherwise.
    690 if (!value) {
    691 // Append a non-entity character to avoid a bug in Webkit that parses
    692 // an invalid entity at the end of innerHTML text as the empty string.
    693 div.innerHTML = s + ' ';
    694 // Then remove the trailing character from the result.
    695 value = div.firstChild.nodeValue.slice(0, -1);
    696 }
    697 // Cache and return.
    698 return seen[s] = value;
    699 });
    700};
    701
    702
    703/**
    704 * Unescapes XML entities.
    705 * @private
    706 * @param {string} str The string to unescape.
    707 * @return {string} An unescaped copy of {@code str}.
    708 */
    709goog.string.unescapePureXmlEntities_ = function(str) {
    710 return str.replace(/&([^;]+);/g, function(s, entity) {
    711 switch (entity) {
    712 case 'amp':
    713 return '&';
    714 case 'lt':
    715 return '<';
    716 case 'gt':
    717 return '>';
    718 case 'quot':
    719 return '"';
    720 default:
    721 if (entity.charAt(0) == '#') {
    722 // Prefix with 0 so that hex entities (e.g. &#x10) parse as hex.
    723 var n = Number('0' + entity.substr(1));
    724 if (!isNaN(n)) {
    725 return String.fromCharCode(n);
    726 }
    727 }
    728 // For invalid entities we just return the entity
    729 return s;
    730 }
    731 });
    732};
    733
    734
    735/**
    736 * Regular expression that matches an HTML entity.
    737 * See also HTML5: Tokenization / Tokenizing character references.
    738 * @private
    739 * @type {!RegExp}
    740 */
    741goog.string.HTML_ENTITY_PATTERN_ = /&([^;\s<&]+);?/g;
    742
    743
    744/**
    745 * Do escaping of whitespace to preserve spatial formatting. We use character
    746 * entity #160 to make it safer for xml.
    747 * @param {string} str The string in which to escape whitespace.
    748 * @param {boolean=} opt_xml Whether to use XML compatible tags.
    749 * @return {string} An escaped copy of {@code str}.
    750 */
    751goog.string.whitespaceEscape = function(str, opt_xml) {
    752 // This doesn't use goog.string.preserveSpaces for backwards compatibility.
    753 return goog.string.newLineToBr(str.replace(/ /g, ' &#160;'), opt_xml);
    754};
    755
    756
    757/**
    758 * Preserve spaces that would be otherwise collapsed in HTML by replacing them
    759 * with non-breaking space Unicode characters.
    760 * @param {string} str The string in which to preserve whitespace.
    761 * @return {string} A copy of {@code str} with preserved whitespace.
    762 */
    763goog.string.preserveSpaces = function(str) {
    764 return str.replace(/(^|[\n ]) /g, '$1' + goog.string.Unicode.NBSP);
    765};
    766
    767
    768/**
    769 * Strip quote characters around a string. The second argument is a string of
    770 * characters to treat as quotes. This can be a single character or a string of
    771 * multiple character and in that case each of those are treated as possible
    772 * quote characters. For example:
    773 *
    774 * <pre>
    775 * goog.string.stripQuotes('"abc"', '"`') --> 'abc'
    776 * goog.string.stripQuotes('`abc`', '"`') --> 'abc'
    777 * </pre>
    778 *
    779 * @param {string} str The string to strip.
    780 * @param {string} quoteChars The quote characters to strip.
    781 * @return {string} A copy of {@code str} without the quotes.
    782 */
    783goog.string.stripQuotes = function(str, quoteChars) {
    784 var length = quoteChars.length;
    785 for (var i = 0; i < length; i++) {
    786 var quoteChar = length == 1 ? quoteChars : quoteChars.charAt(i);
    787 if (str.charAt(0) == quoteChar && str.charAt(str.length - 1) == quoteChar) {
    788 return str.substring(1, str.length - 1);
    789 }
    790 }
    791 return str;
    792};
    793
    794
    795/**
    796 * Truncates a string to a certain length and adds '...' if necessary. The
    797 * length also accounts for the ellipsis, so a maximum length of 10 and a string
    798 * 'Hello World!' produces 'Hello W...'.
    799 * @param {string} str The string to truncate.
    800 * @param {number} chars Max number of characters.
    801 * @param {boolean=} opt_protectEscapedCharacters Whether to protect escaped
    802 * characters from being cut off in the middle.
    803 * @return {string} The truncated {@code str} string.
    804 */
    805goog.string.truncate = function(str, chars, opt_protectEscapedCharacters) {
    806 if (opt_protectEscapedCharacters) {
    807 str = goog.string.unescapeEntities(str);
    808 }
    809
    810 if (str.length > chars) {
    811 str = str.substring(0, chars - 3) + '...';
    812 }
    813
    814 if (opt_protectEscapedCharacters) {
    815 str = goog.string.htmlEscape(str);
    816 }
    817
    818 return str;
    819};
    820
    821
    822/**
    823 * Truncate a string in the middle, adding "..." if necessary,
    824 * and favoring the beginning of the string.
    825 * @param {string} str The string to truncate the middle of.
    826 * @param {number} chars Max number of characters.
    827 * @param {boolean=} opt_protectEscapedCharacters Whether to protect escaped
    828 * characters from being cutoff in the middle.
    829 * @param {number=} opt_trailingChars Optional number of trailing characters to
    830 * leave at the end of the string, instead of truncating as close to the
    831 * middle as possible.
    832 * @return {string} A truncated copy of {@code str}.
    833 */
    834goog.string.truncateMiddle = function(str, chars,
    835 opt_protectEscapedCharacters, opt_trailingChars) {
    836 if (opt_protectEscapedCharacters) {
    837 str = goog.string.unescapeEntities(str);
    838 }
    839
    840 if (opt_trailingChars && str.length > chars) {
    841 if (opt_trailingChars > chars) {
    842 opt_trailingChars = chars;
    843 }
    844 var endPoint = str.length - opt_trailingChars;
    845 var startPoint = chars - opt_trailingChars;
    846 str = str.substring(0, startPoint) + '...' + str.substring(endPoint);
    847 } else if (str.length > chars) {
    848 // Favor the beginning of the string:
    849 var half = Math.floor(chars / 2);
    850 var endPos = str.length - half;
    851 half += chars % 2;
    852 str = str.substring(0, half) + '...' + str.substring(endPos);
    853 }
    854
    855 if (opt_protectEscapedCharacters) {
    856 str = goog.string.htmlEscape(str);
    857 }
    858
    859 return str;
    860};
    861
    862
    863/**
    864 * Special chars that need to be escaped for goog.string.quote.
    865 * @private
    866 * @type {Object}
    867 */
    868goog.string.specialEscapeChars_ = {
    869 '\0': '\\0',
    870 '\b': '\\b',
    871 '\f': '\\f',
    872 '\n': '\\n',
    873 '\r': '\\r',
    874 '\t': '\\t',
    875 '\x0B': '\\x0B', // '\v' is not supported in JScript
    876 '"': '\\"',
    877 '\\': '\\\\'
    878};
    879
    880
    881/**
    882 * Character mappings used internally for goog.string.escapeChar.
    883 * @private
    884 * @type {Object}
    885 */
    886goog.string.jsEscapeCache_ = {
    887 '\'': '\\\''
    888};
    889
    890
    891/**
    892 * Encloses a string in double quotes and escapes characters so that the
    893 * string is a valid JS string.
    894 * @param {string} s The string to quote.
    895 * @return {string} A copy of {@code s} surrounded by double quotes.
    896 */
    897goog.string.quote = function(s) {
    898 s = String(s);
    899 if (s.quote) {
    900 return s.quote();
    901 } else {
    902 var sb = ['"'];
    903 for (var i = 0; i < s.length; i++) {
    904 var ch = s.charAt(i);
    905 var cc = ch.charCodeAt(0);
    906 sb[i + 1] = goog.string.specialEscapeChars_[ch] ||
    907 ((cc > 31 && cc < 127) ? ch : goog.string.escapeChar(ch));
    908 }
    909 sb.push('"');
    910 return sb.join('');
    911 }
    912};
    913
    914
    915/**
    916 * Takes a string and returns the escaped string for that character.
    917 * @param {string} str The string to escape.
    918 * @return {string} An escaped string representing {@code str}.
    919 */
    920goog.string.escapeString = function(str) {
    921 var sb = [];
    922 for (var i = 0; i < str.length; i++) {
    923 sb[i] = goog.string.escapeChar(str.charAt(i));
    924 }
    925 return sb.join('');
    926};
    927
    928
    929/**
    930 * Takes a character and returns the escaped string for that character. For
    931 * example escapeChar(String.fromCharCode(15)) -> "\\x0E".
    932 * @param {string} c The character to escape.
    933 * @return {string} An escaped string representing {@code c}.
    934 */
    935goog.string.escapeChar = function(c) {
    936 if (c in goog.string.jsEscapeCache_) {
    937 return goog.string.jsEscapeCache_[c];
    938 }
    939
    940 if (c in goog.string.specialEscapeChars_) {
    941 return goog.string.jsEscapeCache_[c] = goog.string.specialEscapeChars_[c];
    942 }
    943
    944 var rv = c;
    945 var cc = c.charCodeAt(0);
    946 if (cc > 31 && cc < 127) {
    947 rv = c;
    948 } else {
    949 // tab is 9 but handled above
    950 if (cc < 256) {
    951 rv = '\\x';
    952 if (cc < 16 || cc > 256) {
    953 rv += '0';
    954 }
    955 } else {
    956 rv = '\\u';
    957 if (cc < 4096) { // \u1000
    958 rv += '0';
    959 }
    960 }
    961 rv += cc.toString(16).toUpperCase();
    962 }
    963
    964 return goog.string.jsEscapeCache_[c] = rv;
    965};
    966
    967
    968/**
    969 * Takes a string and creates a map (Object) in which the keys are the
    970 * characters in the string. The value for the key is set to true. You can
    971 * then use goog.object.map or goog.array.map to change the values.
    972 * @param {string} s The string to build the map from.
    973 * @return {!Object} The map of characters used.
    974 */
    975// TODO(arv): It seems like we should have a generic goog.array.toMap. But do
    976// we want a dependency on goog.array in goog.string?
    977goog.string.toMap = function(s) {
    978 var rv = {};
    979 for (var i = 0; i < s.length; i++) {
    980 rv[s.charAt(i)] = true;
    981 }
    982 return rv;
    983};
    984
    985
    986/**
    987 * Determines whether a string contains a substring.
    988 * @param {string} str The string to search.
    989 * @param {string} subString The substring to search for.
    990 * @return {boolean} Whether {@code str} contains {@code subString}.
    991 */
    992goog.string.contains = function(str, subString) {
    993 return str.indexOf(subString) != -1;
    994};
    995
    996
    997/**
    998 * Determines whether a string contains a substring, ignoring case.
    999 * @param {string} str The string to search.
    1000 * @param {string} subString The substring to search for.
    1001 * @return {boolean} Whether {@code str} contains {@code subString}.
    1002 */
    1003goog.string.caseInsensitiveContains = function(str, subString) {
    1004 return goog.string.contains(str.toLowerCase(), subString.toLowerCase());
    1005};
    1006
    1007
    1008/**
    1009 * Returns the non-overlapping occurrences of ss in s.
    1010 * If either s or ss evalutes to false, then returns zero.
    1011 * @param {string} s The string to look in.
    1012 * @param {string} ss The string to look for.
    1013 * @return {number} Number of occurrences of ss in s.
    1014 */
    1015goog.string.countOf = function(s, ss) {
    1016 return s && ss ? s.split(ss).length - 1 : 0;
    1017};
    1018
    1019
    1020/**
    1021 * Removes a substring of a specified length at a specific
    1022 * index in a string.
    1023 * @param {string} s The base string from which to remove.
    1024 * @param {number} index The index at which to remove the substring.
    1025 * @param {number} stringLength The length of the substring to remove.
    1026 * @return {string} A copy of {@code s} with the substring removed or the full
    1027 * string if nothing is removed or the input is invalid.
    1028 */
    1029goog.string.removeAt = function(s, index, stringLength) {
    1030 var resultStr = s;
    1031 // If the index is greater or equal to 0 then remove substring
    1032 if (index >= 0 && index < s.length && stringLength > 0) {
    1033 resultStr = s.substr(0, index) +
    1034 s.substr(index + stringLength, s.length - index - stringLength);
    1035 }
    1036 return resultStr;
    1037};
    1038
    1039
    1040/**
    1041 * Removes the first occurrence of a substring from a string.
    1042 * @param {string} s The base string from which to remove.
    1043 * @param {string} ss The string to remove.
    1044 * @return {string} A copy of {@code s} with {@code ss} removed or the full
    1045 * string if nothing is removed.
    1046 */
    1047goog.string.remove = function(s, ss) {
    1048 var re = new RegExp(goog.string.regExpEscape(ss), '');
    1049 return s.replace(re, '');
    1050};
    1051
    1052
    1053/**
    1054 * Removes all occurrences of a substring from a string.
    1055 * @param {string} s The base string from which to remove.
    1056 * @param {string} ss The string to remove.
    1057 * @return {string} A copy of {@code s} with {@code ss} removed or the full
    1058 * string if nothing is removed.
    1059 */
    1060goog.string.removeAll = function(s, ss) {
    1061 var re = new RegExp(goog.string.regExpEscape(ss), 'g');
    1062 return s.replace(re, '');
    1063};
    1064
    1065
    1066/**
    1067 * Escapes characters in the string that are not safe to use in a RegExp.
    1068 * @param {*} s The string to escape. If not a string, it will be casted
    1069 * to one.
    1070 * @return {string} A RegExp safe, escaped copy of {@code s}.
    1071 */
    1072goog.string.regExpEscape = function(s) {
    1073 return String(s).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1').
    1074 replace(/\x08/g, '\\x08');
    1075};
    1076
    1077
    1078/**
    1079 * Repeats a string n times.
    1080 * @param {string} string The string to repeat.
    1081 * @param {number} length The number of times to repeat.
    1082 * @return {string} A string containing {@code length} repetitions of
    1083 * {@code string}.
    1084 */
    1085goog.string.repeat = function(string, length) {
    1086 return new Array(length + 1).join(string);
    1087};
    1088
    1089
    1090/**
    1091 * Pads number to given length and optionally rounds it to a given precision.
    1092 * For example:
    1093 * <pre>padNumber(1.25, 2, 3) -> '01.250'
    1094 * padNumber(1.25, 2) -> '01.25'
    1095 * padNumber(1.25, 2, 1) -> '01.3'
    1096 * padNumber(1.25, 0) -> '1.25'</pre>
    1097 *
    1098 * @param {number} num The number to pad.
    1099 * @param {number} length The desired length.
    1100 * @param {number=} opt_precision The desired precision.
    1101 * @return {string} {@code num} as a string with the given options.
    1102 */
    1103goog.string.padNumber = function(num, length, opt_precision) {
    1104 var s = goog.isDef(opt_precision) ? num.toFixed(opt_precision) : String(num);
    1105 var index = s.indexOf('.');
    1106 if (index == -1) {
    1107 index = s.length;
    1108 }
    1109 return goog.string.repeat('0', Math.max(0, length - index)) + s;
    1110};
    1111
    1112
    1113/**
    1114 * Returns a string representation of the given object, with
    1115 * null and undefined being returned as the empty string.
    1116 *
    1117 * @param {*} obj The object to convert.
    1118 * @return {string} A string representation of the {@code obj}.
    1119 */
    1120goog.string.makeSafe = function(obj) {
    1121 return obj == null ? '' : String(obj);
    1122};
    1123
    1124
    1125/**
    1126 * Concatenates string expressions. This is useful
    1127 * since some browsers are very inefficient when it comes to using plus to
    1128 * concat strings. Be careful when using null and undefined here since
    1129 * these will not be included in the result. If you need to represent these
    1130 * be sure to cast the argument to a String first.
    1131 * For example:
    1132 * <pre>buildString('a', 'b', 'c', 'd') -> 'abcd'
    1133 * buildString(null, undefined) -> ''
    1134 * </pre>
    1135 * @param {...*} var_args A list of strings to concatenate. If not a string,
    1136 * it will be casted to one.
    1137 * @return {string} The concatenation of {@code var_args}.
    1138 */
    1139goog.string.buildString = function(var_args) {
    1140 return Array.prototype.join.call(arguments, '');
    1141};
    1142
    1143
    1144/**
    1145 * Returns a string with at least 64-bits of randomness.
    1146 *
    1147 * Doesn't trust Javascript's random function entirely. Uses a combination of
    1148 * random and current timestamp, and then encodes the string in base-36 to
    1149 * make it shorter.
    1150 *
    1151 * @return {string} A random string, e.g. sn1s7vb4gcic.
    1152 */
    1153goog.string.getRandomString = function() {
    1154 var x = 2147483648;
    1155 return Math.floor(Math.random() * x).toString(36) +
    1156 Math.abs(Math.floor(Math.random() * x) ^ goog.now()).toString(36);
    1157};
    1158
    1159
    1160/**
    1161 * Compares two version numbers.
    1162 *
    1163 * @param {string|number} version1 Version of first item.
    1164 * @param {string|number} version2 Version of second item.
    1165 *
    1166 * @return {number} 1 if {@code version1} is higher.
    1167 * 0 if arguments are equal.
    1168 * -1 if {@code version2} is higher.
    1169 */
    1170goog.string.compareVersions = function(version1, version2) {
    1171 var order = 0;
    1172 // Trim leading and trailing whitespace and split the versions into
    1173 // subversions.
    1174 var v1Subs = goog.string.trim(String(version1)).split('.');
    1175 var v2Subs = goog.string.trim(String(version2)).split('.');
    1176 var subCount = Math.max(v1Subs.length, v2Subs.length);
    1177
    1178 // Iterate over the subversions, as long as they appear to be equivalent.
    1179 for (var subIdx = 0; order == 0 && subIdx < subCount; subIdx++) {
    1180 var v1Sub = v1Subs[subIdx] || '';
    1181 var v2Sub = v2Subs[subIdx] || '';
    1182
    1183 // Split the subversions into pairs of numbers and qualifiers (like 'b').
    1184 // Two different RegExp objects are needed because they are both using
    1185 // the 'g' flag.
    1186 var v1CompParser = new RegExp('(\\d*)(\\D*)', 'g');
    1187 var v2CompParser = new RegExp('(\\d*)(\\D*)', 'g');
    1188 do {
    1189 var v1Comp = v1CompParser.exec(v1Sub) || ['', '', ''];
    1190 var v2Comp = v2CompParser.exec(v2Sub) || ['', '', ''];
    1191 // Break if there are no more matches.
    1192 if (v1Comp[0].length == 0 && v2Comp[0].length == 0) {
    1193 break;
    1194 }
    1195
    1196 // Parse the numeric part of the subversion. A missing number is
    1197 // equivalent to 0.
    1198 var v1CompNum = v1Comp[1].length == 0 ? 0 : parseInt(v1Comp[1], 10);
    1199 var v2CompNum = v2Comp[1].length == 0 ? 0 : parseInt(v2Comp[1], 10);
    1200
    1201 // Compare the subversion components. The number has the highest
    1202 // precedence. Next, if the numbers are equal, a subversion without any
    1203 // qualifier is always higher than a subversion with any qualifier. Next,
    1204 // the qualifiers are compared as strings.
    1205 order = goog.string.compareElements_(v1CompNum, v2CompNum) ||
    1206 goog.string.compareElements_(v1Comp[2].length == 0,
    1207 v2Comp[2].length == 0) ||
    1208 goog.string.compareElements_(v1Comp[2], v2Comp[2]);
    1209 // Stop as soon as an inequality is discovered.
    1210 } while (order == 0);
    1211 }
    1212
    1213 return order;
    1214};
    1215
    1216
    1217/**
    1218 * Compares elements of a version number.
    1219 *
    1220 * @param {string|number|boolean} left An element from a version number.
    1221 * @param {string|number|boolean} right An element from a version number.
    1222 *
    1223 * @return {number} 1 if {@code left} is higher.
    1224 * 0 if arguments are equal.
    1225 * -1 if {@code right} is higher.
    1226 * @private
    1227 */
    1228goog.string.compareElements_ = function(left, right) {
    1229 if (left < right) {
    1230 return -1;
    1231 } else if (left > right) {
    1232 return 1;
    1233 }
    1234 return 0;
    1235};
    1236
    1237
    1238/**
    1239 * Maximum value of #goog.string.hashCode, exclusive. 2^32.
    1240 * @type {number}
    1241 * @private
    1242 */
    1243goog.string.HASHCODE_MAX_ = 0x100000000;
    1244
    1245
    1246/**
    1247 * String hash function similar to java.lang.String.hashCode().
    1248 * The hash code for a string is computed as
    1249 * s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1],
    1250 * where s[i] is the ith character of the string and n is the length of
    1251 * the string. We mod the result to make it between 0 (inclusive) and 2^32
    1252 * (exclusive).
    1253 * @param {string} str A string.
    1254 * @return {number} Hash value for {@code str}, between 0 (inclusive) and 2^32
    1255 * (exclusive). The empty string returns 0.
    1256 */
    1257goog.string.hashCode = function(str) {
    1258 var result = 0;
    1259 for (var i = 0; i < str.length; ++i) {
    1260 result = 31 * result + str.charCodeAt(i);
    1261 // Normalize to 4 byte range, 0 ... 2^32.
    1262 result %= goog.string.HASHCODE_MAX_;
    1263 }
    1264 return result;
    1265};
    1266
    1267
    1268/**
    1269 * The most recent unique ID. |0 is equivalent to Math.floor in this case.
    1270 * @type {number}
    1271 * @private
    1272 */
    1273goog.string.uniqueStringCounter_ = Math.random() * 0x80000000 | 0;
    1274
    1275
    1276/**
    1277 * Generates and returns a string which is unique in the current document.
    1278 * This is useful, for example, to create unique IDs for DOM elements.
    1279 * @return {string} A unique id.
    1280 */
    1281goog.string.createUniqueString = function() {
    1282 return 'goog_' + goog.string.uniqueStringCounter_++;
    1283};
    1284
    1285
    1286/**
    1287 * Converts the supplied string to a number, which may be Infinity or NaN.
    1288 * This function strips whitespace: (toNumber(' 123') === 123)
    1289 * This function accepts scientific notation: (toNumber('1e1') === 10)
    1290 *
    1291 * This is better than Javascript's built-in conversions because, sadly:
    1292 * (Number(' ') === 0) and (parseFloat('123a') === 123)
    1293 *
    1294 * @param {string} str The string to convert.
    1295 * @return {number} The number the supplied string represents, or NaN.
    1296 */
    1297goog.string.toNumber = function(str) {
    1298 var num = Number(str);
    1299 if (num == 0 && goog.string.isEmpty(str)) {
    1300 return NaN;
    1301 }
    1302 return num;
    1303};
    1304
    1305
    1306/**
    1307 * Returns whether the given string is lower camel case (e.g. "isFooBar").
    1308 *
    1309 * Note that this assumes the string is entirely letters.
    1310 * @see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms
    1311 *
    1312 * @param {string} str String to test.
    1313 * @return {boolean} Whether the string is lower camel case.
    1314 */
    1315goog.string.isLowerCamelCase = function(str) {
    1316 return /^[a-z]+([A-Z][a-z]*)*$/.test(str);
    1317};
    1318
    1319
    1320/**
    1321 * Returns whether the given string is upper camel case (e.g. "FooBarBaz").
    1322 *
    1323 * Note that this assumes the string is entirely letters.
    1324 * @see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms
    1325 *
    1326 * @param {string} str String to test.
    1327 * @return {boolean} Whether the string is upper camel case.
    1328 */
    1329goog.string.isUpperCamelCase = function(str) {
    1330 return /^([A-Z][a-z]*)+$/.test(str);
    1331};
    1332
    1333
    1334/**
    1335 * Converts a string from selector-case to camelCase (e.g. from
    1336 * "multi-part-string" to "multiPartString"), useful for converting
    1337 * CSS selectors and HTML dataset keys to their equivalent JS properties.
    1338 * @param {string} str The string in selector-case form.
    1339 * @return {string} The string in camelCase form.
    1340 */
    1341goog.string.toCamelCase = function(str) {
    1342 return String(str).replace(/\-([a-z])/g, function(all, match) {
    1343 return match.toUpperCase();
    1344 });
    1345};
    1346
    1347
    1348/**
    1349 * Converts a string from camelCase to selector-case (e.g. from
    1350 * "multiPartString" to "multi-part-string"), useful for converting JS
    1351 * style and dataset properties to equivalent CSS selectors and HTML keys.
    1352 * @param {string} str The string in camelCase form.
    1353 * @return {string} The string in selector-case form.
    1354 */
    1355goog.string.toSelectorCase = function(str) {
    1356 return String(str).replace(/([A-Z])/g, '-$1').toLowerCase();
    1357};
    1358
    1359
    1360/**
    1361 * Converts a string into TitleCase. First character of the string is always
    1362 * capitalized in addition to the first letter of every subsequent word.
    1363 * Words are delimited by one or more whitespaces by default. Custom delimiters
    1364 * can optionally be specified to replace the default, which doesn't preserve
    1365 * whitespace delimiters and instead must be explicitly included if needed.
    1366 *
    1367 * Default delimiter => " ":
    1368 * goog.string.toTitleCase('oneTwoThree') => 'OneTwoThree'
    1369 * goog.string.toTitleCase('one two three') => 'One Two Three'
    1370 * goog.string.toTitleCase(' one two ') => ' One Two '
    1371 * goog.string.toTitleCase('one_two_three') => 'One_two_three'
    1372 * goog.string.toTitleCase('one-two-three') => 'One-two-three'
    1373 *
    1374 * Custom delimiter => "_-.":
    1375 * goog.string.toTitleCase('oneTwoThree', '_-.') => 'OneTwoThree'
    1376 * goog.string.toTitleCase('one two three', '_-.') => 'One two three'
    1377 * goog.string.toTitleCase(' one two ', '_-.') => ' one two '
    1378 * goog.string.toTitleCase('one_two_three', '_-.') => 'One_Two_Three'
    1379 * goog.string.toTitleCase('one-two-three', '_-.') => 'One-Two-Three'
    1380 * goog.string.toTitleCase('one...two...three', '_-.') => 'One...Two...Three'
    1381 * goog.string.toTitleCase('one. two. three', '_-.') => 'One. two. three'
    1382 * goog.string.toTitleCase('one-two.three', '_-.') => 'One-Two.Three'
    1383 *
    1384 * @param {string} str String value in camelCase form.
    1385 * @param {string=} opt_delimiters Custom delimiter character set used to
    1386 * distinguish words in the string value. Each character represents a
    1387 * single delimiter. When provided, default whitespace delimiter is
    1388 * overridden and must be explicitly included if needed.
    1389 * @return {string} String value in TitleCase form.
    1390 */
    1391goog.string.toTitleCase = function(str, opt_delimiters) {
    1392 var delimiters = goog.isString(opt_delimiters) ?
    1393 goog.string.regExpEscape(opt_delimiters) : '\\s';
    1394
    1395 // For IE8, we need to prevent using an empty character set. Otherwise,
    1396 // incorrect matching will occur.
    1397 delimiters = delimiters ? '|[' + delimiters + ']+' : '';
    1398
    1399 var regexp = new RegExp('(^' + delimiters + ')([a-z])', 'g');
    1400 return str.replace(regexp, function(all, p1, p2) {
    1401 return p1 + p2.toUpperCase();
    1402 });
    1403};
    1404
    1405
    1406/**
    1407 * Parse a string in decimal or hexidecimal ('0xFFFF') form.
    1408 *
    1409 * To parse a particular radix, please use parseInt(string, radix) directly. See
    1410 * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/parseInt
    1411 *
    1412 * This is a wrapper for the built-in parseInt function that will only parse
    1413 * numbers as base 10 or base 16. Some JS implementations assume strings
    1414 * starting with "0" are intended to be octal. ES3 allowed but discouraged
    1415 * this behavior. ES5 forbids it. This function emulates the ES5 behavior.
    1416 *
    1417 * For more information, see Mozilla JS Reference: http://goo.gl/8RiFj
    1418 *
    1419 * @param {string|number|null|undefined} value The value to be parsed.
    1420 * @return {number} The number, parsed. If the string failed to parse, this
    1421 * will be NaN.
    1422 */
    1423goog.string.parseInt = function(value) {
    1424 // Force finite numbers to strings.
    1425 if (isFinite(value)) {
    1426 value = String(value);
    1427 }
    1428
    1429 if (goog.isString(value)) {
    1430 // If the string starts with '0x' or '-0x', parse as hex.
    1431 return /^\s*-?0x/i.test(value) ?
    1432 parseInt(value, 16) : parseInt(value, 10);
    1433 }
    1434
    1435 return NaN;
    1436};
    1437
    1438
    1439/**
    1440 * Splits a string on a separator a limited number of times.
    1441 *
    1442 * This implementation is more similar to Python or Java, where the limit
    1443 * parameter specifies the maximum number of splits rather than truncating
    1444 * the number of results.
    1445 *
    1446 * See http://docs.python.org/2/library/stdtypes.html#str.split
    1447 * See JavaDoc: http://goo.gl/F2AsY
    1448 * See Mozilla reference: http://goo.gl/dZdZs
    1449 *
    1450 * @param {string} str String to split.
    1451 * @param {string} separator The separator.
    1452 * @param {number} limit The limit to the number of splits. The resulting array
    1453 * will have a maximum length of limit+1. Negative numbers are the same
    1454 * as zero.
    1455 * @return {!Array.<string>} The string, split.
    1456 */
    1457
    1458goog.string.splitLimit = function(str, separator, limit) {
    1459 var parts = str.split(separator);
    1460 var returnVal = [];
    1461
    1462 // Only continue doing this while we haven't hit the limit and we have
    1463 // parts left.
    1464 while (limit > 0 && parts.length) {
    1465 returnVal.push(parts.shift());
    1466 limit--;
    1467 }
    1468
    1469 // If there are remaining parts, append them to the end.
    1470 if (parts.length) {
    1471 returnVal.push(parts.join(separator));
    1472 }
    1473
    1474 return returnVal;
    1475};
    1476
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/structs/map.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/structs/map.js.src.html new file mode 100644 index 0000000..4ad842a --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/structs/map.js.src.html @@ -0,0 +1 @@ +map.js

    lib/goog/structs/map.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Datastructure: Hash Map.
    17 *
    18 * @author arv@google.com (Erik Arvidsson)
    19 * @author jonp@google.com (Jon Perlow) Optimized for IE6
    20 *
    21 * This file contains an implementation of a Map structure. It implements a lot
    22 * of the methods used in goog.structs so those functions work on hashes. This
    23 * is best suited for complex key types. For simple keys such as numbers and
    24 * strings, and where special names like __proto__ are not a concern, consider
    25 * using the lighter-weight utilities in goog.object.
    26 */
    27
    28
    29goog.provide('goog.structs.Map');
    30
    31goog.require('goog.iter.Iterator');
    32goog.require('goog.iter.StopIteration');
    33goog.require('goog.object');
    34
    35
    36
    37/**
    38 * Class for Hash Map datastructure.
    39 * @param {*=} opt_map Map or Object to initialize the map with.
    40 * @param {...*} var_args If 2 or more arguments are present then they
    41 * will be used as key-value pairs.
    42 * @constructor
    43 * @template K, V
    44 */
    45goog.structs.Map = function(opt_map, var_args) {
    46
    47 /**
    48 * Underlying JS object used to implement the map.
    49 * @private {!Object}
    50 */
    51 this.map_ = {};
    52
    53 /**
    54 * An array of keys. This is necessary for two reasons:
    55 * 1. Iterating the keys using for (var key in this.map_) allocates an
    56 * object for every key in IE which is really bad for IE6 GC perf.
    57 * 2. Without a side data structure, we would need to escape all the keys
    58 * as that would be the only way we could tell during iteration if the
    59 * key was an internal key or a property of the object.
    60 *
    61 * This array can contain deleted keys so it's necessary to check the map
    62 * as well to see if the key is still in the map (this doesn't require a
    63 * memory allocation in IE).
    64 * @private {!Array.<string>}
    65 */
    66 this.keys_ = [];
    67
    68 /**
    69 * The number of key value pairs in the map.
    70 * @private {number}
    71 */
    72 this.count_ = 0;
    73
    74 /**
    75 * Version used to detect changes while iterating.
    76 * @private {number}
    77 */
    78 this.version_ = 0;
    79
    80 var argLength = arguments.length;
    81
    82 if (argLength > 1) {
    83 if (argLength % 2) {
    84 throw Error('Uneven number of arguments');
    85 }
    86 for (var i = 0; i < argLength; i += 2) {
    87 this.set(arguments[i], arguments[i + 1]);
    88 }
    89 } else if (opt_map) {
    90 this.addAll(/** @type {Object} */ (opt_map));
    91 }
    92};
    93
    94
    95/**
    96 * @return {number} The number of key-value pairs in the map.
    97 */
    98goog.structs.Map.prototype.getCount = function() {
    99 return this.count_;
    100};
    101
    102
    103/**
    104 * Returns the values of the map.
    105 * @return {!Array.<V>} The values in the map.
    106 */
    107goog.structs.Map.prototype.getValues = function() {
    108 this.cleanupKeysArray_();
    109
    110 var rv = [];
    111 for (var i = 0; i < this.keys_.length; i++) {
    112 var key = this.keys_[i];
    113 rv.push(this.map_[key]);
    114 }
    115 return rv;
    116};
    117
    118
    119/**
    120 * Returns the keys of the map.
    121 * @return {!Array.<string>} Array of string values.
    122 */
    123goog.structs.Map.prototype.getKeys = function() {
    124 this.cleanupKeysArray_();
    125 return /** @type {!Array.<string>} */ (this.keys_.concat());
    126};
    127
    128
    129/**
    130 * Whether the map contains the given key.
    131 * @param {*} key The key to check for.
    132 * @return {boolean} Whether the map contains the key.
    133 */
    134goog.structs.Map.prototype.containsKey = function(key) {
    135 return goog.structs.Map.hasKey_(this.map_, key);
    136};
    137
    138
    139/**
    140 * Whether the map contains the given value. This is O(n).
    141 * @param {V} val The value to check for.
    142 * @return {boolean} Whether the map contains the value.
    143 */
    144goog.structs.Map.prototype.containsValue = function(val) {
    145 for (var i = 0; i < this.keys_.length; i++) {
    146 var key = this.keys_[i];
    147 if (goog.structs.Map.hasKey_(this.map_, key) && this.map_[key] == val) {
    148 return true;
    149 }
    150 }
    151 return false;
    152};
    153
    154
    155/**
    156 * Whether this map is equal to the argument map.
    157 * @param {goog.structs.Map} otherMap The map against which to test equality.
    158 * @param {function(V, V): boolean=} opt_equalityFn Optional equality function
    159 * to test equality of values. If not specified, this will test whether
    160 * the values contained in each map are identical objects.
    161 * @return {boolean} Whether the maps are equal.
    162 */
    163goog.structs.Map.prototype.equals = function(otherMap, opt_equalityFn) {
    164 if (this === otherMap) {
    165 return true;
    166 }
    167
    168 if (this.count_ != otherMap.getCount()) {
    169 return false;
    170 }
    171
    172 var equalityFn = opt_equalityFn || goog.structs.Map.defaultEquals;
    173
    174 this.cleanupKeysArray_();
    175 for (var key, i = 0; key = this.keys_[i]; i++) {
    176 if (!equalityFn(this.get(key), otherMap.get(key))) {
    177 return false;
    178 }
    179 }
    180
    181 return true;
    182};
    183
    184
    185/**
    186 * Default equality test for values.
    187 * @param {*} a The first value.
    188 * @param {*} b The second value.
    189 * @return {boolean} Whether a and b reference the same object.
    190 */
    191goog.structs.Map.defaultEquals = function(a, b) {
    192 return a === b;
    193};
    194
    195
    196/**
    197 * @return {boolean} Whether the map is empty.
    198 */
    199goog.structs.Map.prototype.isEmpty = function() {
    200 return this.count_ == 0;
    201};
    202
    203
    204/**
    205 * Removes all key-value pairs from the map.
    206 */
    207goog.structs.Map.prototype.clear = function() {
    208 this.map_ = {};
    209 this.keys_.length = 0;
    210 this.count_ = 0;
    211 this.version_ = 0;
    212};
    213
    214
    215/**
    216 * Removes a key-value pair based on the key. This is O(logN) amortized due to
    217 * updating the keys array whenever the count becomes half the size of the keys
    218 * in the keys array.
    219 * @param {*} key The key to remove.
    220 * @return {boolean} Whether object was removed.
    221 */
    222goog.structs.Map.prototype.remove = function(key) {
    223 if (goog.structs.Map.hasKey_(this.map_, key)) {
    224 delete this.map_[key];
    225 this.count_--;
    226 this.version_++;
    227
    228 // clean up the keys array if the threshhold is hit
    229 if (this.keys_.length > 2 * this.count_) {
    230 this.cleanupKeysArray_();
    231 }
    232
    233 return true;
    234 }
    235 return false;
    236};
    237
    238
    239/**
    240 * Cleans up the temp keys array by removing entries that are no longer in the
    241 * map.
    242 * @private
    243 */
    244goog.structs.Map.prototype.cleanupKeysArray_ = function() {
    245 if (this.count_ != this.keys_.length) {
    246 // First remove keys that are no longer in the map.
    247 var srcIndex = 0;
    248 var destIndex = 0;
    249 while (srcIndex < this.keys_.length) {
    250 var key = this.keys_[srcIndex];
    251 if (goog.structs.Map.hasKey_(this.map_, key)) {
    252 this.keys_[destIndex++] = key;
    253 }
    254 srcIndex++;
    255 }
    256 this.keys_.length = destIndex;
    257 }
    258
    259 if (this.count_ != this.keys_.length) {
    260 // If the count still isn't correct, that means we have duplicates. This can
    261 // happen when the same key is added and removed multiple times. Now we have
    262 // to allocate one extra Object to remove the duplicates. This could have
    263 // been done in the first pass, but in the common case, we can avoid
    264 // allocating an extra object by only doing this when necessary.
    265 var seen = {};
    266 var srcIndex = 0;
    267 var destIndex = 0;
    268 while (srcIndex < this.keys_.length) {
    269 var key = this.keys_[srcIndex];
    270 if (!(goog.structs.Map.hasKey_(seen, key))) {
    271 this.keys_[destIndex++] = key;
    272 seen[key] = 1;
    273 }
    274 srcIndex++;
    275 }
    276 this.keys_.length = destIndex;
    277 }
    278};
    279
    280
    281/**
    282 * Returns the value for the given key. If the key is not found and the default
    283 * value is not given this will return {@code undefined}.
    284 * @param {*} key The key to get the value for.
    285 * @param {DEFAULT=} opt_val The value to return if no item is found for the
    286 * given key, defaults to undefined.
    287 * @return {V|DEFAULT} The value for the given key.
    288 * @template DEFAULT
    289 */
    290goog.structs.Map.prototype.get = function(key, opt_val) {
    291 if (goog.structs.Map.hasKey_(this.map_, key)) {
    292 return this.map_[key];
    293 }
    294 return opt_val;
    295};
    296
    297
    298/**
    299 * Adds a key-value pair to the map.
    300 * @param {*} key The key.
    301 * @param {V} value The value to add.
    302 * @return {*} Some subclasses return a value.
    303 */
    304goog.structs.Map.prototype.set = function(key, value) {
    305 if (!(goog.structs.Map.hasKey_(this.map_, key))) {
    306 this.count_++;
    307 this.keys_.push(key);
    308 // Only change the version if we add a new key.
    309 this.version_++;
    310 }
    311 this.map_[key] = value;
    312};
    313
    314
    315/**
    316 * Adds multiple key-value pairs from another goog.structs.Map or Object.
    317 * @param {Object} map Object containing the data to add.
    318 */
    319goog.structs.Map.prototype.addAll = function(map) {
    320 var keys, values;
    321 if (map instanceof goog.structs.Map) {
    322 keys = map.getKeys();
    323 values = map.getValues();
    324 } else {
    325 keys = goog.object.getKeys(map);
    326 values = goog.object.getValues(map);
    327 }
    328 // we could use goog.array.forEach here but I don't want to introduce that
    329 // dependency just for this.
    330 for (var i = 0; i < keys.length; i++) {
    331 this.set(keys[i], values[i]);
    332 }
    333};
    334
    335
    336/**
    337 * Calls the given function on each entry in the map.
    338 * @param {function(this:T, V, K, goog.structs.Map.<K,V>)} f
    339 * @param {T=} opt_obj The value of "this" inside f.
    340 * @template T
    341 */
    342goog.structs.Map.prototype.forEach = function(f, opt_obj) {
    343 var keys = this.getKeys();
    344 for (var i = 0; i < keys.length; i++) {
    345 var key = keys[i];
    346 var value = this.get(key);
    347 f.call(opt_obj, value, key, this);
    348 }
    349};
    350
    351
    352/**
    353 * Clones a map and returns a new map.
    354 * @return {!goog.structs.Map} A new map with the same key-value pairs.
    355 */
    356goog.structs.Map.prototype.clone = function() {
    357 return new goog.structs.Map(this);
    358};
    359
    360
    361/**
    362 * Returns a new map in which all the keys and values are interchanged
    363 * (keys become values and values become keys). If multiple keys map to the
    364 * same value, the chosen transposed value is implementation-dependent.
    365 *
    366 * It acts very similarly to {goog.object.transpose(Object)}.
    367 *
    368 * @return {!goog.structs.Map} The transposed map.
    369 */
    370goog.structs.Map.prototype.transpose = function() {
    371 var transposed = new goog.structs.Map();
    372 for (var i = 0; i < this.keys_.length; i++) {
    373 var key = this.keys_[i];
    374 var value = this.map_[key];
    375 transposed.set(value, key);
    376 }
    377
    378 return transposed;
    379};
    380
    381
    382/**
    383 * @return {!Object} Object representation of the map.
    384 */
    385goog.structs.Map.prototype.toObject = function() {
    386 this.cleanupKeysArray_();
    387 var obj = {};
    388 for (var i = 0; i < this.keys_.length; i++) {
    389 var key = this.keys_[i];
    390 obj[key] = this.map_[key];
    391 }
    392 return obj;
    393};
    394
    395
    396/**
    397 * Returns an iterator that iterates over the keys in the map. Removal of keys
    398 * while iterating might have undesired side effects.
    399 * @return {!goog.iter.Iterator} An iterator over the keys in the map.
    400 */
    401goog.structs.Map.prototype.getKeyIterator = function() {
    402 return this.__iterator__(true);
    403};
    404
    405
    406/**
    407 * Returns an iterator that iterates over the values in the map. Removal of
    408 * keys while iterating might have undesired side effects.
    409 * @return {!goog.iter.Iterator} An iterator over the values in the map.
    410 */
    411goog.structs.Map.prototype.getValueIterator = function() {
    412 return this.__iterator__(false);
    413};
    414
    415
    416/**
    417 * Returns an iterator that iterates over the values or the keys in the map.
    418 * This throws an exception if the map was mutated since the iterator was
    419 * created.
    420 * @param {boolean=} opt_keys True to iterate over the keys. False to iterate
    421 * over the values. The default value is false.
    422 * @return {!goog.iter.Iterator} An iterator over the values or keys in the map.
    423 */
    424goog.structs.Map.prototype.__iterator__ = function(opt_keys) {
    425 // Clean up keys to minimize the risk of iterating over dead keys.
    426 this.cleanupKeysArray_();
    427
    428 var i = 0;
    429 var keys = this.keys_;
    430 var map = this.map_;
    431 var version = this.version_;
    432 var selfObj = this;
    433
    434 var newIter = new goog.iter.Iterator;
    435 newIter.next = function() {
    436 while (true) {
    437 if (version != selfObj.version_) {
    438 throw Error('The map has changed since the iterator was created');
    439 }
    440 if (i >= keys.length) {
    441 throw goog.iter.StopIteration;
    442 }
    443 var key = keys[i++];
    444 return opt_keys ? key : map[key];
    445 }
    446 };
    447 return newIter;
    448};
    449
    450
    451/**
    452 * Safe way to test for hasOwnProperty. It even allows testing for
    453 * 'hasOwnProperty'.
    454 * @param {Object} obj The object to test for presence of the given key.
    455 * @param {*} key The key to check for.
    456 * @return {boolean} Whether the object has the key.
    457 * @private
    458 */
    459goog.structs.Map.hasKey_ = function(obj, key) {
    460 return Object.prototype.hasOwnProperty.call(obj, key);
    461};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/structs/structs.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/structs/structs.js.src.html new file mode 100644 index 0000000..57aa493 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/structs/structs.js.src.html @@ -0,0 +1 @@ +structs.js

    lib/goog/structs/structs.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Generics method for collection-like classes and objects.
    17 *
    18 * @author arv@google.com (Erik Arvidsson)
    19 *
    20 * This file contains functions to work with collections. It supports using
    21 * Map, Set, Array and Object and other classes that implement collection-like
    22 * methods.
    23 */
    24
    25
    26goog.provide('goog.structs');
    27
    28goog.require('goog.array');
    29goog.require('goog.object');
    30
    31
    32// We treat an object as a dictionary if it has getKeys or it is an object that
    33// isn't arrayLike.
    34
    35
    36/**
    37 * Returns the number of values in the collection-like object.
    38 * @param {Object} col The collection-like object.
    39 * @return {number} The number of values in the collection-like object.
    40 */
    41goog.structs.getCount = function(col) {
    42 if (typeof col.getCount == 'function') {
    43 return col.getCount();
    44 }
    45 if (goog.isArrayLike(col) || goog.isString(col)) {
    46 return col.length;
    47 }
    48 return goog.object.getCount(col);
    49};
    50
    51
    52/**
    53 * Returns the values of the collection-like object.
    54 * @param {Object} col The collection-like object.
    55 * @return {!Array} The values in the collection-like object.
    56 */
    57goog.structs.getValues = function(col) {
    58 if (typeof col.getValues == 'function') {
    59 return col.getValues();
    60 }
    61 if (goog.isString(col)) {
    62 return col.split('');
    63 }
    64 if (goog.isArrayLike(col)) {
    65 var rv = [];
    66 var l = col.length;
    67 for (var i = 0; i < l; i++) {
    68 rv.push(col[i]);
    69 }
    70 return rv;
    71 }
    72 return goog.object.getValues(col);
    73};
    74
    75
    76/**
    77 * Returns the keys of the collection. Some collections have no notion of
    78 * keys/indexes and this function will return undefined in those cases.
    79 * @param {Object} col The collection-like object.
    80 * @return {!Array|undefined} The keys in the collection.
    81 */
    82goog.structs.getKeys = function(col) {
    83 if (typeof col.getKeys == 'function') {
    84 return col.getKeys();
    85 }
    86 // if we have getValues but no getKeys we know this is a key-less collection
    87 if (typeof col.getValues == 'function') {
    88 return undefined;
    89 }
    90 if (goog.isArrayLike(col) || goog.isString(col)) {
    91 var rv = [];
    92 var l = col.length;
    93 for (var i = 0; i < l; i++) {
    94 rv.push(i);
    95 }
    96 return rv;
    97 }
    98
    99 return goog.object.getKeys(col);
    100};
    101
    102
    103/**
    104 * Whether the collection contains the given value. This is O(n) and uses
    105 * equals (==) to test the existence.
    106 * @param {Object} col The collection-like object.
    107 * @param {*} val The value to check for.
    108 * @return {boolean} True if the map contains the value.
    109 */
    110goog.structs.contains = function(col, val) {
    111 if (typeof col.contains == 'function') {
    112 return col.contains(val);
    113 }
    114 if (typeof col.containsValue == 'function') {
    115 return col.containsValue(val);
    116 }
    117 if (goog.isArrayLike(col) || goog.isString(col)) {
    118 return goog.array.contains(/** @type {Array} */ (col), val);
    119 }
    120 return goog.object.containsValue(col, val);
    121};
    122
    123
    124/**
    125 * Whether the collection is empty.
    126 * @param {Object} col The collection-like object.
    127 * @return {boolean} True if empty.
    128 */
    129goog.structs.isEmpty = function(col) {
    130 if (typeof col.isEmpty == 'function') {
    131 return col.isEmpty();
    132 }
    133
    134 // We do not use goog.string.isEmpty because here we treat the string as
    135 // collection and as such even whitespace matters
    136
    137 if (goog.isArrayLike(col) || goog.isString(col)) {
    138 return goog.array.isEmpty(/** @type {Array} */ (col));
    139 }
    140 return goog.object.isEmpty(col);
    141};
    142
    143
    144/**
    145 * Removes all the elements from the collection.
    146 * @param {Object} col The collection-like object.
    147 */
    148goog.structs.clear = function(col) {
    149 // NOTE(arv): This should not contain strings because strings are immutable
    150 if (typeof col.clear == 'function') {
    151 col.clear();
    152 } else if (goog.isArrayLike(col)) {
    153 goog.array.clear(/** @type {goog.array.ArrayLike} */ (col));
    154 } else {
    155 goog.object.clear(col);
    156 }
    157};
    158
    159
    160/**
    161 * Calls a function for each value in a collection. The function takes
    162 * three arguments; the value, the key and the collection.
    163 *
    164 * NOTE: This will be deprecated soon! Please use a more specific method if
    165 * possible, e.g. goog.array.forEach, goog.object.forEach, etc.
    166 *
    167 * @param {S} col The collection-like object.
    168 * @param {function(this:T,?,?,S):?} f The function to call for every value.
    169 * This function takes
    170 * 3 arguments (the value, the key or undefined if the collection has no
    171 * notion of keys, and the collection) and the return value is irrelevant.
    172 * @param {T=} opt_obj The object to be used as the value of 'this'
    173 * within {@code f}.
    174 * @template T,S
    175 */
    176goog.structs.forEach = function(col, f, opt_obj) {
    177 if (typeof col.forEach == 'function') {
    178 col.forEach(f, opt_obj);
    179 } else if (goog.isArrayLike(col) || goog.isString(col)) {
    180 goog.array.forEach(/** @type {Array} */ (col), f, opt_obj);
    181 } else {
    182 var keys = goog.structs.getKeys(col);
    183 var values = goog.structs.getValues(col);
    184 var l = values.length;
    185 for (var i = 0; i < l; i++) {
    186 f.call(opt_obj, values[i], keys && keys[i], col);
    187 }
    188 }
    189};
    190
    191
    192/**
    193 * Calls a function for every value in the collection. When a call returns true,
    194 * adds the value to a new collection (Array is returned by default).
    195 *
    196 * @param {S} col The collection-like object.
    197 * @param {function(this:T,?,?,S):boolean} f The function to call for every
    198 * value. This function takes
    199 * 3 arguments (the value, the key or undefined if the collection has no
    200 * notion of keys, and the collection) and should return a Boolean. If the
    201 * return value is true the value is added to the result collection. If it
    202 * is false the value is not included.
    203 * @param {T=} opt_obj The object to be used as the value of 'this'
    204 * within {@code f}.
    205 * @return {!Object|!Array} A new collection where the passed values are
    206 * present. If col is a key-less collection an array is returned. If col
    207 * has keys and values a plain old JS object is returned.
    208 * @template T,S
    209 */
    210goog.structs.filter = function(col, f, opt_obj) {
    211 if (typeof col.filter == 'function') {
    212 return col.filter(f, opt_obj);
    213 }
    214 if (goog.isArrayLike(col) || goog.isString(col)) {
    215 return goog.array.filter(/** @type {!Array} */ (col), f, opt_obj);
    216 }
    217
    218 var rv;
    219 var keys = goog.structs.getKeys(col);
    220 var values = goog.structs.getValues(col);
    221 var l = values.length;
    222 if (keys) {
    223 rv = {};
    224 for (var i = 0; i < l; i++) {
    225 if (f.call(opt_obj, values[i], keys[i], col)) {
    226 rv[keys[i]] = values[i];
    227 }
    228 }
    229 } else {
    230 // We should not use goog.array.filter here since we want to make sure that
    231 // the index is undefined as well as make sure that col is passed to the
    232 // function.
    233 rv = [];
    234 for (var i = 0; i < l; i++) {
    235 if (f.call(opt_obj, values[i], undefined, col)) {
    236 rv.push(values[i]);
    237 }
    238 }
    239 }
    240 return rv;
    241};
    242
    243
    244/**
    245 * Calls a function for every value in the collection and adds the result into a
    246 * new collection (defaults to creating a new Array).
    247 *
    248 * @param {S} col The collection-like object.
    249 * @param {function(this:T,?,?,S):V} f The function to call for every value.
    250 * This function takes 3 arguments (the value, the key or undefined if the
    251 * collection has no notion of keys, and the collection) and should return
    252 * something. The result will be used as the value in the new collection.
    253 * @param {T=} opt_obj The object to be used as the value of 'this'
    254 * within {@code f}.
    255 * @return {!Object.<V>|!Array.<V>} A new collection with the new values. If
    256 * col is a key-less collection an array is returned. If col has keys and
    257 * values a plain old JS object is returned.
    258 * @template T,S,V
    259 */
    260goog.structs.map = function(col, f, opt_obj) {
    261 if (typeof col.map == 'function') {
    262 return col.map(f, opt_obj);
    263 }
    264 if (goog.isArrayLike(col) || goog.isString(col)) {
    265 return goog.array.map(/** @type {!Array} */ (col), f, opt_obj);
    266 }
    267
    268 var rv;
    269 var keys = goog.structs.getKeys(col);
    270 var values = goog.structs.getValues(col);
    271 var l = values.length;
    272 if (keys) {
    273 rv = {};
    274 for (var i = 0; i < l; i++) {
    275 rv[keys[i]] = f.call(opt_obj, values[i], keys[i], col);
    276 }
    277 } else {
    278 // We should not use goog.array.map here since we want to make sure that
    279 // the index is undefined as well as make sure that col is passed to the
    280 // function.
    281 rv = [];
    282 for (var i = 0; i < l; i++) {
    283 rv[i] = f.call(opt_obj, values[i], undefined, col);
    284 }
    285 }
    286 return rv;
    287};
    288
    289
    290/**
    291 * Calls f for each value in a collection. If any call returns true this returns
    292 * true (without checking the rest). If all returns false this returns false.
    293 *
    294 * @param {S} col The collection-like object.
    295 * @param {function(this:T,?,?,S):boolean} f The function to call for every
    296 * value. This function takes 3 arguments (the value, the key or undefined
    297 * if the collection has no notion of keys, and the collection) and should
    298 * return a boolean.
    299 * @param {T=} opt_obj The object to be used as the value of 'this'
    300 * within {@code f}.
    301 * @return {boolean} True if any value passes the test.
    302 * @template T,S
    303 */
    304goog.structs.some = function(col, f, opt_obj) {
    305 if (typeof col.some == 'function') {
    306 return col.some(f, opt_obj);
    307 }
    308 if (goog.isArrayLike(col) || goog.isString(col)) {
    309 return goog.array.some(/** @type {!Array} */ (col), f, opt_obj);
    310 }
    311 var keys = goog.structs.getKeys(col);
    312 var values = goog.structs.getValues(col);
    313 var l = values.length;
    314 for (var i = 0; i < l; i++) {
    315 if (f.call(opt_obj, values[i], keys && keys[i], col)) {
    316 return true;
    317 }
    318 }
    319 return false;
    320};
    321
    322
    323/**
    324 * Calls f for each value in a collection. If all calls return true this return
    325 * true this returns true. If any returns false this returns false at this point
    326 * and does not continue to check the remaining values.
    327 *
    328 * @param {S} col The collection-like object.
    329 * @param {function(this:T,?,?,S):boolean} f The function to call for every
    330 * value. This function takes 3 arguments (the value, the key or
    331 * undefined if the collection has no notion of keys, and the collection)
    332 * and should return a boolean.
    333 * @param {T=} opt_obj The object to be used as the value of 'this'
    334 * within {@code f}.
    335 * @return {boolean} True if all key-value pairs pass the test.
    336 * @template T,S
    337 */
    338goog.structs.every = function(col, f, opt_obj) {
    339 if (typeof col.every == 'function') {
    340 return col.every(f, opt_obj);
    341 }
    342 if (goog.isArrayLike(col) || goog.isString(col)) {
    343 return goog.array.every(/** @type {!Array} */ (col), f, opt_obj);
    344 }
    345 var keys = goog.structs.getKeys(col);
    346 var values = goog.structs.getValues(col);
    347 var l = values.length;
    348 for (var i = 0; i < l; i++) {
    349 if (!f.call(opt_obj, values[i], keys && keys[i], col)) {
    350 return false;
    351 }
    352 }
    353 return true;
    354};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/uri/uri.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/uri/uri.js.src.html new file mode 100644 index 0000000..b7fbd0f --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/uri/uri.js.src.html @@ -0,0 +1 @@ +uri.js

    lib/goog/uri/uri.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Class for parsing and formatting URIs.
    17 *
    18 * Use goog.Uri(string) to parse a URI string. Use goog.Uri.create(...) to
    19 * create a new instance of the goog.Uri object from Uri parts.
    20 *
    21 * e.g: <code>var myUri = new goog.Uri(window.location);</code>
    22 *
    23 * Implements RFC 3986 for parsing/formatting URIs.
    24 * http://www.ietf.org/rfc/rfc3986.txt
    25 *
    26 * Some changes have been made to the interface (more like .NETs), though the
    27 * internal representation is now of un-encoded parts, this will change the
    28 * behavior slightly.
    29 *
    30 */
    31
    32goog.provide('goog.Uri');
    33goog.provide('goog.Uri.QueryData');
    34
    35goog.require('goog.array');
    36goog.require('goog.string');
    37goog.require('goog.structs');
    38goog.require('goog.structs.Map');
    39goog.require('goog.uri.utils');
    40goog.require('goog.uri.utils.ComponentIndex');
    41goog.require('goog.uri.utils.StandardQueryParam');
    42
    43
    44
    45/**
    46 * This class contains setters and getters for the parts of the URI.
    47 * The <code>getXyz</code>/<code>setXyz</code> methods return the decoded part
    48 * -- so<code>goog.Uri.parse('/foo%20bar').getPath()</code> will return the
    49 * decoded path, <code>/foo bar</code>.
    50 *
    51 * The constructor accepts an optional unparsed, raw URI string. The parser
    52 * is relaxed, so special characters that aren't escaped but don't cause
    53 * ambiguities will not cause parse failures.
    54 *
    55 * All setters return <code>this</code> and so may be chained, a la
    56 * <code>goog.Uri.parse('/foo').setFragment('part').toString()</code>.
    57 *
    58 * @param {*=} opt_uri Optional string URI to parse
    59 * (use goog.Uri.create() to create a URI from parts), or if
    60 * a goog.Uri is passed, a clone is created.
    61 * @param {boolean=} opt_ignoreCase If true, #getParameterValue will ignore
    62 * the case of the parameter name.
    63 *
    64 * @constructor
    65 */
    66goog.Uri = function(opt_uri, opt_ignoreCase) {
    67 // Parse in the uri string
    68 var m;
    69 if (opt_uri instanceof goog.Uri) {
    70 this.ignoreCase_ = goog.isDef(opt_ignoreCase) ?
    71 opt_ignoreCase : opt_uri.getIgnoreCase();
    72 this.setScheme(opt_uri.getScheme());
    73 this.setUserInfo(opt_uri.getUserInfo());
    74 this.setDomain(opt_uri.getDomain());
    75 this.setPort(opt_uri.getPort());
    76 this.setPath(opt_uri.getPath());
    77 this.setQueryData(opt_uri.getQueryData().clone());
    78 this.setFragment(opt_uri.getFragment());
    79 } else if (opt_uri && (m = goog.uri.utils.split(String(opt_uri)))) {
    80 this.ignoreCase_ = !!opt_ignoreCase;
    81
    82 // Set the parts -- decoding as we do so.
    83 // COMPATABILITY NOTE - In IE, unmatched fields may be empty strings,
    84 // whereas in other browsers they will be undefined.
    85 this.setScheme(m[goog.uri.utils.ComponentIndex.SCHEME] || '', true);
    86 this.setUserInfo(m[goog.uri.utils.ComponentIndex.USER_INFO] || '', true);
    87 this.setDomain(m[goog.uri.utils.ComponentIndex.DOMAIN] || '', true);
    88 this.setPort(m[goog.uri.utils.ComponentIndex.PORT]);
    89 this.setPath(m[goog.uri.utils.ComponentIndex.PATH] || '', true);
    90 this.setQueryData(m[goog.uri.utils.ComponentIndex.QUERY_DATA] || '', true);
    91 this.setFragment(m[goog.uri.utils.ComponentIndex.FRAGMENT] || '', true);
    92
    93 } else {
    94 this.ignoreCase_ = !!opt_ignoreCase;
    95 this.queryData_ = new goog.Uri.QueryData(null, null, this.ignoreCase_);
    96 }
    97};
    98
    99
    100/**
    101 * If true, we preserve the type of query parameters set programmatically.
    102 *
    103 * This means that if you set a parameter to a boolean, and then call
    104 * getParameterValue, you will get a boolean back.
    105 *
    106 * If false, we will coerce parameters to strings, just as they would
    107 * appear in real URIs.
    108 *
    109 * TODO(nicksantos): Remove this once people have time to fix all tests.
    110 *
    111 * @type {boolean}
    112 */
    113goog.Uri.preserveParameterTypesCompatibilityFlag = false;
    114
    115
    116/**
    117 * Parameter name added to stop caching.
    118 * @type {string}
    119 */
    120goog.Uri.RANDOM_PARAM = goog.uri.utils.StandardQueryParam.RANDOM;
    121
    122
    123/**
    124 * Scheme such as "http".
    125 * @type {string}
    126 * @private
    127 */
    128goog.Uri.prototype.scheme_ = '';
    129
    130
    131/**
    132 * User credentials in the form "username:password".
    133 * @type {string}
    134 * @private
    135 */
    136goog.Uri.prototype.userInfo_ = '';
    137
    138
    139/**
    140 * Domain part, e.g. "www.google.com".
    141 * @type {string}
    142 * @private
    143 */
    144goog.Uri.prototype.domain_ = '';
    145
    146
    147/**
    148 * Port, e.g. 8080.
    149 * @type {?number}
    150 * @private
    151 */
    152goog.Uri.prototype.port_ = null;
    153
    154
    155/**
    156 * Path, e.g. "/tests/img.png".
    157 * @type {string}
    158 * @private
    159 */
    160goog.Uri.prototype.path_ = '';
    161
    162
    163/**
    164 * Object representing query data.
    165 * @type {!goog.Uri.QueryData}
    166 * @private
    167 */
    168goog.Uri.prototype.queryData_;
    169
    170
    171/**
    172 * The fragment without the #.
    173 * @type {string}
    174 * @private
    175 */
    176goog.Uri.prototype.fragment_ = '';
    177
    178
    179/**
    180 * Whether or not this Uri should be treated as Read Only.
    181 * @type {boolean}
    182 * @private
    183 */
    184goog.Uri.prototype.isReadOnly_ = false;
    185
    186
    187/**
    188 * Whether or not to ignore case when comparing query params.
    189 * @type {boolean}
    190 * @private
    191 */
    192goog.Uri.prototype.ignoreCase_ = false;
    193
    194
    195/**
    196 * @return {string} The string form of the url.
    197 * @override
    198 */
    199goog.Uri.prototype.toString = function() {
    200 var out = [];
    201
    202 var scheme = this.getScheme();
    203 if (scheme) {
    204 out.push(goog.Uri.encodeSpecialChars_(
    205 scheme, goog.Uri.reDisallowedInSchemeOrUserInfo_), ':');
    206 }
    207
    208 var domain = this.getDomain();
    209 if (domain) {
    210 out.push('//');
    211
    212 var userInfo = this.getUserInfo();
    213 if (userInfo) {
    214 out.push(goog.Uri.encodeSpecialChars_(
    215 userInfo, goog.Uri.reDisallowedInSchemeOrUserInfo_), '@');
    216 }
    217
    218 out.push(goog.string.urlEncode(domain));
    219
    220 var port = this.getPort();
    221 if (port != null) {
    222 out.push(':', String(port));
    223 }
    224 }
    225
    226 var path = this.getPath();
    227 if (path) {
    228 if (this.hasDomain() && path.charAt(0) != '/') {
    229 out.push('/');
    230 }
    231 out.push(goog.Uri.encodeSpecialChars_(
    232 path,
    233 path.charAt(0) == '/' ?
    234 goog.Uri.reDisallowedInAbsolutePath_ :
    235 goog.Uri.reDisallowedInRelativePath_));
    236 }
    237
    238 var query = this.getEncodedQuery();
    239 if (query) {
    240 out.push('?', query);
    241 }
    242
    243 var fragment = this.getFragment();
    244 if (fragment) {
    245 out.push('#', goog.Uri.encodeSpecialChars_(
    246 fragment, goog.Uri.reDisallowedInFragment_));
    247 }
    248 return out.join('');
    249};
    250
    251
    252/**
    253 * Resolves the given relative URI (a goog.Uri object), using the URI
    254 * represented by this instance as the base URI.
    255 *
    256 * There are several kinds of relative URIs:<br>
    257 * 1. foo - replaces the last part of the path, the whole query and fragment<br>
    258 * 2. /foo - replaces the the path, the query and fragment<br>
    259 * 3. //foo - replaces everything from the domain on. foo is a domain name<br>
    260 * 4. ?foo - replace the query and fragment<br>
    261 * 5. #foo - replace the fragment only
    262 *
    263 * Additionally, if relative URI has a non-empty path, all ".." and "."
    264 * segments will be resolved, as described in RFC 3986.
    265 *
    266 * @param {goog.Uri} relativeUri The relative URI to resolve.
    267 * @return {!goog.Uri} The resolved URI.
    268 */
    269goog.Uri.prototype.resolve = function(relativeUri) {
    270
    271 var absoluteUri = this.clone();
    272
    273 // we satisfy these conditions by looking for the first part of relativeUri
    274 // that is not blank and applying defaults to the rest
    275
    276 var overridden = relativeUri.hasScheme();
    277
    278 if (overridden) {
    279 absoluteUri.setScheme(relativeUri.getScheme());
    280 } else {
    281 overridden = relativeUri.hasUserInfo();
    282 }
    283
    284 if (overridden) {
    285 absoluteUri.setUserInfo(relativeUri.getUserInfo());
    286 } else {
    287 overridden = relativeUri.hasDomain();
    288 }
    289
    290 if (overridden) {
    291 absoluteUri.setDomain(relativeUri.getDomain());
    292 } else {
    293 overridden = relativeUri.hasPort();
    294 }
    295
    296 var path = relativeUri.getPath();
    297 if (overridden) {
    298 absoluteUri.setPort(relativeUri.getPort());
    299 } else {
    300 overridden = relativeUri.hasPath();
    301 if (overridden) {
    302 // resolve path properly
    303 if (path.charAt(0) != '/') {
    304 // path is relative
    305 if (this.hasDomain() && !this.hasPath()) {
    306 // RFC 3986, section 5.2.3, case 1
    307 path = '/' + path;
    308 } else {
    309 // RFC 3986, section 5.2.3, case 2
    310 var lastSlashIndex = absoluteUri.getPath().lastIndexOf('/');
    311 if (lastSlashIndex != -1) {
    312 path = absoluteUri.getPath().substr(0, lastSlashIndex + 1) + path;
    313 }
    314 }
    315 }
    316 path = goog.Uri.removeDotSegments(path);
    317 }
    318 }
    319
    320 if (overridden) {
    321 absoluteUri.setPath(path);
    322 } else {
    323 overridden = relativeUri.hasQuery();
    324 }
    325
    326 if (overridden) {
    327 absoluteUri.setQueryData(relativeUri.getDecodedQuery());
    328 } else {
    329 overridden = relativeUri.hasFragment();
    330 }
    331
    332 if (overridden) {
    333 absoluteUri.setFragment(relativeUri.getFragment());
    334 }
    335
    336 return absoluteUri;
    337};
    338
    339
    340/**
    341 * Clones the URI instance.
    342 * @return {!goog.Uri} New instance of the URI object.
    343 */
    344goog.Uri.prototype.clone = function() {
    345 return new goog.Uri(this);
    346};
    347
    348
    349/**
    350 * @return {string} The encoded scheme/protocol for the URI.
    351 */
    352goog.Uri.prototype.getScheme = function() {
    353 return this.scheme_;
    354};
    355
    356
    357/**
    358 * Sets the scheme/protocol.
    359 * @param {string} newScheme New scheme value.
    360 * @param {boolean=} opt_decode Optional param for whether to decode new value.
    361 * @return {!goog.Uri} Reference to this URI object.
    362 */
    363goog.Uri.prototype.setScheme = function(newScheme, opt_decode) {
    364 this.enforceReadOnly();
    365 this.scheme_ = opt_decode ? goog.Uri.decodeOrEmpty_(newScheme) : newScheme;
    366
    367 // remove an : at the end of the scheme so somebody can pass in
    368 // window.location.protocol
    369 if (this.scheme_) {
    370 this.scheme_ = this.scheme_.replace(/:$/, '');
    371 }
    372 return this;
    373};
    374
    375
    376/**
    377 * @return {boolean} Whether the scheme has been set.
    378 */
    379goog.Uri.prototype.hasScheme = function() {
    380 return !!this.scheme_;
    381};
    382
    383
    384/**
    385 * @return {string} The decoded user info.
    386 */
    387goog.Uri.prototype.getUserInfo = function() {
    388 return this.userInfo_;
    389};
    390
    391
    392/**
    393 * Sets the userInfo.
    394 * @param {string} newUserInfo New userInfo value.
    395 * @param {boolean=} opt_decode Optional param for whether to decode new value.
    396 * @return {!goog.Uri} Reference to this URI object.
    397 */
    398goog.Uri.prototype.setUserInfo = function(newUserInfo, opt_decode) {
    399 this.enforceReadOnly();
    400 this.userInfo_ = opt_decode ? goog.Uri.decodeOrEmpty_(newUserInfo) :
    401 newUserInfo;
    402 return this;
    403};
    404
    405
    406/**
    407 * @return {boolean} Whether the user info has been set.
    408 */
    409goog.Uri.prototype.hasUserInfo = function() {
    410 return !!this.userInfo_;
    411};
    412
    413
    414/**
    415 * @return {string} The decoded domain.
    416 */
    417goog.Uri.prototype.getDomain = function() {
    418 return this.domain_;
    419};
    420
    421
    422/**
    423 * Sets the domain.
    424 * @param {string} newDomain New domain value.
    425 * @param {boolean=} opt_decode Optional param for whether to decode new value.
    426 * @return {!goog.Uri} Reference to this URI object.
    427 */
    428goog.Uri.prototype.setDomain = function(newDomain, opt_decode) {
    429 this.enforceReadOnly();
    430 this.domain_ = opt_decode ? goog.Uri.decodeOrEmpty_(newDomain) : newDomain;
    431 return this;
    432};
    433
    434
    435/**
    436 * @return {boolean} Whether the domain has been set.
    437 */
    438goog.Uri.prototype.hasDomain = function() {
    439 return !!this.domain_;
    440};
    441
    442
    443/**
    444 * @return {?number} The port number.
    445 */
    446goog.Uri.prototype.getPort = function() {
    447 return this.port_;
    448};
    449
    450
    451/**
    452 * Sets the port number.
    453 * @param {*} newPort Port number. Will be explicitly casted to a number.
    454 * @return {!goog.Uri} Reference to this URI object.
    455 */
    456goog.Uri.prototype.setPort = function(newPort) {
    457 this.enforceReadOnly();
    458
    459 if (newPort) {
    460 newPort = Number(newPort);
    461 if (isNaN(newPort) || newPort < 0) {
    462 throw Error('Bad port number ' + newPort);
    463 }
    464 this.port_ = newPort;
    465 } else {
    466 this.port_ = null;
    467 }
    468
    469 return this;
    470};
    471
    472
    473/**
    474 * @return {boolean} Whether the port has been set.
    475 */
    476goog.Uri.prototype.hasPort = function() {
    477 return this.port_ != null;
    478};
    479
    480
    481/**
    482 * @return {string} The decoded path.
    483 */
    484goog.Uri.prototype.getPath = function() {
    485 return this.path_;
    486};
    487
    488
    489/**
    490 * Sets the path.
    491 * @param {string} newPath New path value.
    492 * @param {boolean=} opt_decode Optional param for whether to decode new value.
    493 * @return {!goog.Uri} Reference to this URI object.
    494 */
    495goog.Uri.prototype.setPath = function(newPath, opt_decode) {
    496 this.enforceReadOnly();
    497 this.path_ = opt_decode ? goog.Uri.decodeOrEmpty_(newPath) : newPath;
    498 return this;
    499};
    500
    501
    502/**
    503 * @return {boolean} Whether the path has been set.
    504 */
    505goog.Uri.prototype.hasPath = function() {
    506 return !!this.path_;
    507};
    508
    509
    510/**
    511 * @return {boolean} Whether the query string has been set.
    512 */
    513goog.Uri.prototype.hasQuery = function() {
    514 return this.queryData_.toString() !== '';
    515};
    516
    517
    518/**
    519 * Sets the query data.
    520 * @param {goog.Uri.QueryData|string|undefined} queryData QueryData object.
    521 * @param {boolean=} opt_decode Optional param for whether to decode new value.
    522 * Applies only if queryData is a string.
    523 * @return {!goog.Uri} Reference to this URI object.
    524 */
    525goog.Uri.prototype.setQueryData = function(queryData, opt_decode) {
    526 this.enforceReadOnly();
    527
    528 if (queryData instanceof goog.Uri.QueryData) {
    529 this.queryData_ = queryData;
    530 this.queryData_.setIgnoreCase(this.ignoreCase_);
    531 } else {
    532 if (!opt_decode) {
    533 // QueryData accepts encoded query string, so encode it if
    534 // opt_decode flag is not true.
    535 queryData = goog.Uri.encodeSpecialChars_(queryData,
    536 goog.Uri.reDisallowedInQuery_);
    537 }
    538 this.queryData_ = new goog.Uri.QueryData(queryData, null, this.ignoreCase_);
    539 }
    540
    541 return this;
    542};
    543
    544
    545/**
    546 * Sets the URI query.
    547 * @param {string} newQuery New query value.
    548 * @param {boolean=} opt_decode Optional param for whether to decode new value.
    549 * @return {!goog.Uri} Reference to this URI object.
    550 */
    551goog.Uri.prototype.setQuery = function(newQuery, opt_decode) {
    552 return this.setQueryData(newQuery, opt_decode);
    553};
    554
    555
    556/**
    557 * @return {string} The encoded URI query, not including the ?.
    558 */
    559goog.Uri.prototype.getEncodedQuery = function() {
    560 return this.queryData_.toString();
    561};
    562
    563
    564/**
    565 * @return {string} The decoded URI query, not including the ?.
    566 */
    567goog.Uri.prototype.getDecodedQuery = function() {
    568 return this.queryData_.toDecodedString();
    569};
    570
    571
    572/**
    573 * Returns the query data.
    574 * @return {!goog.Uri.QueryData} QueryData object.
    575 */
    576goog.Uri.prototype.getQueryData = function() {
    577 return this.queryData_;
    578};
    579
    580
    581/**
    582 * @return {string} The encoded URI query, not including the ?.
    583 *
    584 * Warning: This method, unlike other getter methods, returns encoded
    585 * value, instead of decoded one.
    586 */
    587goog.Uri.prototype.getQuery = function() {
    588 return this.getEncodedQuery();
    589};
    590
    591
    592/**
    593 * Sets the value of the named query parameters, clearing previous values for
    594 * that key.
    595 *
    596 * @param {string} key The parameter to set.
    597 * @param {*} value The new value.
    598 * @return {!goog.Uri} Reference to this URI object.
    599 */
    600goog.Uri.prototype.setParameterValue = function(key, value) {
    601 this.enforceReadOnly();
    602 this.queryData_.set(key, value);
    603 return this;
    604};
    605
    606
    607/**
    608 * Sets the values of the named query parameters, clearing previous values for
    609 * that key. Not new values will currently be moved to the end of the query
    610 * string.
    611 *
    612 * So, <code>goog.Uri.parse('foo?a=b&c=d&e=f').setParameterValues('c', ['new'])
    613 * </code> yields <tt>foo?a=b&e=f&c=new</tt>.</p>
    614 *
    615 * @param {string} key The parameter to set.
    616 * @param {*} values The new values. If values is a single
    617 * string then it will be treated as the sole value.
    618 * @return {!goog.Uri} Reference to this URI object.
    619 */
    620goog.Uri.prototype.setParameterValues = function(key, values) {
    621 this.enforceReadOnly();
    622
    623 if (!goog.isArray(values)) {
    624 values = [String(values)];
    625 }
    626
    627 // TODO(nicksantos): This cast shouldn't be necessary.
    628 this.queryData_.setValues(key, /** @type {Array} */ (values));
    629
    630 return this;
    631};
    632
    633
    634/**
    635 * Returns the value<b>s</b> for a given cgi parameter as a list of decoded
    636 * query parameter values.
    637 * @param {string} name The parameter to get values for.
    638 * @return {!Array} The values for a given cgi parameter as a list of
    639 * decoded query parameter values.
    640 */
    641goog.Uri.prototype.getParameterValues = function(name) {
    642 return this.queryData_.getValues(name);
    643};
    644
    645
    646/**
    647 * Returns the first value for a given cgi parameter or undefined if the given
    648 * parameter name does not appear in the query string.
    649 * @param {string} paramName Unescaped parameter name.
    650 * @return {string|undefined} The first value for a given cgi parameter or
    651 * undefined if the given parameter name does not appear in the query
    652 * string.
    653 */
    654goog.Uri.prototype.getParameterValue = function(paramName) {
    655 // NOTE(nicksantos): This type-cast is a lie when
    656 // preserveParameterTypesCompatibilityFlag is set to true.
    657 // But this should only be set to true in tests.
    658 return /** @type {string|undefined} */ (this.queryData_.get(paramName));
    659};
    660
    661
    662/**
    663 * @return {string} The URI fragment, not including the #.
    664 */
    665goog.Uri.prototype.getFragment = function() {
    666 return this.fragment_;
    667};
    668
    669
    670/**
    671 * Sets the URI fragment.
    672 * @param {string} newFragment New fragment value.
    673 * @param {boolean=} opt_decode Optional param for whether to decode new value.
    674 * @return {!goog.Uri} Reference to this URI object.
    675 */
    676goog.Uri.prototype.setFragment = function(newFragment, opt_decode) {
    677 this.enforceReadOnly();
    678 this.fragment_ = opt_decode ? goog.Uri.decodeOrEmpty_(newFragment) :
    679 newFragment;
    680 return this;
    681};
    682
    683
    684/**
    685 * @return {boolean} Whether the URI has a fragment set.
    686 */
    687goog.Uri.prototype.hasFragment = function() {
    688 return !!this.fragment_;
    689};
    690
    691
    692/**
    693 * Returns true if this has the same domain as that of uri2.
    694 * @param {goog.Uri} uri2 The URI object to compare to.
    695 * @return {boolean} true if same domain; false otherwise.
    696 */
    697goog.Uri.prototype.hasSameDomainAs = function(uri2) {
    698 return ((!this.hasDomain() && !uri2.hasDomain()) ||
    699 this.getDomain() == uri2.getDomain()) &&
    700 ((!this.hasPort() && !uri2.hasPort()) ||
    701 this.getPort() == uri2.getPort());
    702};
    703
    704
    705/**
    706 * Adds a random parameter to the Uri.
    707 * @return {!goog.Uri} Reference to this Uri object.
    708 */
    709goog.Uri.prototype.makeUnique = function() {
    710 this.enforceReadOnly();
    711 this.setParameterValue(goog.Uri.RANDOM_PARAM, goog.string.getRandomString());
    712
    713 return this;
    714};
    715
    716
    717/**
    718 * Removes the named query parameter.
    719 *
    720 * @param {string} key The parameter to remove.
    721 * @return {!goog.Uri} Reference to this URI object.
    722 */
    723goog.Uri.prototype.removeParameter = function(key) {
    724 this.enforceReadOnly();
    725 this.queryData_.remove(key);
    726 return this;
    727};
    728
    729
    730/**
    731 * Sets whether Uri is read only. If this goog.Uri is read-only,
    732 * enforceReadOnly_ will be called at the start of any function that may modify
    733 * this Uri.
    734 * @param {boolean} isReadOnly whether this goog.Uri should be read only.
    735 * @return {!goog.Uri} Reference to this Uri object.
    736 */
    737goog.Uri.prototype.setReadOnly = function(isReadOnly) {
    738 this.isReadOnly_ = isReadOnly;
    739 return this;
    740};
    741
    742
    743/**
    744 * @return {boolean} Whether the URI is read only.
    745 */
    746goog.Uri.prototype.isReadOnly = function() {
    747 return this.isReadOnly_;
    748};
    749
    750
    751/**
    752 * Checks if this Uri has been marked as read only, and if so, throws an error.
    753 * This should be called whenever any modifying function is called.
    754 */
    755goog.Uri.prototype.enforceReadOnly = function() {
    756 if (this.isReadOnly_) {
    757 throw Error('Tried to modify a read-only Uri');
    758 }
    759};
    760
    761
    762/**
    763 * Sets whether to ignore case.
    764 * NOTE: If there are already key/value pairs in the QueryData, and
    765 * ignoreCase_ is set to false, the keys will all be lower-cased.
    766 * @param {boolean} ignoreCase whether this goog.Uri should ignore case.
    767 * @return {!goog.Uri} Reference to this Uri object.
    768 */
    769goog.Uri.prototype.setIgnoreCase = function(ignoreCase) {
    770 this.ignoreCase_ = ignoreCase;
    771 if (this.queryData_) {
    772 this.queryData_.setIgnoreCase(ignoreCase);
    773 }
    774 return this;
    775};
    776
    777
    778/**
    779 * @return {boolean} Whether to ignore case.
    780 */
    781goog.Uri.prototype.getIgnoreCase = function() {
    782 return this.ignoreCase_;
    783};
    784
    785
    786//==============================================================================
    787// Static members
    788//==============================================================================
    789
    790
    791/**
    792 * Creates a uri from the string form. Basically an alias of new goog.Uri().
    793 * If a Uri object is passed to parse then it will return a clone of the object.
    794 *
    795 * @param {*} uri Raw URI string or instance of Uri
    796 * object.
    797 * @param {boolean=} opt_ignoreCase Whether to ignore the case of parameter
    798 * names in #getParameterValue.
    799 * @return {!goog.Uri} The new URI object.
    800 */
    801goog.Uri.parse = function(uri, opt_ignoreCase) {
    802 return uri instanceof goog.Uri ?
    803 uri.clone() : new goog.Uri(uri, opt_ignoreCase);
    804};
    805
    806
    807/**
    808 * Creates a new goog.Uri object from unencoded parts.
    809 *
    810 * @param {?string=} opt_scheme Scheme/protocol or full URI to parse.
    811 * @param {?string=} opt_userInfo username:password.
    812 * @param {?string=} opt_domain www.google.com.
    813 * @param {?number=} opt_port 9830.
    814 * @param {?string=} opt_path /some/path/to/a/file.html.
    815 * @param {string|goog.Uri.QueryData=} opt_query a=1&b=2.
    816 * @param {?string=} opt_fragment The fragment without the #.
    817 * @param {boolean=} opt_ignoreCase Whether to ignore parameter name case in
    818 * #getParameterValue.
    819 *
    820 * @return {!goog.Uri} The new URI object.
    821 */
    822goog.Uri.create = function(opt_scheme, opt_userInfo, opt_domain, opt_port,
    823 opt_path, opt_query, opt_fragment, opt_ignoreCase) {
    824
    825 var uri = new goog.Uri(null, opt_ignoreCase);
    826
    827 // Only set the parts if they are defined and not empty strings.
    828 opt_scheme && uri.setScheme(opt_scheme);
    829 opt_userInfo && uri.setUserInfo(opt_userInfo);
    830 opt_domain && uri.setDomain(opt_domain);
    831 opt_port && uri.setPort(opt_port);
    832 opt_path && uri.setPath(opt_path);
    833 opt_query && uri.setQueryData(opt_query);
    834 opt_fragment && uri.setFragment(opt_fragment);
    835
    836 return uri;
    837};
    838
    839
    840/**
    841 * Resolves a relative Uri against a base Uri, accepting both strings and
    842 * Uri objects.
    843 *
    844 * @param {*} base Base Uri.
    845 * @param {*} rel Relative Uri.
    846 * @return {!goog.Uri} Resolved uri.
    847 */
    848goog.Uri.resolve = function(base, rel) {
    849 if (!(base instanceof goog.Uri)) {
    850 base = goog.Uri.parse(base);
    851 }
    852
    853 if (!(rel instanceof goog.Uri)) {
    854 rel = goog.Uri.parse(rel);
    855 }
    856
    857 return base.resolve(rel);
    858};
    859
    860
    861/**
    862 * Removes dot segments in given path component, as described in
    863 * RFC 3986, section 5.2.4.
    864 *
    865 * @param {string} path A non-empty path component.
    866 * @return {string} Path component with removed dot segments.
    867 */
    868goog.Uri.removeDotSegments = function(path) {
    869 if (path == '..' || path == '.') {
    870 return '';
    871
    872 } else if (!goog.string.contains(path, './') &&
    873 !goog.string.contains(path, '/.')) {
    874 // This optimization detects uris which do not contain dot-segments,
    875 // and as a consequence do not require any processing.
    876 return path;
    877
    878 } else {
    879 var leadingSlash = goog.string.startsWith(path, '/');
    880 var segments = path.split('/');
    881 var out = [];
    882
    883 for (var pos = 0; pos < segments.length; ) {
    884 var segment = segments[pos++];
    885
    886 if (segment == '.') {
    887 if (leadingSlash && pos == segments.length) {
    888 out.push('');
    889 }
    890 } else if (segment == '..') {
    891 if (out.length > 1 || out.length == 1 && out[0] != '') {
    892 out.pop();
    893 }
    894 if (leadingSlash && pos == segments.length) {
    895 out.push('');
    896 }
    897 } else {
    898 out.push(segment);
    899 leadingSlash = true;
    900 }
    901 }
    902
    903 return out.join('/');
    904 }
    905};
    906
    907
    908/**
    909 * Decodes a value or returns the empty string if it isn't defined or empty.
    910 * @param {string|undefined} val Value to decode.
    911 * @return {string} Decoded value.
    912 * @private
    913 */
    914goog.Uri.decodeOrEmpty_ = function(val) {
    915 // Don't use UrlDecode() here because val is not a query parameter.
    916 return val ? decodeURIComponent(val) : '';
    917};
    918
    919
    920/**
    921 * If unescapedPart is non null, then escapes any characters in it that aren't
    922 * valid characters in a url and also escapes any special characters that
    923 * appear in extra.
    924 *
    925 * @param {*} unescapedPart The string to encode.
    926 * @param {RegExp} extra A character set of characters in [\01-\177].
    927 * @return {?string} null iff unescapedPart == null.
    928 * @private
    929 */
    930goog.Uri.encodeSpecialChars_ = function(unescapedPart, extra) {
    931 if (goog.isString(unescapedPart)) {
    932 return encodeURI(unescapedPart).replace(extra, goog.Uri.encodeChar_);
    933 }
    934 return null;
    935};
    936
    937
    938/**
    939 * Converts a character in [\01-\177] to its unicode character equivalent.
    940 * @param {string} ch One character string.
    941 * @return {string} Encoded string.
    942 * @private
    943 */
    944goog.Uri.encodeChar_ = function(ch) {
    945 var n = ch.charCodeAt(0);
    946 return '%' + ((n >> 4) & 0xf).toString(16) + (n & 0xf).toString(16);
    947};
    948
    949
    950/**
    951 * Regular expression for characters that are disallowed in the scheme or
    952 * userInfo part of the URI.
    953 * @type {RegExp}
    954 * @private
    955 */
    956goog.Uri.reDisallowedInSchemeOrUserInfo_ = /[#\/\?@]/g;
    957
    958
    959/**
    960 * Regular expression for characters that are disallowed in a relative path.
    961 * @type {RegExp}
    962 * @private
    963 */
    964goog.Uri.reDisallowedInRelativePath_ = /[\#\?:]/g;
    965
    966
    967/**
    968 * Regular expression for characters that are disallowed in an absolute path.
    969 * @type {RegExp}
    970 * @private
    971 */
    972goog.Uri.reDisallowedInAbsolutePath_ = /[\#\?]/g;
    973
    974
    975/**
    976 * Regular expression for characters that are disallowed in the query.
    977 * @type {RegExp}
    978 * @private
    979 */
    980goog.Uri.reDisallowedInQuery_ = /[\#\?@]/g;
    981
    982
    983/**
    984 * Regular expression for characters that are disallowed in the fragment.
    985 * @type {RegExp}
    986 * @private
    987 */
    988goog.Uri.reDisallowedInFragment_ = /#/g;
    989
    990
    991/**
    992 * Checks whether two URIs have the same domain.
    993 * @param {string} uri1String First URI string.
    994 * @param {string} uri2String Second URI string.
    995 * @return {boolean} true if the two URIs have the same domain; false otherwise.
    996 */
    997goog.Uri.haveSameDomain = function(uri1String, uri2String) {
    998 // Differs from goog.uri.utils.haveSameDomain, since this ignores scheme.
    999 // TODO(gboyer): Have this just call goog.uri.util.haveSameDomain.
    1000 var pieces1 = goog.uri.utils.split(uri1String);
    1001 var pieces2 = goog.uri.utils.split(uri2String);
    1002 return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] ==
    1003 pieces2[goog.uri.utils.ComponentIndex.DOMAIN] &&
    1004 pieces1[goog.uri.utils.ComponentIndex.PORT] ==
    1005 pieces2[goog.uri.utils.ComponentIndex.PORT];
    1006};
    1007
    1008
    1009
    1010/**
    1011 * Class used to represent URI query parameters. It is essentially a hash of
    1012 * name-value pairs, though a name can be present more than once.
    1013 *
    1014 * Has the same interface as the collections in goog.structs.
    1015 *
    1016 * @param {?string=} opt_query Optional encoded query string to parse into
    1017 * the object.
    1018 * @param {goog.Uri=} opt_uri Optional uri object that should have its
    1019 * cache invalidated when this object updates. Deprecated -- this
    1020 * is no longer required.
    1021 * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter
    1022 * name in #get.
    1023 * @constructor
    1024 * @final
    1025 */
    1026goog.Uri.QueryData = function(opt_query, opt_uri, opt_ignoreCase) {
    1027 /**
    1028 * Encoded query string, or null if it requires computing from the key map.
    1029 * @type {?string}
    1030 * @private
    1031 */
    1032 this.encodedQuery_ = opt_query || null;
    1033
    1034 /**
    1035 * If true, ignore the case of the parameter name in #get.
    1036 * @type {boolean}
    1037 * @private
    1038 */
    1039 this.ignoreCase_ = !!opt_ignoreCase;
    1040};
    1041
    1042
    1043/**
    1044 * If the underlying key map is not yet initialized, it parses the
    1045 * query string and fills the map with parsed data.
    1046 * @private
    1047 */
    1048goog.Uri.QueryData.prototype.ensureKeyMapInitialized_ = function() {
    1049 if (!this.keyMap_) {
    1050 this.keyMap_ = new goog.structs.Map();
    1051 this.count_ = 0;
    1052
    1053 if (this.encodedQuery_) {
    1054 var pairs = this.encodedQuery_.split('&');
    1055 for (var i = 0; i < pairs.length; i++) {
    1056 var indexOfEquals = pairs[i].indexOf('=');
    1057 var name = null;
    1058 var value = null;
    1059 if (indexOfEquals >= 0) {
    1060 name = pairs[i].substring(0, indexOfEquals);
    1061 value = pairs[i].substring(indexOfEquals + 1);
    1062 } else {
    1063 name = pairs[i];
    1064 }
    1065 name = goog.string.urlDecode(name);
    1066 name = this.getKeyName_(name);
    1067 this.add(name, value ? goog.string.urlDecode(value) : '');
    1068 }
    1069 }
    1070 }
    1071};
    1072
    1073
    1074/**
    1075 * Creates a new query data instance from a map of names and values.
    1076 *
    1077 * @param {!goog.structs.Map|!Object} map Map of string parameter
    1078 * names to parameter value. If parameter value is an array, it is
    1079 * treated as if the key maps to each individual value in the
    1080 * array.
    1081 * @param {goog.Uri=} opt_uri URI object that should have its cache
    1082 * invalidated when this object updates.
    1083 * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter
    1084 * name in #get.
    1085 * @return {!goog.Uri.QueryData} The populated query data instance.
    1086 */
    1087goog.Uri.QueryData.createFromMap = function(map, opt_uri, opt_ignoreCase) {
    1088 var keys = goog.structs.getKeys(map);
    1089 if (typeof keys == 'undefined') {
    1090 throw Error('Keys are undefined');
    1091 }
    1092
    1093 var queryData = new goog.Uri.QueryData(null, null, opt_ignoreCase);
    1094 var values = goog.structs.getValues(map);
    1095 for (var i = 0; i < keys.length; i++) {
    1096 var key = keys[i];
    1097 var value = values[i];
    1098 if (!goog.isArray(value)) {
    1099 queryData.add(key, value);
    1100 } else {
    1101 queryData.setValues(key, value);
    1102 }
    1103 }
    1104 return queryData;
    1105};
    1106
    1107
    1108/**
    1109 * Creates a new query data instance from parallel arrays of parameter names
    1110 * and values. Allows for duplicate parameter names. Throws an error if the
    1111 * lengths of the arrays differ.
    1112 *
    1113 * @param {Array.<string>} keys Parameter names.
    1114 * @param {Array} values Parameter values.
    1115 * @param {goog.Uri=} opt_uri URI object that should have its cache
    1116 * invalidated when this object updates.
    1117 * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter
    1118 * name in #get.
    1119 * @return {!goog.Uri.QueryData} The populated query data instance.
    1120 */
    1121goog.Uri.QueryData.createFromKeysValues = function(
    1122 keys, values, opt_uri, opt_ignoreCase) {
    1123 if (keys.length != values.length) {
    1124 throw Error('Mismatched lengths for keys/values');
    1125 }
    1126 var queryData = new goog.Uri.QueryData(null, null, opt_ignoreCase);
    1127 for (var i = 0; i < keys.length; i++) {
    1128 queryData.add(keys[i], values[i]);
    1129 }
    1130 return queryData;
    1131};
    1132
    1133
    1134/**
    1135 * The map containing name/value or name/array-of-values pairs.
    1136 * May be null if it requires parsing from the query string.
    1137 *
    1138 * We need to use a Map because we cannot guarantee that the key names will
    1139 * not be problematic for IE.
    1140 *
    1141 * @type {goog.structs.Map.<string, Array>}
    1142 * @private
    1143 */
    1144goog.Uri.QueryData.prototype.keyMap_ = null;
    1145
    1146
    1147/**
    1148 * The number of params, or null if it requires computing.
    1149 * @type {?number}
    1150 * @private
    1151 */
    1152goog.Uri.QueryData.prototype.count_ = null;
    1153
    1154
    1155/**
    1156 * @return {?number} The number of parameters.
    1157 */
    1158goog.Uri.QueryData.prototype.getCount = function() {
    1159 this.ensureKeyMapInitialized_();
    1160 return this.count_;
    1161};
    1162
    1163
    1164/**
    1165 * Adds a key value pair.
    1166 * @param {string} key Name.
    1167 * @param {*} value Value.
    1168 * @return {!goog.Uri.QueryData} Instance of this object.
    1169 */
    1170goog.Uri.QueryData.prototype.add = function(key, value) {
    1171 this.ensureKeyMapInitialized_();
    1172 this.invalidateCache_();
    1173
    1174 key = this.getKeyName_(key);
    1175 var values = this.keyMap_.get(key);
    1176 if (!values) {
    1177 this.keyMap_.set(key, (values = []));
    1178 }
    1179 values.push(value);
    1180 this.count_++;
    1181 return this;
    1182};
    1183
    1184
    1185/**
    1186 * Removes all the params with the given key.
    1187 * @param {string} key Name.
    1188 * @return {boolean} Whether any parameter was removed.
    1189 */
    1190goog.Uri.QueryData.prototype.remove = function(key) {
    1191 this.ensureKeyMapInitialized_();
    1192
    1193 key = this.getKeyName_(key);
    1194 if (this.keyMap_.containsKey(key)) {
    1195 this.invalidateCache_();
    1196
    1197 // Decrement parameter count.
    1198 this.count_ -= this.keyMap_.get(key).length;
    1199 return this.keyMap_.remove(key);
    1200 }
    1201 return false;
    1202};
    1203
    1204
    1205/**
    1206 * Clears the parameters.
    1207 */
    1208goog.Uri.QueryData.prototype.clear = function() {
    1209 this.invalidateCache_();
    1210 this.keyMap_ = null;
    1211 this.count_ = 0;
    1212};
    1213
    1214
    1215/**
    1216 * @return {boolean} Whether we have any parameters.
    1217 */
    1218goog.Uri.QueryData.prototype.isEmpty = function() {
    1219 this.ensureKeyMapInitialized_();
    1220 return this.count_ == 0;
    1221};
    1222
    1223
    1224/**
    1225 * Whether there is a parameter with the given name
    1226 * @param {string} key The parameter name to check for.
    1227 * @return {boolean} Whether there is a parameter with the given name.
    1228 */
    1229goog.Uri.QueryData.prototype.containsKey = function(key) {
    1230 this.ensureKeyMapInitialized_();
    1231 key = this.getKeyName_(key);
    1232 return this.keyMap_.containsKey(key);
    1233};
    1234
    1235
    1236/**
    1237 * Whether there is a parameter with the given value.
    1238 * @param {*} value The value to check for.
    1239 * @return {boolean} Whether there is a parameter with the given value.
    1240 */
    1241goog.Uri.QueryData.prototype.containsValue = function(value) {
    1242 // NOTE(arv): This solution goes through all the params even if it was the
    1243 // first param. We can get around this by not reusing code or by switching to
    1244 // iterators.
    1245 var vals = this.getValues();
    1246 return goog.array.contains(vals, value);
    1247};
    1248
    1249
    1250/**
    1251 * Returns all the keys of the parameters. If a key is used multiple times
    1252 * it will be included multiple times in the returned array
    1253 * @return {!Array.<string>} All the keys of the parameters.
    1254 */
    1255goog.Uri.QueryData.prototype.getKeys = function() {
    1256 this.ensureKeyMapInitialized_();
    1257 // We need to get the values to know how many keys to add.
    1258 var vals = /** @type {Array.<Array|*>} */ (this.keyMap_.getValues());
    1259 var keys = this.keyMap_.getKeys();
    1260 var rv = [];
    1261 for (var i = 0; i < keys.length; i++) {
    1262 var val = vals[i];
    1263 for (var j = 0; j < val.length; j++) {
    1264 rv.push(keys[i]);
    1265 }
    1266 }
    1267 return rv;
    1268};
    1269
    1270
    1271/**
    1272 * Returns all the values of the parameters with the given name. If the query
    1273 * data has no such key this will return an empty array. If no key is given
    1274 * all values wil be returned.
    1275 * @param {string=} opt_key The name of the parameter to get the values for.
    1276 * @return {!Array} All the values of the parameters with the given name.
    1277 */
    1278goog.Uri.QueryData.prototype.getValues = function(opt_key) {
    1279 this.ensureKeyMapInitialized_();
    1280 var rv = [];
    1281 if (goog.isString(opt_key)) {
    1282 if (this.containsKey(opt_key)) {
    1283 rv = goog.array.concat(rv, this.keyMap_.get(this.getKeyName_(opt_key)));
    1284 }
    1285 } else {
    1286 // Return all values.
    1287 var values = /** @type {Array.<Array|*>} */ (this.keyMap_.getValues());
    1288 for (var i = 0; i < values.length; i++) {
    1289 rv = goog.array.concat(rv, values[i]);
    1290 }
    1291 }
    1292 return rv;
    1293};
    1294
    1295
    1296/**
    1297 * Sets a key value pair and removes all other keys with the same value.
    1298 *
    1299 * @param {string} key Name.
    1300 * @param {*} value Value.
    1301 * @return {!goog.Uri.QueryData} Instance of this object.
    1302 */
    1303goog.Uri.QueryData.prototype.set = function(key, value) {
    1304 this.ensureKeyMapInitialized_();
    1305 this.invalidateCache_();
    1306
    1307 // TODO(user): This could be better written as
    1308 // this.remove(key), this.add(key, value), but that would reorder
    1309 // the key (since the key is first removed and then added at the
    1310 // end) and we would have to fix unit tests that depend on key
    1311 // ordering.
    1312 key = this.getKeyName_(key);
    1313 if (this.containsKey(key)) {
    1314 this.count_ -= this.keyMap_.get(key).length;
    1315 }
    1316 this.keyMap_.set(key, [value]);
    1317 this.count_++;
    1318 return this;
    1319};
    1320
    1321
    1322/**
    1323 * Returns the first value associated with the key. If the query data has no
    1324 * such key this will return undefined or the optional default.
    1325 * @param {string} key The name of the parameter to get the value for.
    1326 * @param {*=} opt_default The default value to return if the query data
    1327 * has no such key.
    1328 * @return {*} The first string value associated with the key, or opt_default
    1329 * if there's no value.
    1330 */
    1331goog.Uri.QueryData.prototype.get = function(key, opt_default) {
    1332 var values = key ? this.getValues(key) : [];
    1333 if (goog.Uri.preserveParameterTypesCompatibilityFlag) {
    1334 return values.length > 0 ? values[0] : opt_default;
    1335 } else {
    1336 return values.length > 0 ? String(values[0]) : opt_default;
    1337 }
    1338};
    1339
    1340
    1341/**
    1342 * Sets the values for a key. If the key already exists, this will
    1343 * override all of the existing values that correspond to the key.
    1344 * @param {string} key The key to set values for.
    1345 * @param {Array} values The values to set.
    1346 */
    1347goog.Uri.QueryData.prototype.setValues = function(key, values) {
    1348 this.remove(key);
    1349
    1350 if (values.length > 0) {
    1351 this.invalidateCache_();
    1352 this.keyMap_.set(this.getKeyName_(key), goog.array.clone(values));
    1353 this.count_ += values.length;
    1354 }
    1355};
    1356
    1357
    1358/**
    1359 * @return {string} Encoded query string.
    1360 * @override
    1361 */
    1362goog.Uri.QueryData.prototype.toString = function() {
    1363 if (this.encodedQuery_) {
    1364 return this.encodedQuery_;
    1365 }
    1366
    1367 if (!this.keyMap_) {
    1368 return '';
    1369 }
    1370
    1371 var sb = [];
    1372
    1373 // In the past, we use this.getKeys() and this.getVals(), but that
    1374 // generates a lot of allocations as compared to simply iterating
    1375 // over the keys.
    1376 var keys = this.keyMap_.getKeys();
    1377 for (var i = 0; i < keys.length; i++) {
    1378 var key = keys[i];
    1379 var encodedKey = goog.string.urlEncode(key);
    1380 var val = this.getValues(key);
    1381 for (var j = 0; j < val.length; j++) {
    1382 var param = encodedKey;
    1383 // Ensure that null and undefined are encoded into the url as
    1384 // literal strings.
    1385 if (val[j] !== '') {
    1386 param += '=' + goog.string.urlEncode(val[j]);
    1387 }
    1388 sb.push(param);
    1389 }
    1390 }
    1391
    1392 return this.encodedQuery_ = sb.join('&');
    1393};
    1394
    1395
    1396/**
    1397 * @return {string} Decoded query string.
    1398 */
    1399goog.Uri.QueryData.prototype.toDecodedString = function() {
    1400 return goog.Uri.decodeOrEmpty_(this.toString());
    1401};
    1402
    1403
    1404/**
    1405 * Invalidate the cache.
    1406 * @private
    1407 */
    1408goog.Uri.QueryData.prototype.invalidateCache_ = function() {
    1409 this.encodedQuery_ = null;
    1410};
    1411
    1412
    1413/**
    1414 * Removes all keys that are not in the provided list. (Modifies this object.)
    1415 * @param {Array.<string>} keys The desired keys.
    1416 * @return {!goog.Uri.QueryData} a reference to this object.
    1417 */
    1418goog.Uri.QueryData.prototype.filterKeys = function(keys) {
    1419 this.ensureKeyMapInitialized_();
    1420 this.keyMap_.forEach(
    1421 function(value, key) {
    1422 if (!goog.array.contains(keys, key)) {
    1423 this.remove(key);
    1424 }
    1425 }, this);
    1426 return this;
    1427};
    1428
    1429
    1430/**
    1431 * Clone the query data instance.
    1432 * @return {!goog.Uri.QueryData} New instance of the QueryData object.
    1433 */
    1434goog.Uri.QueryData.prototype.clone = function() {
    1435 var rv = new goog.Uri.QueryData();
    1436 rv.encodedQuery_ = this.encodedQuery_;
    1437 if (this.keyMap_) {
    1438 rv.keyMap_ = this.keyMap_.clone();
    1439 rv.count_ = this.count_;
    1440 }
    1441 return rv;
    1442};
    1443
    1444
    1445/**
    1446 * Helper function to get the key name from a JavaScript object. Converts
    1447 * the object to a string, and to lower case if necessary.
    1448 * @private
    1449 * @param {*} arg The object to get a key name from.
    1450 * @return {string} valid key name which can be looked up in #keyMap_.
    1451 */
    1452goog.Uri.QueryData.prototype.getKeyName_ = function(arg) {
    1453 var keyName = String(arg);
    1454 if (this.ignoreCase_) {
    1455 keyName = keyName.toLowerCase();
    1456 }
    1457 return keyName;
    1458};
    1459
    1460
    1461/**
    1462 * Ignore case in parameter names.
    1463 * NOTE: If there are already key/value pairs in the QueryData, and
    1464 * ignoreCase_ is set to false, the keys will all be lower-cased.
    1465 * @param {boolean} ignoreCase whether this goog.Uri should ignore case.
    1466 */
    1467goog.Uri.QueryData.prototype.setIgnoreCase = function(ignoreCase) {
    1468 var resetKeys = ignoreCase && !this.ignoreCase_;
    1469 if (resetKeys) {
    1470 this.ensureKeyMapInitialized_();
    1471 this.invalidateCache_();
    1472 this.keyMap_.forEach(
    1473 function(value, key) {
    1474 var lowerCase = key.toLowerCase();
    1475 if (key != lowerCase) {
    1476 this.remove(key);
    1477 this.setValues(lowerCase, value);
    1478 }
    1479 }, this);
    1480 }
    1481 this.ignoreCase_ = ignoreCase;
    1482};
    1483
    1484
    1485/**
    1486 * Extends a query data object with another query data or map like object. This
    1487 * operates 'in-place', it does not create a new QueryData object.
    1488 *
    1489 * @param {...(goog.Uri.QueryData|goog.structs.Map|Object)} var_args The object
    1490 * from which key value pairs will be copied.
    1491 */
    1492goog.Uri.QueryData.prototype.extend = function(var_args) {
    1493 for (var i = 0; i < arguments.length; i++) {
    1494 var data = arguments[i];
    1495 goog.structs.forEach(data,
    1496 /** @this {goog.Uri.QueryData} */
    1497 function(value, key) {
    1498 this.add(key, value);
    1499 }, this);
    1500 }
    1501};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/uri/utils.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/uri/utils.js.src.html new file mode 100644 index 0000000..8ffa2df --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/uri/utils.js.src.html @@ -0,0 +1 @@ +utils.js

    lib/goog/uri/utils.js

    1// Copyright 2008 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Simple utilities for dealing with URI strings.
    17 *
    18 * This is intended to be a lightweight alternative to constructing goog.Uri
    19 * objects. Whereas goog.Uri adds several kilobytes to the binary regardless
    20 * of how much of its functionality you use, this is designed to be a set of
    21 * mostly-independent utilities so that the compiler includes only what is
    22 * necessary for the task. Estimated savings of porting is 5k pre-gzip and
    23 * 1.5k post-gzip. To ensure the savings remain, future developers should
    24 * avoid adding new functionality to existing functions, but instead create
    25 * new ones and factor out shared code.
    26 *
    27 * Many of these utilities have limited functionality, tailored to common
    28 * cases. The query parameter utilities assume that the parameter keys are
    29 * already encoded, since most keys are compile-time alphanumeric strings. The
    30 * query parameter mutation utilities also do not tolerate fragment identifiers.
    31 *
    32 * By design, these functions can be slower than goog.Uri equivalents.
    33 * Repeated calls to some of functions may be quadratic in behavior for IE,
    34 * although the effect is somewhat limited given the 2kb limit.
    35 *
    36 * One advantage of the limited functionality here is that this approach is
    37 * less sensitive to differences in URI encodings than goog.Uri, since these
    38 * functions modify the strings in place, rather than decoding and
    39 * re-encoding.
    40 *
    41 * Uses features of RFC 3986 for parsing/formatting URIs:
    42 * http://www.ietf.org/rfc/rfc3986.txt
    43 *
    44 * @author gboyer@google.com (Garrett Boyer) - The "lightened" design.
    45 * @author msamuel@google.com (Mike Samuel) - Domain knowledge and regexes.
    46 */
    47
    48goog.provide('goog.uri.utils');
    49goog.provide('goog.uri.utils.ComponentIndex');
    50goog.provide('goog.uri.utils.QueryArray');
    51goog.provide('goog.uri.utils.QueryValue');
    52goog.provide('goog.uri.utils.StandardQueryParam');
    53
    54goog.require('goog.asserts');
    55goog.require('goog.string');
    56goog.require('goog.userAgent');
    57
    58
    59/**
    60 * Character codes inlined to avoid object allocations due to charCode.
    61 * @enum {number}
    62 * @private
    63 */
    64goog.uri.utils.CharCode_ = {
    65 AMPERSAND: 38,
    66 EQUAL: 61,
    67 HASH: 35,
    68 QUESTION: 63
    69};
    70
    71
    72/**
    73 * Builds a URI string from already-encoded parts.
    74 *
    75 * No encoding is performed. Any component may be omitted as either null or
    76 * undefined.
    77 *
    78 * @param {?string=} opt_scheme The scheme such as 'http'.
    79 * @param {?string=} opt_userInfo The user name before the '@'.
    80 * @param {?string=} opt_domain The domain such as 'www.google.com', already
    81 * URI-encoded.
    82 * @param {(string|number|null)=} opt_port The port number.
    83 * @param {?string=} opt_path The path, already URI-encoded. If it is not
    84 * empty, it must begin with a slash.
    85 * @param {?string=} opt_queryData The URI-encoded query data.
    86 * @param {?string=} opt_fragment The URI-encoded fragment identifier.
    87 * @return {string} The fully combined URI.
    88 */
    89goog.uri.utils.buildFromEncodedParts = function(opt_scheme, opt_userInfo,
    90 opt_domain, opt_port, opt_path, opt_queryData, opt_fragment) {
    91 var out = '';
    92
    93 if (opt_scheme) {
    94 out += opt_scheme + ':';
    95 }
    96
    97 if (opt_domain) {
    98 out += '//';
    99
    100 if (opt_userInfo) {
    101 out += opt_userInfo + '@';
    102 }
    103
    104 out += opt_domain;
    105
    106 if (opt_port) {
    107 out += ':' + opt_port;
    108 }
    109 }
    110
    111 if (opt_path) {
    112 out += opt_path;
    113 }
    114
    115 if (opt_queryData) {
    116 out += '?' + opt_queryData;
    117 }
    118
    119 if (opt_fragment) {
    120 out += '#' + opt_fragment;
    121 }
    122
    123 return out;
    124};
    125
    126
    127/**
    128 * A regular expression for breaking a URI into its component parts.
    129 *
    130 * {@link http://www.ietf.org/rfc/rfc3986.txt} says in Appendix B
    131 * As the "first-match-wins" algorithm is identical to the "greedy"
    132 * disambiguation method used by POSIX regular expressions, it is natural and
    133 * commonplace to use a regular expression for parsing the potential five
    134 * components of a URI reference.
    135 *
    136 * The following line is the regular expression for breaking-down a
    137 * well-formed URI reference into its components.
    138 *
    139 * <pre>
    140 * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
    141 * 12 3 4 5 6 7 8 9
    142 * </pre>
    143 *
    144 * The numbers in the second line above are only to assist readability; they
    145 * indicate the reference points for each subexpression (i.e., each paired
    146 * parenthesis). We refer to the value matched for subexpression <n> as $<n>.
    147 * For example, matching the above expression to
    148 * <pre>
    149 * http://www.ics.uci.edu/pub/ietf/uri/#Related
    150 * </pre>
    151 * results in the following subexpression matches:
    152 * <pre>
    153 * $1 = http:
    154 * $2 = http
    155 * $3 = //www.ics.uci.edu
    156 * $4 = www.ics.uci.edu
    157 * $5 = /pub/ietf/uri/
    158 * $6 = <undefined>
    159 * $7 = <undefined>
    160 * $8 = #Related
    161 * $9 = Related
    162 * </pre>
    163 * where <undefined> indicates that the component is not present, as is the
    164 * case for the query component in the above example. Therefore, we can
    165 * determine the value of the five components as
    166 * <pre>
    167 * scheme = $2
    168 * authority = $4
    169 * path = $5
    170 * query = $7
    171 * fragment = $9
    172 * </pre>
    173 *
    174 * The regular expression has been modified slightly to expose the
    175 * userInfo, domain, and port separately from the authority.
    176 * The modified version yields
    177 * <pre>
    178 * $1 = http scheme
    179 * $2 = <undefined> userInfo -\
    180 * $3 = www.ics.uci.edu domain | authority
    181 * $4 = <undefined> port -/
    182 * $5 = /pub/ietf/uri/ path
    183 * $6 = <undefined> query without ?
    184 * $7 = Related fragment without #
    185 * </pre>
    186 * @type {!RegExp}
    187 * @private
    188 */
    189goog.uri.utils.splitRe_ = new RegExp(
    190 '^' +
    191 '(?:' +
    192 '([^:/?#.]+)' + // scheme - ignore special characters
    193 // used by other URL parts such as :,
    194 // ?, /, #, and .
    195 ':)?' +
    196 '(?://' +
    197 '(?:([^/?#]*)@)?' + // userInfo
    198 '([^/#?]*?)' + // domain
    199 '(?::([0-9]+))?' + // port
    200 '(?=[/#?]|$)' + // authority-terminating character
    201 ')?' +
    202 '([^?#]+)?' + // path
    203 '(?:\\?([^#]*))?' + // query
    204 '(?:#(.*))?' + // fragment
    205 '$');
    206
    207
    208/**
    209 * The index of each URI component in the return value of goog.uri.utils.split.
    210 * @enum {number}
    211 */
    212goog.uri.utils.ComponentIndex = {
    213 SCHEME: 1,
    214 USER_INFO: 2,
    215 DOMAIN: 3,
    216 PORT: 4,
    217 PATH: 5,
    218 QUERY_DATA: 6,
    219 FRAGMENT: 7
    220};
    221
    222
    223/**
    224 * Splits a URI into its component parts.
    225 *
    226 * Each component can be accessed via the component indices; for example:
    227 * <pre>
    228 * goog.uri.utils.split(someStr)[goog.uri.utils.CompontentIndex.QUERY_DATA];
    229 * </pre>
    230 *
    231 * @param {string} uri The URI string to examine.
    232 * @return {!Array.<string|undefined>} Each component still URI-encoded.
    233 * Each component that is present will contain the encoded value, whereas
    234 * components that are not present will be undefined or empty, depending
    235 * on the browser's regular expression implementation. Never null, since
    236 * arbitrary strings may still look like path names.
    237 */
    238goog.uri.utils.split = function(uri) {
    239 goog.uri.utils.phishingProtection_();
    240
    241 // See @return comment -- never null.
    242 return /** @type {!Array.<string|undefined>} */ (
    243 uri.match(goog.uri.utils.splitRe_));
    244};
    245
    246
    247/**
    248 * Safari has a nasty bug where if you have an http URL with a username, e.g.,
    249 * http://evil.com%2F@google.com/
    250 * Safari will report that window.location.href is
    251 * http://evil.com/google.com/
    252 * so that anyone who tries to parse the domain of that URL will get
    253 * the wrong domain. We've seen exploits where people use this to trick
    254 * Safari into loading resources from evil domains.
    255 *
    256 * To work around this, we run a little "Safari phishing check", and throw
    257 * an exception if we see this happening.
    258 *
    259 * There is no convenient place to put this check. We apply it to
    260 * anyone doing URI parsing on Webkit. We're not happy about this, but
    261 * it fixes the problem.
    262 *
    263 * This should be removed once Safari fixes their bug.
    264 *
    265 * Exploit reported by Masato Kinugawa.
    266 *
    267 * @type {boolean}
    268 * @private
    269 */
    270goog.uri.utils.needsPhishingProtection_ = goog.userAgent.WEBKIT;
    271
    272
    273/**
    274 * Check to see if the user is being phished.
    275 * @private
    276 */
    277goog.uri.utils.phishingProtection_ = function() {
    278 if (goog.uri.utils.needsPhishingProtection_) {
    279 // Turn protection off, so that we don't recurse.
    280 goog.uri.utils.needsPhishingProtection_ = false;
    281
    282 // Use quoted access, just in case the user isn't using location externs.
    283 var location = goog.global['location'];
    284 if (location) {
    285 var href = location['href'];
    286 if (href) {
    287 var domain = goog.uri.utils.getDomain(href);
    288 if (domain && domain != location['hostname']) {
    289 // Phishing attack
    290 goog.uri.utils.needsPhishingProtection_ = true;
    291 throw Error();
    292 }
    293 }
    294 }
    295 }
    296};
    297
    298
    299/**
    300 * @param {?string} uri A possibly null string.
    301 * @return {?string} The string URI-decoded, or null if uri is null.
    302 * @private
    303 */
    304goog.uri.utils.decodeIfPossible_ = function(uri) {
    305 return uri && decodeURIComponent(uri);
    306};
    307
    308
    309/**
    310 * Gets a URI component by index.
    311 *
    312 * It is preferred to use the getPathEncoded() variety of functions ahead,
    313 * since they are more readable.
    314 *
    315 * @param {goog.uri.utils.ComponentIndex} componentIndex The component index.
    316 * @param {string} uri The URI to examine.
    317 * @return {?string} The still-encoded component, or null if the component
    318 * is not present.
    319 * @private
    320 */
    321goog.uri.utils.getComponentByIndex_ = function(componentIndex, uri) {
    322 // Convert undefined, null, and empty string into null.
    323 return goog.uri.utils.split(uri)[componentIndex] || null;
    324};
    325
    326
    327/**
    328 * @param {string} uri The URI to examine.
    329 * @return {?string} The protocol or scheme, or null if none. Does not
    330 * include trailing colons or slashes.
    331 */
    332goog.uri.utils.getScheme = function(uri) {
    333 return goog.uri.utils.getComponentByIndex_(
    334 goog.uri.utils.ComponentIndex.SCHEME, uri);
    335};
    336
    337
    338/**
    339 * Gets the effective scheme for the URL. If the URL is relative then the
    340 * scheme is derived from the page's location.
    341 * @param {string} uri The URI to examine.
    342 * @return {string} The protocol or scheme, always lower case.
    343 */
    344goog.uri.utils.getEffectiveScheme = function(uri) {
    345 var scheme = goog.uri.utils.getScheme(uri);
    346 if (!scheme && self.location) {
    347 var protocol = self.location.protocol;
    348 scheme = protocol.substr(0, protocol.length - 1);
    349 }
    350 // NOTE: When called from a web worker in Firefox 3.5, location maybe null.
    351 // All other browsers with web workers support self.location from the worker.
    352 return scheme ? scheme.toLowerCase() : '';
    353};
    354
    355
    356/**
    357 * @param {string} uri The URI to examine.
    358 * @return {?string} The user name still encoded, or null if none.
    359 */
    360goog.uri.utils.getUserInfoEncoded = function(uri) {
    361 return goog.uri.utils.getComponentByIndex_(
    362 goog.uri.utils.ComponentIndex.USER_INFO, uri);
    363};
    364
    365
    366/**
    367 * @param {string} uri The URI to examine.
    368 * @return {?string} The decoded user info, or null if none.
    369 */
    370goog.uri.utils.getUserInfo = function(uri) {
    371 return goog.uri.utils.decodeIfPossible_(
    372 goog.uri.utils.getUserInfoEncoded(uri));
    373};
    374
    375
    376/**
    377 * @param {string} uri The URI to examine.
    378 * @return {?string} The domain name still encoded, or null if none.
    379 */
    380goog.uri.utils.getDomainEncoded = function(uri) {
    381 return goog.uri.utils.getComponentByIndex_(
    382 goog.uri.utils.ComponentIndex.DOMAIN, uri);
    383};
    384
    385
    386/**
    387 * @param {string} uri The URI to examine.
    388 * @return {?string} The decoded domain, or null if none.
    389 */
    390goog.uri.utils.getDomain = function(uri) {
    391 return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getDomainEncoded(uri));
    392};
    393
    394
    395/**
    396 * @param {string} uri The URI to examine.
    397 * @return {?number} The port number, or null if none.
    398 */
    399goog.uri.utils.getPort = function(uri) {
    400 // Coerce to a number. If the result of getComponentByIndex_ is null or
    401 // non-numeric, the number coersion yields NaN. This will then return
    402 // null for all non-numeric cases (though also zero, which isn't a relevant
    403 // port number).
    404 return Number(goog.uri.utils.getComponentByIndex_(
    405 goog.uri.utils.ComponentIndex.PORT, uri)) || null;
    406};
    407
    408
    409/**
    410 * @param {string} uri The URI to examine.
    411 * @return {?string} The path still encoded, or null if none. Includes the
    412 * leading slash, if any.
    413 */
    414goog.uri.utils.getPathEncoded = function(uri) {
    415 return goog.uri.utils.getComponentByIndex_(
    416 goog.uri.utils.ComponentIndex.PATH, uri);
    417};
    418
    419
    420/**
    421 * @param {string} uri The URI to examine.
    422 * @return {?string} The decoded path, or null if none. Includes the leading
    423 * slash, if any.
    424 */
    425goog.uri.utils.getPath = function(uri) {
    426 return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getPathEncoded(uri));
    427};
    428
    429
    430/**
    431 * @param {string} uri The URI to examine.
    432 * @return {?string} The query data still encoded, or null if none. Does not
    433 * include the question mark itself.
    434 */
    435goog.uri.utils.getQueryData = function(uri) {
    436 return goog.uri.utils.getComponentByIndex_(
    437 goog.uri.utils.ComponentIndex.QUERY_DATA, uri);
    438};
    439
    440
    441/**
    442 * @param {string} uri The URI to examine.
    443 * @return {?string} The fragment identifier, or null if none. Does not
    444 * include the hash mark itself.
    445 */
    446goog.uri.utils.getFragmentEncoded = function(uri) {
    447 // The hash mark may not appear in any other part of the URL.
    448 var hashIndex = uri.indexOf('#');
    449 return hashIndex < 0 ? null : uri.substr(hashIndex + 1);
    450};
    451
    452
    453/**
    454 * @param {string} uri The URI to examine.
    455 * @param {?string} fragment The encoded fragment identifier, or null if none.
    456 * Does not include the hash mark itself.
    457 * @return {string} The URI with the fragment set.
    458 */
    459goog.uri.utils.setFragmentEncoded = function(uri, fragment) {
    460 return goog.uri.utils.removeFragment(uri) + (fragment ? '#' + fragment : '');
    461};
    462
    463
    464/**
    465 * @param {string} uri The URI to examine.
    466 * @return {?string} The decoded fragment identifier, or null if none. Does
    467 * not include the hash mark.
    468 */
    469goog.uri.utils.getFragment = function(uri) {
    470 return goog.uri.utils.decodeIfPossible_(
    471 goog.uri.utils.getFragmentEncoded(uri));
    472};
    473
    474
    475/**
    476 * Extracts everything up to the port of the URI.
    477 * @param {string} uri The URI string.
    478 * @return {string} Everything up to and including the port.
    479 */
    480goog.uri.utils.getHost = function(uri) {
    481 var pieces = goog.uri.utils.split(uri);
    482 return goog.uri.utils.buildFromEncodedParts(
    483 pieces[goog.uri.utils.ComponentIndex.SCHEME],
    484 pieces[goog.uri.utils.ComponentIndex.USER_INFO],
    485 pieces[goog.uri.utils.ComponentIndex.DOMAIN],
    486 pieces[goog.uri.utils.ComponentIndex.PORT]);
    487};
    488
    489
    490/**
    491 * Extracts the path of the URL and everything after.
    492 * @param {string} uri The URI string.
    493 * @return {string} The URI, starting at the path and including the query
    494 * parameters and fragment identifier.
    495 */
    496goog.uri.utils.getPathAndAfter = function(uri) {
    497 var pieces = goog.uri.utils.split(uri);
    498 return goog.uri.utils.buildFromEncodedParts(null, null, null, null,
    499 pieces[goog.uri.utils.ComponentIndex.PATH],
    500 pieces[goog.uri.utils.ComponentIndex.QUERY_DATA],
    501 pieces[goog.uri.utils.ComponentIndex.FRAGMENT]);
    502};
    503
    504
    505/**
    506 * Gets the URI with the fragment identifier removed.
    507 * @param {string} uri The URI to examine.
    508 * @return {string} Everything preceding the hash mark.
    509 */
    510goog.uri.utils.removeFragment = function(uri) {
    511 // The hash mark may not appear in any other part of the URL.
    512 var hashIndex = uri.indexOf('#');
    513 return hashIndex < 0 ? uri : uri.substr(0, hashIndex);
    514};
    515
    516
    517/**
    518 * Ensures that two URI's have the exact same domain, scheme, and port.
    519 *
    520 * Unlike the version in goog.Uri, this checks protocol, and therefore is
    521 * suitable for checking against the browser's same-origin policy.
    522 *
    523 * @param {string} uri1 The first URI.
    524 * @param {string} uri2 The second URI.
    525 * @return {boolean} Whether they have the same domain and port.
    526 */
    527goog.uri.utils.haveSameDomain = function(uri1, uri2) {
    528 var pieces1 = goog.uri.utils.split(uri1);
    529 var pieces2 = goog.uri.utils.split(uri2);
    530 return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] ==
    531 pieces2[goog.uri.utils.ComponentIndex.DOMAIN] &&
    532 pieces1[goog.uri.utils.ComponentIndex.SCHEME] ==
    533 pieces2[goog.uri.utils.ComponentIndex.SCHEME] &&
    534 pieces1[goog.uri.utils.ComponentIndex.PORT] ==
    535 pieces2[goog.uri.utils.ComponentIndex.PORT];
    536};
    537
    538
    539/**
    540 * Asserts that there are no fragment or query identifiers, only in uncompiled
    541 * mode.
    542 * @param {string} uri The URI to examine.
    543 * @private
    544 */
    545goog.uri.utils.assertNoFragmentsOrQueries_ = function(uri) {
    546 // NOTE: would use goog.asserts here, but jscompiler doesn't know that
    547 // indexOf has no side effects.
    548 if (goog.DEBUG && (uri.indexOf('#') >= 0 || uri.indexOf('?') >= 0)) {
    549 throw Error('goog.uri.utils: Fragment or query identifiers are not ' +
    550 'supported: [' + uri + ']');
    551 }
    552};
    553
    554
    555/**
    556 * Supported query parameter values by the parameter serializing utilities.
    557 *
    558 * If a value is null or undefined, the key-value pair is skipped, as an easy
    559 * way to omit parameters conditionally. Non-array parameters are converted
    560 * to a string and URI encoded. Array values are expanded into multiple
    561 * &key=value pairs, with each element stringized and URI-encoded.
    562 *
    563 * @typedef {*}
    564 */
    565goog.uri.utils.QueryValue;
    566
    567
    568/**
    569 * An array representing a set of query parameters with alternating keys
    570 * and values.
    571 *
    572 * Keys are assumed to be URI encoded already and live at even indices. See
    573 * goog.uri.utils.QueryValue for details on how parameter values are encoded.
    574 *
    575 * Example:
    576 * <pre>
    577 * var data = [
    578 * // Simple param: ?name=BobBarker
    579 * 'name', 'BobBarker',
    580 * // Conditional param -- may be omitted entirely.
    581 * 'specialDietaryNeeds', hasDietaryNeeds() ? getDietaryNeeds() : null,
    582 * // Multi-valued param: &house=LosAngeles&house=NewYork&house=null
    583 * 'house', ['LosAngeles', 'NewYork', null]
    584 * ];
    585 * </pre>
    586 *
    587 * @typedef {!Array.<string|goog.uri.utils.QueryValue>}
    588 */
    589goog.uri.utils.QueryArray;
    590
    591
    592/**
    593 * Appends a URI and query data in a string buffer with special preconditions.
    594 *
    595 * Internal implementation utility, performing very few object allocations.
    596 *
    597 * @param {!Array.<string|undefined>} buffer A string buffer. The first element
    598 * must be the base URI, and may have a fragment identifier. If the array
    599 * contains more than one element, the second element must be an ampersand,
    600 * and may be overwritten, depending on the base URI. Undefined elements
    601 * are treated as empty-string.
    602 * @return {string} The concatenated URI and query data.
    603 * @private
    604 */
    605goog.uri.utils.appendQueryData_ = function(buffer) {
    606 if (buffer[1]) {
    607 // At least one query parameter was added. We need to check the
    608 // punctuation mark, which is currently an ampersand, and also make sure
    609 // there aren't any interfering fragment identifiers.
    610 var baseUri = /** @type {string} */ (buffer[0]);
    611 var hashIndex = baseUri.indexOf('#');
    612 if (hashIndex >= 0) {
    613 // Move the fragment off the base part of the URI into the end.
    614 buffer.push(baseUri.substr(hashIndex));
    615 buffer[0] = baseUri = baseUri.substr(0, hashIndex);
    616 }
    617 var questionIndex = baseUri.indexOf('?');
    618 if (questionIndex < 0) {
    619 // No question mark, so we need a question mark instead of an ampersand.
    620 buffer[1] = '?';
    621 } else if (questionIndex == baseUri.length - 1) {
    622 // Question mark is the very last character of the existing URI, so don't
    623 // append an additional delimiter.
    624 buffer[1] = undefined;
    625 }
    626 }
    627
    628 return buffer.join('');
    629};
    630
    631
    632/**
    633 * Appends key=value pairs to an array, supporting multi-valued objects.
    634 * @param {string} key The key prefix.
    635 * @param {goog.uri.utils.QueryValue} value The value to serialize.
    636 * @param {!Array.<string>} pairs The array to which the 'key=value' strings
    637 * should be appended.
    638 * @private
    639 */
    640goog.uri.utils.appendKeyValuePairs_ = function(key, value, pairs) {
    641 if (goog.isArray(value)) {
    642 // Convince the compiler it's an array.
    643 goog.asserts.assertArray(value);
    644 for (var j = 0; j < value.length; j++) {
    645 // Convert to string explicitly, to short circuit the null and array
    646 // logic in this function -- this ensures that null and undefined get
    647 // written as literal 'null' and 'undefined', and arrays don't get
    648 // expanded out but instead encoded in the default way.
    649 goog.uri.utils.appendKeyValuePairs_(key, String(value[j]), pairs);
    650 }
    651 } else if (value != null) {
    652 // Skip a top-level null or undefined entirely.
    653 pairs.push('&', key,
    654 // Check for empty string. Zero gets encoded into the url as literal
    655 // strings. For empty string, skip the equal sign, to be consistent
    656 // with UriBuilder.java.
    657 value === '' ? '' : '=',
    658 goog.string.urlEncode(value));
    659 }
    660};
    661
    662
    663/**
    664 * Builds a buffer of query data from a sequence of alternating keys and values.
    665 *
    666 * @param {!Array.<string|undefined>} buffer A string buffer to append to. The
    667 * first element appended will be an '&', and may be replaced by the caller.
    668 * @param {goog.uri.utils.QueryArray|Arguments} keysAndValues An array with
    669 * alternating keys and values -- see the typedef.
    670 * @param {number=} opt_startIndex A start offset into the arary, defaults to 0.
    671 * @return {!Array.<string|undefined>} The buffer argument.
    672 * @private
    673 */
    674goog.uri.utils.buildQueryDataBuffer_ = function(
    675 buffer, keysAndValues, opt_startIndex) {
    676 goog.asserts.assert(Math.max(keysAndValues.length - (opt_startIndex || 0),
    677 0) % 2 == 0, 'goog.uri.utils: Key/value lists must be even in length.');
    678
    679 for (var i = opt_startIndex || 0; i < keysAndValues.length; i += 2) {
    680 goog.uri.utils.appendKeyValuePairs_(
    681 keysAndValues[i], keysAndValues[i + 1], buffer);
    682 }
    683
    684 return buffer;
    685};
    686
    687
    688/**
    689 * Builds a query data string from a sequence of alternating keys and values.
    690 * Currently generates "&key&" for empty args.
    691 *
    692 * @param {goog.uri.utils.QueryArray} keysAndValues Alternating keys and
    693 * values. See the typedef.
    694 * @param {number=} opt_startIndex A start offset into the arary, defaults to 0.
    695 * @return {string} The encoded query string, in the form 'a=1&b=2'.
    696 */
    697goog.uri.utils.buildQueryData = function(keysAndValues, opt_startIndex) {
    698 var buffer = goog.uri.utils.buildQueryDataBuffer_(
    699 [], keysAndValues, opt_startIndex);
    700 buffer[0] = ''; // Remove the leading ampersand.
    701 return buffer.join('');
    702};
    703
    704
    705/**
    706 * Builds a buffer of query data from a map.
    707 *
    708 * @param {!Array.<string|undefined>} buffer A string buffer to append to. The
    709 * first element appended will be an '&', and may be replaced by the caller.
    710 * @param {Object.<goog.uri.utils.QueryValue>} map An object where keys are
    711 * URI-encoded parameter keys, and the values conform to the contract
    712 * specified in the goog.uri.utils.QueryValue typedef.
    713 * @return {!Array.<string|undefined>} The buffer argument.
    714 * @private
    715 */
    716goog.uri.utils.buildQueryDataBufferFromMap_ = function(buffer, map) {
    717 for (var key in map) {
    718 goog.uri.utils.appendKeyValuePairs_(key, map[key], buffer);
    719 }
    720
    721 return buffer;
    722};
    723
    724
    725/**
    726 * Builds a query data string from a map.
    727 * Currently generates "&key&" for empty args.
    728 *
    729 * @param {Object} map An object where keys are URI-encoded parameter keys,
    730 * and the values are arbitrary types or arrays. Keys with a null value
    731 * are dropped.
    732 * @return {string} The encoded query string, in the form 'a=1&b=2'.
    733 */
    734goog.uri.utils.buildQueryDataFromMap = function(map) {
    735 var buffer = goog.uri.utils.buildQueryDataBufferFromMap_([], map);
    736 buffer[0] = '';
    737 return buffer.join('');
    738};
    739
    740
    741/**
    742 * Appends URI parameters to an existing URI.
    743 *
    744 * The variable arguments may contain alternating keys and values. Keys are
    745 * assumed to be already URI encoded. The values should not be URI-encoded,
    746 * and will instead be encoded by this function.
    747 * <pre>
    748 * appendParams('http://www.foo.com?existing=true',
    749 * 'key1', 'value1',
    750 * 'key2', 'value?willBeEncoded',
    751 * 'key3', ['valueA', 'valueB', 'valueC'],
    752 * 'key4', null);
    753 * result: 'http://www.foo.com?existing=true&' +
    754 * 'key1=value1&' +
    755 * 'key2=value%3FwillBeEncoded&' +
    756 * 'key3=valueA&key3=valueB&key3=valueC'
    757 * </pre>
    758 *
    759 * A single call to this function will not exhibit quadratic behavior in IE,
    760 * whereas multiple repeated calls may, although the effect is limited by
    761 * fact that URL's generally can't exceed 2kb.
    762 *
    763 * @param {string} uri The original URI, which may already have query data.
    764 * @param {...(goog.uri.utils.QueryArray|string|goog.uri.utils.QueryValue)} var_args
    765 * An array or argument list conforming to goog.uri.utils.QueryArray.
    766 * @return {string} The URI with all query parameters added.
    767 */
    768goog.uri.utils.appendParams = function(uri, var_args) {
    769 return goog.uri.utils.appendQueryData_(
    770 arguments.length == 2 ?
    771 goog.uri.utils.buildQueryDataBuffer_([uri], arguments[1], 0) :
    772 goog.uri.utils.buildQueryDataBuffer_([uri], arguments, 1));
    773};
    774
    775
    776/**
    777 * Appends query parameters from a map.
    778 *
    779 * @param {string} uri The original URI, which may already have query data.
    780 * @param {Object} map An object where keys are URI-encoded parameter keys,
    781 * and the values are arbitrary types or arrays. Keys with a null value
    782 * are dropped.
    783 * @return {string} The new parameters.
    784 */
    785goog.uri.utils.appendParamsFromMap = function(uri, map) {
    786 return goog.uri.utils.appendQueryData_(
    787 goog.uri.utils.buildQueryDataBufferFromMap_([uri], map));
    788};
    789
    790
    791/**
    792 * Appends a single URI parameter.
    793 *
    794 * Repeated calls to this can exhibit quadratic behavior in IE6 due to the
    795 * way string append works, though it should be limited given the 2kb limit.
    796 *
    797 * @param {string} uri The original URI, which may already have query data.
    798 * @param {string} key The key, which must already be URI encoded.
    799 * @param {*=} opt_value The value, which will be stringized and encoded
    800 * (assumed not already to be encoded). If omitted, undefined, or null, the
    801 * key will be added as a valueless parameter.
    802 * @return {string} The URI with the query parameter added.
    803 */
    804goog.uri.utils.appendParam = function(uri, key, opt_value) {
    805 var paramArr = [uri, '&', key];
    806 if (goog.isDefAndNotNull(opt_value)) {
    807 paramArr.push('=', goog.string.urlEncode(opt_value));
    808 }
    809 return goog.uri.utils.appendQueryData_(paramArr);
    810};
    811
    812
    813/**
    814 * Finds the next instance of a query parameter with the specified name.
    815 *
    816 * Does not instantiate any objects.
    817 *
    818 * @param {string} uri The URI to search. May contain a fragment identifier
    819 * if opt_hashIndex is specified.
    820 * @param {number} startIndex The index to begin searching for the key at. A
    821 * match may be found even if this is one character after the ampersand.
    822 * @param {string} keyEncoded The URI-encoded key.
    823 * @param {number} hashOrEndIndex Index to stop looking at. If a hash
    824 * mark is present, it should be its index, otherwise it should be the
    825 * length of the string.
    826 * @return {number} The position of the first character in the key's name,
    827 * immediately after either a question mark or a dot.
    828 * @private
    829 */
    830goog.uri.utils.findParam_ = function(
    831 uri, startIndex, keyEncoded, hashOrEndIndex) {
    832 var index = startIndex;
    833 var keyLength = keyEncoded.length;
    834
    835 // Search for the key itself and post-filter for surronuding punctuation,
    836 // rather than expensively building a regexp.
    837 while ((index = uri.indexOf(keyEncoded, index)) >= 0 &&
    838 index < hashOrEndIndex) {
    839 var precedingChar = uri.charCodeAt(index - 1);
    840 // Ensure that the preceding character is '&' or '?'.
    841 if (precedingChar == goog.uri.utils.CharCode_.AMPERSAND ||
    842 precedingChar == goog.uri.utils.CharCode_.QUESTION) {
    843 // Ensure the following character is '&', '=', '#', or NaN
    844 // (end of string).
    845 var followingChar = uri.charCodeAt(index + keyLength);
    846 if (!followingChar ||
    847 followingChar == goog.uri.utils.CharCode_.EQUAL ||
    848 followingChar == goog.uri.utils.CharCode_.AMPERSAND ||
    849 followingChar == goog.uri.utils.CharCode_.HASH) {
    850 return index;
    851 }
    852 }
    853 index += keyLength + 1;
    854 }
    855
    856 return -1;
    857};
    858
    859
    860/**
    861 * Regular expression for finding a hash mark or end of string.
    862 * @type {RegExp}
    863 * @private
    864 */
    865goog.uri.utils.hashOrEndRe_ = /#|$/;
    866
    867
    868/**
    869 * Determines if the URI contains a specific key.
    870 *
    871 * Performs no object instantiations.
    872 *
    873 * @param {string} uri The URI to process. May contain a fragment
    874 * identifier.
    875 * @param {string} keyEncoded The URI-encoded key. Case-sensitive.
    876 * @return {boolean} Whether the key is present.
    877 */
    878goog.uri.utils.hasParam = function(uri, keyEncoded) {
    879 return goog.uri.utils.findParam_(uri, 0, keyEncoded,
    880 uri.search(goog.uri.utils.hashOrEndRe_)) >= 0;
    881};
    882
    883
    884/**
    885 * Gets the first value of a query parameter.
    886 * @param {string} uri The URI to process. May contain a fragment.
    887 * @param {string} keyEncoded The URI-encoded key. Case-sensitive.
    888 * @return {?string} The first value of the parameter (URI-decoded), or null
    889 * if the parameter is not found.
    890 */
    891goog.uri.utils.getParamValue = function(uri, keyEncoded) {
    892 var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);
    893 var foundIndex = goog.uri.utils.findParam_(
    894 uri, 0, keyEncoded, hashOrEndIndex);
    895
    896 if (foundIndex < 0) {
    897 return null;
    898 } else {
    899 var endPosition = uri.indexOf('&', foundIndex);
    900 if (endPosition < 0 || endPosition > hashOrEndIndex) {
    901 endPosition = hashOrEndIndex;
    902 }
    903 // Progress forth to the end of the "key=" or "key&" substring.
    904 foundIndex += keyEncoded.length + 1;
    905 // Use substr, because it (unlike substring) will return empty string
    906 // if foundIndex > endPosition.
    907 return goog.string.urlDecode(
    908 uri.substr(foundIndex, endPosition - foundIndex));
    909 }
    910};
    911
    912
    913/**
    914 * Gets all values of a query parameter.
    915 * @param {string} uri The URI to process. May contain a framgnet.
    916 * @param {string} keyEncoded The URI-encoded key. Case-snsitive.
    917 * @return {!Array.<string>} All URI-decoded values with the given key.
    918 * If the key is not found, this will have length 0, but never be null.
    919 */
    920goog.uri.utils.getParamValues = function(uri, keyEncoded) {
    921 var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);
    922 var position = 0;
    923 var foundIndex;
    924 var result = [];
    925
    926 while ((foundIndex = goog.uri.utils.findParam_(
    927 uri, position, keyEncoded, hashOrEndIndex)) >= 0) {
    928 // Find where this parameter ends, either the '&' or the end of the
    929 // query parameters.
    930 position = uri.indexOf('&', foundIndex);
    931 if (position < 0 || position > hashOrEndIndex) {
    932 position = hashOrEndIndex;
    933 }
    934
    935 // Progress forth to the end of the "key=" or "key&" substring.
    936 foundIndex += keyEncoded.length + 1;
    937 // Use substr, because it (unlike substring) will return empty string
    938 // if foundIndex > position.
    939 result.push(goog.string.urlDecode(uri.substr(
    940 foundIndex, position - foundIndex)));
    941 }
    942
    943 return result;
    944};
    945
    946
    947/**
    948 * Regexp to find trailing question marks and ampersands.
    949 * @type {RegExp}
    950 * @private
    951 */
    952goog.uri.utils.trailingQueryPunctuationRe_ = /[?&]($|#)/;
    953
    954
    955/**
    956 * Removes all instances of a query parameter.
    957 * @param {string} uri The URI to process. Must not contain a fragment.
    958 * @param {string} keyEncoded The URI-encoded key.
    959 * @return {string} The URI with all instances of the parameter removed.
    960 */
    961goog.uri.utils.removeParam = function(uri, keyEncoded) {
    962 var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);
    963 var position = 0;
    964 var foundIndex;
    965 var buffer = [];
    966
    967 // Look for a query parameter.
    968 while ((foundIndex = goog.uri.utils.findParam_(
    969 uri, position, keyEncoded, hashOrEndIndex)) >= 0) {
    970 // Get the portion of the query string up to, but not including, the ?
    971 // or & starting the parameter.
    972 buffer.push(uri.substring(position, foundIndex));
    973 // Progress to immediately after the '&'. If not found, go to the end.
    974 // Avoid including the hash mark.
    975 position = Math.min((uri.indexOf('&', foundIndex) + 1) || hashOrEndIndex,
    976 hashOrEndIndex);
    977 }
    978
    979 // Append everything that is remaining.
    980 buffer.push(uri.substr(position));
    981
    982 // Join the buffer, and remove trailing punctuation that remains.
    983 return buffer.join('').replace(
    984 goog.uri.utils.trailingQueryPunctuationRe_, '$1');
    985};
    986
    987
    988/**
    989 * Replaces all existing definitions of a parameter with a single definition.
    990 *
    991 * Repeated calls to this can exhibit quadratic behavior due to the need to
    992 * find existing instances and reconstruct the string, though it should be
    993 * limited given the 2kb limit. Consider using appendParams to append multiple
    994 * parameters in bulk.
    995 *
    996 * @param {string} uri The original URI, which may already have query data.
    997 * @param {string} keyEncoded The key, which must already be URI encoded.
    998 * @param {*} value The value, which will be stringized and encoded (assumed
    999 * not already to be encoded).
    1000 * @return {string} The URI with the query parameter added.
    1001 */
    1002goog.uri.utils.setParam = function(uri, keyEncoded, value) {
    1003 return goog.uri.utils.appendParam(
    1004 goog.uri.utils.removeParam(uri, keyEncoded), keyEncoded, value);
    1005};
    1006
    1007
    1008/**
    1009 * Generates a URI path using a given URI and a path with checks to
    1010 * prevent consecutive "//". The baseUri passed in must not contain
    1011 * query or fragment identifiers. The path to append may not contain query or
    1012 * fragment identifiers.
    1013 *
    1014 * @param {string} baseUri URI to use as the base.
    1015 * @param {string} path Path to append.
    1016 * @return {string} Updated URI.
    1017 */
    1018goog.uri.utils.appendPath = function(baseUri, path) {
    1019 goog.uri.utils.assertNoFragmentsOrQueries_(baseUri);
    1020
    1021 // Remove any trailing '/'
    1022 if (goog.string.endsWith(baseUri, '/')) {
    1023 baseUri = baseUri.substr(0, baseUri.length - 1);
    1024 }
    1025 // Remove any leading '/'
    1026 if (goog.string.startsWith(path, '/')) {
    1027 path = path.substr(1);
    1028 }
    1029 return goog.string.buildString(baseUri, '/', path);
    1030};
    1031
    1032
    1033/**
    1034 * Replaces the path.
    1035 * @param {string} uri URI to use as the base.
    1036 * @param {string} path New path.
    1037 * @return {string} Updated URI.
    1038 */
    1039goog.uri.utils.setPath = function(uri, path) {
    1040 // Add any missing '/'.
    1041 if (!goog.string.startsWith(path, '/')) {
    1042 path = '/' + path;
    1043 }
    1044 var parts = goog.uri.utils.split(uri);
    1045 return goog.uri.utils.buildFromEncodedParts(
    1046 parts[goog.uri.utils.ComponentIndex.SCHEME],
    1047 parts[goog.uri.utils.ComponentIndex.USER_INFO],
    1048 parts[goog.uri.utils.ComponentIndex.DOMAIN],
    1049 parts[goog.uri.utils.ComponentIndex.PORT],
    1050 path,
    1051 parts[goog.uri.utils.ComponentIndex.QUERY_DATA],
    1052 parts[goog.uri.utils.ComponentIndex.FRAGMENT]);
    1053};
    1054
    1055
    1056/**
    1057 * Standard supported query parameters.
    1058 * @enum {string}
    1059 */
    1060goog.uri.utils.StandardQueryParam = {
    1061
    1062 /** Unused parameter for unique-ifying. */
    1063 RANDOM: 'zx'
    1064};
    1065
    1066
    1067/**
    1068 * Sets the zx parameter of a URI to a random value.
    1069 * @param {string} uri Any URI.
    1070 * @return {string} That URI with the "zx" parameter added or replaced to
    1071 * contain a random string.
    1072 */
    1073goog.uri.utils.makeUnique = function(uri) {
    1074 return goog.uri.utils.setParam(uri,
    1075 goog.uri.utils.StandardQueryParam.RANDOM, goog.string.getRandomString());
    1076};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/useragent/product.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/useragent/product.js.src.html new file mode 100644 index 0000000..a79a97b --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/useragent/product.js.src.html @@ -0,0 +1 @@ +product.js

    lib/goog/useragent/product.js

    1// Copyright 2008 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Detects the specific browser and not just the rendering engine.
    17 *
    18 */
    19
    20goog.provide('goog.userAgent.product');
    21
    22goog.require('goog.userAgent');
    23
    24
    25/**
    26 * @define {boolean} Whether the code is running on the Firefox web browser.
    27 */
    28goog.define('goog.userAgent.product.ASSUME_FIREFOX', false);
    29
    30
    31/**
    32 * @define {boolean} Whether the code is running on the Camino web browser.
    33 */
    34goog.define('goog.userAgent.product.ASSUME_CAMINO', false);
    35
    36
    37/**
    38 * @define {boolean} Whether we know at compile-time that the product is an
    39 * iPhone.
    40 */
    41goog.define('goog.userAgent.product.ASSUME_IPHONE', false);
    42
    43
    44/**
    45 * @define {boolean} Whether we know at compile-time that the product is an
    46 * iPad.
    47 */
    48goog.define('goog.userAgent.product.ASSUME_IPAD', false);
    49
    50
    51/**
    52 * @define {boolean} Whether we know at compile-time that the product is an
    53 * Android phone.
    54 */
    55goog.define('goog.userAgent.product.ASSUME_ANDROID', false);
    56
    57
    58/**
    59 * @define {boolean} Whether the code is running on the Chrome web browser.
    60 */
    61goog.define('goog.userAgent.product.ASSUME_CHROME', false);
    62
    63
    64/**
    65 * @define {boolean} Whether the code is running on the Safari web browser.
    66 */
    67goog.define('goog.userAgent.product.ASSUME_SAFARI', false);
    68
    69
    70/**
    71 * Whether we know the product type at compile-time.
    72 * @type {boolean}
    73 * @private
    74 */
    75goog.userAgent.product.PRODUCT_KNOWN_ =
    76 goog.userAgent.ASSUME_IE ||
    77 goog.userAgent.ASSUME_OPERA ||
    78 goog.userAgent.product.ASSUME_FIREFOX ||
    79 goog.userAgent.product.ASSUME_CAMINO ||
    80 goog.userAgent.product.ASSUME_IPHONE ||
    81 goog.userAgent.product.ASSUME_IPAD ||
    82 goog.userAgent.product.ASSUME_ANDROID ||
    83 goog.userAgent.product.ASSUME_CHROME ||
    84 goog.userAgent.product.ASSUME_SAFARI;
    85
    86
    87/**
    88 * Right now we just focus on Tier 1-3 browsers at:
    89 * http://wiki/Nonconf/ProductPlatformGuidelines
    90 * As well as the YUI grade A browsers at:
    91 * http://developer.yahoo.com/yui/articles/gbs/
    92 *
    93 * @private
    94 */
    95goog.userAgent.product.init_ = function() {
    96
    97 /**
    98 * Whether the code is running on the Firefox web browser.
    99 * @type {boolean}
    100 * @private
    101 */
    102 goog.userAgent.product.detectedFirefox_ = false;
    103
    104 /**
    105 * Whether the code is running on the Camino web browser.
    106 * @type {boolean}
    107 * @private
    108 */
    109 goog.userAgent.product.detectedCamino_ = false;
    110
    111 /**
    112 * Whether the code is running on an iPhone or iPod touch.
    113 * @type {boolean}
    114 * @private
    115 */
    116 goog.userAgent.product.detectedIphone_ = false;
    117
    118 /**
    119 * Whether the code is running on an iPad
    120 * @type {boolean}
    121 * @private
    122 */
    123 goog.userAgent.product.detectedIpad_ = false;
    124
    125 /**
    126 * Whether the code is running on the default browser on an Android phone.
    127 * @type {boolean}
    128 * @private
    129 */
    130 goog.userAgent.product.detectedAndroid_ = false;
    131
    132 /**
    133 * Whether the code is running on the Chrome web browser.
    134 * @type {boolean}
    135 * @private
    136 */
    137 goog.userAgent.product.detectedChrome_ = false;
    138
    139 /**
    140 * Whether the code is running on the Safari web browser.
    141 * @type {boolean}
    142 * @private
    143 */
    144 goog.userAgent.product.detectedSafari_ = false;
    145
    146 var ua = goog.userAgent.getUserAgentString();
    147 if (!ua) {
    148 return;
    149 }
    150
    151 // The order of the if-statements in the following code is important.
    152 // For example, in the WebKit section, we put Chrome in front of Safari
    153 // because the string 'Safari' is present on both of those browsers'
    154 // userAgent strings as well as the string we are looking for.
    155 // The idea is to prevent accidental detection of more than one client.
    156
    157 if (ua.indexOf('Firefox') != -1) {
    158 goog.userAgent.product.detectedFirefox_ = true;
    159 } else if (ua.indexOf('Camino') != -1) {
    160 goog.userAgent.product.detectedCamino_ = true;
    161 } else if (ua.indexOf('iPhone') != -1 || ua.indexOf('iPod') != -1) {
    162 goog.userAgent.product.detectedIphone_ = true;
    163 } else if (ua.indexOf('iPad') != -1) {
    164 goog.userAgent.product.detectedIpad_ = true;
    165 } else if (ua.indexOf('Chrome') != -1) {
    166 goog.userAgent.product.detectedChrome_ = true;
    167 } else if (ua.indexOf('Android') != -1) {
    168 goog.userAgent.product.detectedAndroid_ = true;
    169 } else if (ua.indexOf('Safari') != -1) {
    170 goog.userAgent.product.detectedSafari_ = true;
    171 }
    172};
    173
    174if (!goog.userAgent.product.PRODUCT_KNOWN_) {
    175 goog.userAgent.product.init_();
    176}
    177
    178
    179/**
    180 * Whether the code is running on the Opera web browser.
    181 * @type {boolean}
    182 */
    183goog.userAgent.product.OPERA = goog.userAgent.OPERA;
    184
    185
    186/**
    187 * Whether the code is running on an IE web browser.
    188 * @type {boolean}
    189 */
    190goog.userAgent.product.IE = goog.userAgent.IE;
    191
    192
    193/**
    194 * Whether the code is running on the Firefox web browser.
    195 * @type {boolean}
    196 */
    197goog.userAgent.product.FIREFOX = goog.userAgent.product.PRODUCT_KNOWN_ ?
    198 goog.userAgent.product.ASSUME_FIREFOX :
    199 goog.userAgent.product.detectedFirefox_;
    200
    201
    202/**
    203 * Whether the code is running on the Camino web browser.
    204 * @type {boolean}
    205 */
    206goog.userAgent.product.CAMINO = goog.userAgent.product.PRODUCT_KNOWN_ ?
    207 goog.userAgent.product.ASSUME_CAMINO :
    208 goog.userAgent.product.detectedCamino_;
    209
    210
    211/**
    212 * Whether the code is running on an iPhone or iPod touch.
    213 * @type {boolean}
    214 */
    215goog.userAgent.product.IPHONE = goog.userAgent.product.PRODUCT_KNOWN_ ?
    216 goog.userAgent.product.ASSUME_IPHONE :
    217 goog.userAgent.product.detectedIphone_;
    218
    219
    220/**
    221 * Whether the code is running on an iPad.
    222 * @type {boolean}
    223 */
    224goog.userAgent.product.IPAD = goog.userAgent.product.PRODUCT_KNOWN_ ?
    225 goog.userAgent.product.ASSUME_IPAD :
    226 goog.userAgent.product.detectedIpad_;
    227
    228
    229/**
    230 * Whether the code is running on the default browser on an Android phone.
    231 * @type {boolean}
    232 */
    233goog.userAgent.product.ANDROID = goog.userAgent.product.PRODUCT_KNOWN_ ?
    234 goog.userAgent.product.ASSUME_ANDROID :
    235 goog.userAgent.product.detectedAndroid_;
    236
    237
    238/**
    239 * Whether the code is running on the Chrome web browser.
    240 * @type {boolean}
    241 */
    242goog.userAgent.product.CHROME = goog.userAgent.product.PRODUCT_KNOWN_ ?
    243 goog.userAgent.product.ASSUME_CHROME :
    244 goog.userAgent.product.detectedChrome_;
    245
    246
    247/**
    248 * Whether the code is running on the Safari web browser.
    249 * @type {boolean}
    250 */
    251goog.userAgent.product.SAFARI = goog.userAgent.product.PRODUCT_KNOWN_ ?
    252 goog.userAgent.product.ASSUME_SAFARI :
    253 goog.userAgent.product.detectedSafari_;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/useragent/product_isversion.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/useragent/product_isversion.js.src.html new file mode 100644 index 0000000..4f99683 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/useragent/product_isversion.js.src.html @@ -0,0 +1 @@ +product_isversion.js

    lib/goog/useragent/product_isversion.js

    1// Copyright 2009 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Functions for understanding the version of the browser.
    17 * This is pulled out of product.js to ensure that only builds that need
    18 * this functionality actually get it, without having to rely on the compiler
    19 * to strip out unneeded pieces.
    20 *
    21 * TODO(nnaze): Move to more appropriate filename/namespace.
    22 *
    23 */
    24
    25
    26goog.provide('goog.userAgent.product.isVersion');
    27
    28
    29goog.require('goog.userAgent.product');
    30
    31
    32/**
    33 * @return {string} The string that describes the version number of the user
    34 * agent product. This is a string rather than a number because it may
    35 * contain 'b', 'a', and so on.
    36 * @private
    37 */
    38goog.userAgent.product.determineVersion_ = function() {
    39 // All browsers have different ways to detect the version and they all have
    40 // different naming schemes.
    41
    42 if (goog.userAgent.product.FIREFOX) {
    43 // Firefox/2.0.0.1 or Firefox/3.5.3
    44 return goog.userAgent.product.getFirstRegExpGroup_(/Firefox\/([0-9.]+)/);
    45 }
    46
    47 if (goog.userAgent.product.IE || goog.userAgent.product.OPERA) {
    48 return goog.userAgent.VERSION;
    49 }
    50
    51 if (goog.userAgent.product.CHROME) {
    52 // Chrome/4.0.223.1
    53 return goog.userAgent.product.getFirstRegExpGroup_(/Chrome\/([0-9.]+)/);
    54 }
    55
    56 if (goog.userAgent.product.SAFARI) {
    57 // Version/5.0.3
    58 //
    59 // NOTE: Before version 3, Safari did not report a product version number.
    60 // The product version number for these browsers will be the empty string.
    61 // They may be differentiated by WebKit version number in goog.userAgent.
    62 return goog.userAgent.product.getFirstRegExpGroup_(/Version\/([0-9.]+)/);
    63 }
    64
    65 if (goog.userAgent.product.IPHONE || goog.userAgent.product.IPAD) {
    66 // Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1
    67 // (KHTML, like Gecko) Version/3.0 Mobile/3A100a Safari/419.3
    68 // Version is the browser version, Mobile is the build number. We combine
    69 // the version string with the build number: 3.0.3A100a for the example.
    70 var arr = goog.userAgent.product.execRegExp_(
    71 /Version\/(\S+).*Mobile\/(\S+)/);
    72 if (arr) {
    73 return arr[1] + '.' + arr[2];
    74 }
    75 } else if (goog.userAgent.product.ANDROID) {
    76 // Mozilla/5.0 (Linux; U; Android 0.5; en-us) AppleWebKit/522+
    77 // (KHTML, like Gecko) Safari/419.3
    78 //
    79 // Mozilla/5.0 (Linux; U; Android 1.0; en-us; dream) AppleWebKit/525.10+
    80 // (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2
    81 //
    82 // Prefer Version number if present, else make do with the OS number
    83 var version = goog.userAgent.product.getFirstRegExpGroup_(
    84 /Android\s+([0-9.]+)/);
    85 if (version) {
    86 return version;
    87 }
    88
    89 return goog.userAgent.product.getFirstRegExpGroup_(/Version\/([0-9.]+)/);
    90 } else if (goog.userAgent.product.CAMINO) {
    91 return goog.userAgent.product.getFirstRegExpGroup_(/Camino\/([0-9.]+)/);
    92 }
    93
    94 return '';
    95};
    96
    97
    98/**
    99 * Return the first group of the given regex.
    100 * @param {!RegExp} re Regular expression with at least one group.
    101 * @return {string} Contents of the first group or an empty string if no match.
    102 * @private
    103 */
    104goog.userAgent.product.getFirstRegExpGroup_ = function(re) {
    105 var arr = goog.userAgent.product.execRegExp_(re);
    106 return arr ? arr[1] : '';
    107};
    108
    109
    110/**
    111 * Run regexp's exec() on the userAgent string.
    112 * @param {!RegExp} re Regular expression.
    113 * @return {Array} A result array, or null for no match.
    114 * @private
    115 */
    116goog.userAgent.product.execRegExp_ = function(re) {
    117 return re.exec(goog.userAgent.getUserAgentString());
    118};
    119
    120
    121/**
    122 * The version of the user agent. This is a string because it might contain
    123 * 'b' (as in beta) as well as multiple dots.
    124 * @type {string}
    125 */
    126goog.userAgent.product.VERSION = goog.userAgent.product.determineVersion_();
    127
    128
    129/**
    130 * Whether the user agent product version is higher or the same as the given
    131 * version.
    132 *
    133 * @param {string|number} version The version to check.
    134 * @return {boolean} Whether the user agent product version is higher or the
    135 * same as the given version.
    136 */
    137goog.userAgent.product.isVersion = function(version) {
    138 return goog.string.compareVersions(
    139 goog.userAgent.product.VERSION, version) >= 0;
    140};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/goog/useragent/useragent.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/goog/useragent/useragent.js.src.html new file mode 100644 index 0000000..48508b1 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/goog/useragent/useragent.js.src.html @@ -0,0 +1 @@ +useragent.js

    lib/goog/useragent/useragent.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS-IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Rendering engine detection.
    17 * @see <a href="http://www.useragentstring.com/">User agent strings</a>
    18 * For information on the browser brand (such as Safari versus Chrome), see
    19 * goog.userAgent.product.
    20 * @see ../demos/useragent.html
    21 */
    22
    23goog.provide('goog.userAgent');
    24
    25goog.require('goog.labs.userAgent.browser');
    26goog.require('goog.labs.userAgent.engine');
    27goog.require('goog.labs.userAgent.util');
    28goog.require('goog.string');
    29
    30
    31/**
    32 * @define {boolean} Whether we know at compile-time that the browser is IE.
    33 */
    34goog.define('goog.userAgent.ASSUME_IE', false);
    35
    36
    37/**
    38 * @define {boolean} Whether we know at compile-time that the browser is GECKO.
    39 */
    40goog.define('goog.userAgent.ASSUME_GECKO', false);
    41
    42
    43/**
    44 * @define {boolean} Whether we know at compile-time that the browser is WEBKIT.
    45 */
    46goog.define('goog.userAgent.ASSUME_WEBKIT', false);
    47
    48
    49/**
    50 * @define {boolean} Whether we know at compile-time that the browser is a
    51 * mobile device running WebKit e.g. iPhone or Android.
    52 */
    53goog.define('goog.userAgent.ASSUME_MOBILE_WEBKIT', false);
    54
    55
    56/**
    57 * @define {boolean} Whether we know at compile-time that the browser is OPERA.
    58 */
    59goog.define('goog.userAgent.ASSUME_OPERA', false);
    60
    61
    62/**
    63 * @define {boolean} Whether the
    64 * {@code goog.userAgent.isVersionOrHigher}
    65 * function will return true for any version.
    66 */
    67goog.define('goog.userAgent.ASSUME_ANY_VERSION', false);
    68
    69
    70/**
    71 * Whether we know the browser engine at compile-time.
    72 * @type {boolean}
    73 * @private
    74 */
    75goog.userAgent.BROWSER_KNOWN_ =
    76 goog.userAgent.ASSUME_IE ||
    77 goog.userAgent.ASSUME_GECKO ||
    78 goog.userAgent.ASSUME_MOBILE_WEBKIT ||
    79 goog.userAgent.ASSUME_WEBKIT ||
    80 goog.userAgent.ASSUME_OPERA;
    81
    82
    83/**
    84 * Returns the userAgent string for the current browser.
    85 *
    86 * @return {string} The userAgent string.
    87 */
    88goog.userAgent.getUserAgentString = function() {
    89 return goog.labs.userAgent.util.getUserAgent();
    90};
    91
    92
    93/**
    94 * TODO(nnaze): Change type to "Navigator" and update compilation targets.
    95 * @return {Object} The native navigator object.
    96 */
    97goog.userAgent.getNavigator = function() {
    98 // Need a local navigator reference instead of using the global one,
    99 // to avoid the rare case where they reference different objects.
    100 // (in a WorkerPool, for example).
    101 return goog.global['navigator'] || null;
    102};
    103
    104
    105/**
    106 * Whether the user agent is Opera.
    107 * @type {boolean}
    108 */
    109goog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ?
    110 goog.userAgent.ASSUME_OPERA :
    111 goog.labs.userAgent.browser.isOpera();
    112
    113
    114/**
    115 * Whether the user agent is Internet Explorer.
    116 * @type {boolean}
    117 */
    118goog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ?
    119 goog.userAgent.ASSUME_IE :
    120 goog.labs.userAgent.browser.isIE();
    121
    122
    123/**
    124 * Whether the user agent is Gecko. Gecko is the rendering engine used by
    125 * Mozilla, Firefox, and others.
    126 * @type {boolean}
    127 */
    128goog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ?
    129 goog.userAgent.ASSUME_GECKO :
    130 goog.labs.userAgent.engine.isGecko();
    131
    132
    133/**
    134 * Whether the user agent is WebKit. WebKit is the rendering engine that
    135 * Safari, Android and others use.
    136 * @type {boolean}
    137 */
    138goog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ?
    139 goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT :
    140 goog.labs.userAgent.engine.isWebKit();
    141
    142
    143/**
    144 * Whether the user agent is running on a mobile device.
    145 *
    146 * This is a separate function so that the logic can be tested.
    147 *
    148 * TODO(nnaze): Investigate swapping in goog.labs.userAgent.device.isMobile().
    149 *
    150 * @return {boolean} Whether the user agent is running on a mobile device.
    151 * @private
    152 */
    153goog.userAgent.isMobile_ = function() {
    154 return goog.userAgent.WEBKIT &&
    155 goog.labs.userAgent.util.matchUserAgent('Mobile');
    156};
    157
    158
    159/**
    160 * Whether the user agent is running on a mobile device.
    161 *
    162 * TODO(nnaze): Consider deprecating MOBILE when labs.userAgent
    163 * is promoted as the gecko/webkit logic is likely inaccurate.
    164 *
    165 * @type {boolean}
    166 */
    167goog.userAgent.MOBILE = goog.userAgent.ASSUME_MOBILE_WEBKIT ||
    168 goog.userAgent.isMobile_();
    169
    170
    171/**
    172 * Used while transitioning code to use WEBKIT instead.
    173 * @type {boolean}
    174 * @deprecated Use {@link goog.userAgent.product.SAFARI} instead.
    175 * TODO(nicksantos): Delete this from goog.userAgent.
    176 */
    177goog.userAgent.SAFARI = goog.userAgent.WEBKIT;
    178
    179
    180/**
    181 * @return {string} the platform (operating system) the user agent is running
    182 * on. Default to empty string because navigator.platform may not be defined
    183 * (on Rhino, for example).
    184 * @private
    185 */
    186goog.userAgent.determinePlatform_ = function() {
    187 var navigator = goog.userAgent.getNavigator();
    188 return navigator && navigator.platform || '';
    189};
    190
    191
    192/**
    193 * The platform (operating system) the user agent is running on. Default to
    194 * empty string because navigator.platform may not be defined (on Rhino, for
    195 * example).
    196 * @type {string}
    197 */
    198goog.userAgent.PLATFORM = goog.userAgent.determinePlatform_();
    199
    200
    201/**
    202 * @define {boolean} Whether the user agent is running on a Macintosh operating
    203 * system.
    204 */
    205goog.define('goog.userAgent.ASSUME_MAC', false);
    206
    207
    208/**
    209 * @define {boolean} Whether the user agent is running on a Windows operating
    210 * system.
    211 */
    212goog.define('goog.userAgent.ASSUME_WINDOWS', false);
    213
    214
    215/**
    216 * @define {boolean} Whether the user agent is running on a Linux operating
    217 * system.
    218 */
    219goog.define('goog.userAgent.ASSUME_LINUX', false);
    220
    221
    222/**
    223 * @define {boolean} Whether the user agent is running on a X11 windowing
    224 * system.
    225 */
    226goog.define('goog.userAgent.ASSUME_X11', false);
    227
    228
    229/**
    230 * @define {boolean} Whether the user agent is running on Android.
    231 */
    232goog.define('goog.userAgent.ASSUME_ANDROID', false);
    233
    234
    235/**
    236 * @define {boolean} Whether the user agent is running on an iPhone.
    237 */
    238goog.define('goog.userAgent.ASSUME_IPHONE', false);
    239
    240
    241/**
    242 * @define {boolean} Whether the user agent is running on an iPad.
    243 */
    244goog.define('goog.userAgent.ASSUME_IPAD', false);
    245
    246
    247/**
    248 * @type {boolean}
    249 * @private
    250 */
    251goog.userAgent.PLATFORM_KNOWN_ =
    252 goog.userAgent.ASSUME_MAC ||
    253 goog.userAgent.ASSUME_WINDOWS ||
    254 goog.userAgent.ASSUME_LINUX ||
    255 goog.userAgent.ASSUME_X11 ||
    256 goog.userAgent.ASSUME_ANDROID ||
    257 goog.userAgent.ASSUME_IPHONE ||
    258 goog.userAgent.ASSUME_IPAD;
    259
    260
    261/**
    262 * Initialize the goog.userAgent constants that define which platform the user
    263 * agent is running on.
    264 * @private
    265 */
    266goog.userAgent.initPlatform_ = function() {
    267 /**
    268 * Whether the user agent is running on a Macintosh operating system.
    269 * @type {boolean}
    270 * @private
    271 */
    272 goog.userAgent.detectedMac_ = goog.string.contains(goog.userAgent.PLATFORM,
    273 'Mac');
    274
    275 /**
    276 * Whether the user agent is running on a Windows operating system.
    277 * @type {boolean}
    278 * @private
    279 */
    280 goog.userAgent.detectedWindows_ = goog.string.contains(
    281 goog.userAgent.PLATFORM, 'Win');
    282
    283 /**
    284 * Whether the user agent is running on a Linux operating system.
    285 * @type {boolean}
    286 * @private
    287 */
    288 goog.userAgent.detectedLinux_ = goog.string.contains(goog.userAgent.PLATFORM,
    289 'Linux');
    290
    291 /**
    292 * Whether the user agent is running on a X11 windowing system.
    293 * @type {boolean}
    294 * @private
    295 */
    296 goog.userAgent.detectedX11_ = !!goog.userAgent.getNavigator() &&
    297 goog.string.contains(goog.userAgent.getNavigator()['appVersion'] || '',
    298 'X11');
    299
    300 // Need user agent string for Android/IOS detection
    301 var ua = goog.userAgent.getUserAgentString();
    302
    303 /**
    304 * Whether the user agent is running on Android.
    305 * @type {boolean}
    306 * @private
    307 */
    308 goog.userAgent.detectedAndroid_ = !!ua &&
    309 goog.string.contains(ua, 'Android');
    310
    311 /**
    312 * Whether the user agent is running on an iPhone.
    313 * @type {boolean}
    314 * @private
    315 */
    316 goog.userAgent.detectedIPhone_ = !!ua && goog.string.contains(ua, 'iPhone');
    317
    318 /**
    319 * Whether the user agent is running on an iPad.
    320 * @type {boolean}
    321 * @private
    322 */
    323 goog.userAgent.detectedIPad_ = !!ua && goog.string.contains(ua, 'iPad');
    324};
    325
    326
    327if (!goog.userAgent.PLATFORM_KNOWN_) {
    328 goog.userAgent.initPlatform_();
    329}
    330
    331
    332/**
    333 * Whether the user agent is running on a Macintosh operating system.
    334 * @type {boolean}
    335 */
    336goog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ?
    337 goog.userAgent.ASSUME_MAC : goog.userAgent.detectedMac_;
    338
    339
    340/**
    341 * Whether the user agent is running on a Windows operating system.
    342 * @type {boolean}
    343 */
    344goog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ?
    345 goog.userAgent.ASSUME_WINDOWS : goog.userAgent.detectedWindows_;
    346
    347
    348/**
    349 * Whether the user agent is running on a Linux operating system.
    350 * @type {boolean}
    351 */
    352goog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ?
    353 goog.userAgent.ASSUME_LINUX : goog.userAgent.detectedLinux_;
    354
    355
    356/**
    357 * Whether the user agent is running on a X11 windowing system.
    358 * @type {boolean}
    359 */
    360goog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ?
    361 goog.userAgent.ASSUME_X11 : goog.userAgent.detectedX11_;
    362
    363
    364/**
    365 * Whether the user agent is running on Android.
    366 * @type {boolean}
    367 */
    368goog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ?
    369 goog.userAgent.ASSUME_ANDROID : goog.userAgent.detectedAndroid_;
    370
    371
    372/**
    373 * Whether the user agent is running on an iPhone.
    374 * @type {boolean}
    375 */
    376goog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ?
    377 goog.userAgent.ASSUME_IPHONE : goog.userAgent.detectedIPhone_;
    378
    379
    380/**
    381 * Whether the user agent is running on an iPad.
    382 * @type {boolean}
    383 */
    384goog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ?
    385 goog.userAgent.ASSUME_IPAD : goog.userAgent.detectedIPad_;
    386
    387
    388/**
    389 * @return {string} The string that describes the version number of the user
    390 * agent.
    391 * @private
    392 */
    393goog.userAgent.determineVersion_ = function() {
    394 // All browsers have different ways to detect the version and they all have
    395 // different naming schemes.
    396
    397 // version is a string rather than a number because it may contain 'b', 'a',
    398 // and so on.
    399 var version = '', re;
    400
    401 if (goog.userAgent.OPERA && goog.global['opera']) {
    402 var operaVersion = goog.global['opera'].version;
    403 return goog.isFunction(operaVersion) ? operaVersion() : operaVersion;
    404 }
    405
    406 if (goog.userAgent.GECKO) {
    407 re = /rv\:([^\);]+)(\)|;)/;
    408 } else if (goog.userAgent.IE) {
    409 re = /\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/;
    410 } else if (goog.userAgent.WEBKIT) {
    411 // WebKit/125.4
    412 re = /WebKit\/(\S+)/;
    413 }
    414
    415 if (re) {
    416 var arr = re.exec(goog.userAgent.getUserAgentString());
    417 version = arr ? arr[1] : '';
    418 }
    419
    420 if (goog.userAgent.IE) {
    421 // IE9 can be in document mode 9 but be reporting an inconsistent user agent
    422 // version. If it is identifying as a version lower than 9 we take the
    423 // documentMode as the version instead. IE8 has similar behavior.
    424 // It is recommended to set the X-UA-Compatible header to ensure that IE9
    425 // uses documentMode 9.
    426 var docMode = goog.userAgent.getDocumentMode_();
    427 if (docMode > parseFloat(version)) {
    428 return String(docMode);
    429 }
    430 }
    431
    432 return version;
    433};
    434
    435
    436/**
    437 * @return {number|undefined} Returns the document mode (for testing).
    438 * @private
    439 */
    440goog.userAgent.getDocumentMode_ = function() {
    441 // NOTE(user): goog.userAgent may be used in context where there is no DOM.
    442 var doc = goog.global['document'];
    443 return doc ? doc['documentMode'] : undefined;
    444};
    445
    446
    447/**
    448 * The version of the user agent. This is a string because it might contain
    449 * 'b' (as in beta) as well as multiple dots.
    450 * @type {string}
    451 */
    452goog.userAgent.VERSION = goog.userAgent.determineVersion_();
    453
    454
    455/**
    456 * Compares two version numbers.
    457 *
    458 * @param {string} v1 Version of first item.
    459 * @param {string} v2 Version of second item.
    460 *
    461 * @return {number} 1 if first argument is higher
    462 * 0 if arguments are equal
    463 * -1 if second argument is higher.
    464 * @deprecated Use goog.string.compareVersions.
    465 */
    466goog.userAgent.compare = function(v1, v2) {
    467 return goog.string.compareVersions(v1, v2);
    468};
    469
    470
    471/**
    472 * Cache for {@link goog.userAgent.isVersionOrHigher}.
    473 * Calls to compareVersions are surprisingly expensive and, as a browser's
    474 * version number is unlikely to change during a session, we cache the results.
    475 * @const
    476 * @private
    477 */
    478goog.userAgent.isVersionOrHigherCache_ = {};
    479
    480
    481/**
    482 * Whether the user agent version is higher or the same as the given version.
    483 * NOTE: When checking the version numbers for Firefox and Safari, be sure to
    484 * use the engine's version, not the browser's version number. For example,
    485 * Firefox 3.0 corresponds to Gecko 1.9 and Safari 3.0 to Webkit 522.11.
    486 * Opera and Internet Explorer versions match the product release number.<br>
    487 * @see <a href="http://en.wikipedia.org/wiki/Safari_version_history">
    488 * Webkit</a>
    489 * @see <a href="http://en.wikipedia.org/wiki/Gecko_engine">Gecko</a>
    490 *
    491 * @param {string|number} version The version to check.
    492 * @return {boolean} Whether the user agent version is higher or the same as
    493 * the given version.
    494 */
    495goog.userAgent.isVersionOrHigher = function(version) {
    496 return goog.userAgent.ASSUME_ANY_VERSION ||
    497 goog.userAgent.isVersionOrHigherCache_[version] ||
    498 (goog.userAgent.isVersionOrHigherCache_[version] =
    499 goog.string.compareVersions(goog.userAgent.VERSION, version) >= 0);
    500};
    501
    502
    503/**
    504 * Deprecated alias to {@code goog.userAgent.isVersionOrHigher}.
    505 * @param {string|number} version The version to check.
    506 * @return {boolean} Whether the user agent version is higher or the same as
    507 * the given version.
    508 * @deprecated Use goog.userAgent.isVersionOrHigher().
    509 */
    510goog.userAgent.isVersion = goog.userAgent.isVersionOrHigher;
    511
    512
    513/**
    514 * Whether the IE effective document mode is higher or the same as the given
    515 * document mode version.
    516 * NOTE: Only for IE, return false for another browser.
    517 *
    518 * @param {number} documentMode The document mode version to check.
    519 * @return {boolean} Whether the IE effective document mode is higher or the
    520 * same as the given version.
    521 */
    522goog.userAgent.isDocumentModeOrHigher = function(documentMode) {
    523 return goog.userAgent.IE && goog.userAgent.DOCUMENT_MODE >= documentMode;
    524};
    525
    526
    527/**
    528 * Deprecated alias to {@code goog.userAgent.isDocumentModeOrHigher}.
    529 * @param {number} version The version to check.
    530 * @return {boolean} Whether the IE effective document mode is higher or the
    531 * same as the given version.
    532 * @deprecated Use goog.userAgent.isDocumentModeOrHigher().
    533 */
    534goog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher;
    535
    536
    537/**
    538 * For IE version < 7, documentMode is undefined, so attempt to use the
    539 * CSS1Compat property to see if we are in standards mode. If we are in
    540 * standards mode, treat the browser version as the document mode. Otherwise,
    541 * IE is emulating version 5.
    542 * @type {number|undefined}
    543 * @const
    544 */
    545goog.userAgent.DOCUMENT_MODE = (function() {
    546 var doc = goog.global['document'];
    547 if (!doc || !goog.userAgent.IE) {
    548 return undefined;
    549 }
    550 var mode = goog.userAgent.getDocumentMode_();
    551 return mode || (doc['compatMode'] == 'CSS1Compat' ?
    552 parseInt(goog.userAgent.VERSION, 10) : 5);
    553})();
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/abstractbuilder.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/abstractbuilder.js.src.html new file mode 100644 index 0000000..242c7a7 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/abstractbuilder.js.src.html @@ -0,0 +1 @@ +abstractbuilder.js

    lib/webdriver/abstractbuilder.js

    1// Copyright 2012 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15goog.provide('webdriver.AbstractBuilder');
    16
    17goog.require('webdriver.Capabilities');
    18goog.require('webdriver.process');
    19
    20
    21
    22/**
    23 * Creates new {@code webdriver.WebDriver} clients. Upon instantiation, each
    24 * Builder will configure itself based on the following environment variables:
    25 * <dl>
    26 * <dt>{@code webdriver.AbstractBuilder.SERVER_URL_ENV}</dt>
    27 * <dd>Defines the remote WebDriver server that should be used for command
    28 * command execution; may be overridden using
    29 * {@code webdriver.AbstractBuilder.prototype.usingServer}.</dd>
    30 * </dl>
    31 * @constructor
    32 */
    33webdriver.AbstractBuilder = function() {
    34
    35 /**
    36 * URL of the remote server to use for new clients; initialized from the
    37 * value of the {@link webdriver.AbstractBuilder.SERVER_URL_ENV} environment
    38 * variable, but may be overridden using
    39 * {@link webdriver.AbstractBuilder#usingServer}.
    40 * @private {string}
    41 */
    42 this.serverUrl_ = webdriver.process.getEnv(
    43 webdriver.AbstractBuilder.SERVER_URL_ENV);
    44
    45 /**
    46 * The desired capabilities to use when creating a new session.
    47 * @private {!webdriver.Capabilities}
    48 */
    49 this.capabilities_ = new webdriver.Capabilities();
    50};
    51
    52
    53/**
    54 * Environment variable that defines the URL of the WebDriver server that
    55 * should be used for all new WebDriver clients. This setting may be overridden
    56 * using {@code #usingServer(url)}.
    57 * @type {string}
    58 * @const
    59 * @see webdriver.process.getEnv
    60 */
    61webdriver.AbstractBuilder.SERVER_URL_ENV = 'wdurl';
    62
    63
    64/**
    65 * The default URL of the WebDriver server to use if
    66 * {@link webdriver.AbstractBuilder.SERVER_URL_ENV} is not set.
    67 * @type {string}
    68 * @const
    69 */
    70webdriver.AbstractBuilder.DEFAULT_SERVER_URL = 'http://localhost:4444/wd/hub';
    71
    72
    73/**
    74 * Configures which WebDriver server should be used for new sessions. Overrides
    75 * the value loaded from the {@link webdriver.AbstractBuilder.SERVER_URL_ENV}
    76 * upon creation of this instance.
    77 * @param {string} url URL of the server to use.
    78 * @return {!webdriver.AbstractBuilder} This Builder instance for chain calling.
    79 */
    80webdriver.AbstractBuilder.prototype.usingServer = function(url) {
    81 this.serverUrl_ = url;
    82 return this;
    83};
    84
    85
    86/**
    87 * @return {string} The URL of the WebDriver server this instance is configured
    88 * to use.
    89 */
    90webdriver.AbstractBuilder.prototype.getServerUrl = function() {
    91 return this.serverUrl_;
    92};
    93
    94
    95/**
    96 * Sets the desired capabilities when requesting a new session. This will
    97 * overwrite any previously set desired capabilities.
    98 * @param {!(Object|webdriver.Capabilities)} capabilities The desired
    99 * capabilities for a new session.
    100 * @return {!webdriver.AbstractBuilder} This Builder instance for chain calling.
    101 */
    102webdriver.AbstractBuilder.prototype.withCapabilities = function(capabilities) {
    103 this.capabilities_ = new webdriver.Capabilities(capabilities);
    104 return this;
    105};
    106
    107
    108/**
    109 * @return {!webdriver.Capabilities} The current desired capabilities for this
    110 * builder.
    111 */
    112webdriver.AbstractBuilder.prototype.getCapabilities = function() {
    113 return this.capabilities_;
    114};
    115
    116
    117/**
    118 * Builds a new {@link webdriver.WebDriver} instance using this builder's
    119 * current configuration.
    120 * @return {!webdriver.WebDriver} A new WebDriver client.
    121 */
    122webdriver.AbstractBuilder.prototype.build = goog.abstractMethod;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/actionsequence.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/actionsequence.js.src.html new file mode 100644 index 0000000..711b4de --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/actionsequence.js.src.html @@ -0,0 +1 @@ +actionsequence.js

    lib/webdriver/actionsequence.js

    1// Copyright 2012 Selenium comitters
    2// Copyright 2012 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16goog.provide('webdriver.ActionSequence');
    17
    18goog.require('goog.array');
    19goog.require('webdriver.Button');
    20goog.require('webdriver.Command');
    21goog.require('webdriver.CommandName');
    22goog.require('webdriver.Key');
    23
    24
    25
    26/**
    27 * Class for defining sequences of complex user interactions. Each sequence
    28 * will not be executed until {@link #perform} is called.
    29 *
    30 * <p>Example:<pre><code>
    31 * new webdriver.ActionSequence(driver).
    32 * keyDown(webdriver.Key.SHIFT).
    33 * click(element1).
    34 * click(element2).
    35 * dragAndDrop(element3, element4).
    36 * keyUp(webdriver.Key.SHIFT).
    37 * perform();
    38 * </pre></code>
    39 *
    40 * @param {!webdriver.WebDriver} driver The driver instance to use.
    41 * @constructor
    42 */
    43webdriver.ActionSequence = function(driver) {
    44
    45 /** @private {!webdriver.WebDriver} */
    46 this.driver_ = driver;
    47
    48 /** @private {!Array.<{description: string, command: !webdriver.Command}>} */
    49 this.actions_ = [];
    50};
    51
    52
    53/**
    54 * Schedules an action to be executed each time {@link #perform} is called on
    55 * this instance.
    56 * @param {string} description A description of the command.
    57 * @param {!webdriver.Command} command The command.
    58 * @private
    59 */
    60webdriver.ActionSequence.prototype.schedule_ = function(description, command) {
    61 this.actions_.push({
    62 description: description,
    63 command: command
    64 });
    65};
    66
    67
    68/**
    69 * Executes this action sequence.
    70 * @return {!webdriver.promise.Promise} A promise that will be resolved once
    71 * this sequence has completed.
    72 */
    73webdriver.ActionSequence.prototype.perform = function() {
    74 // Make a protected copy of the scheduled actions. This will protect against
    75 // users defining additional commands before this sequence is actually
    76 // executed.
    77 var actions = goog.array.clone(this.actions_);
    78 var driver = this.driver_;
    79 return driver.controlFlow().execute(function() {
    80 goog.array.forEach(actions, function(action) {
    81 driver.schedule(action.command, action.description);
    82 });
    83 }, 'ActionSequence.perform');
    84};
    85
    86
    87/**
    88 * Moves the mouse. The location to move to may be specified in terms of the
    89 * mouse's current location, an offset relative to the top-left corner of an
    90 * element, or an element (in which case the middle of the element is used).
    91 * @param {(!webdriver.WebElement|{x: number, y: number})} location The
    92 * location to drag to, as either another WebElement or an offset in pixels.
    93 * @param {{x: number, y: number}=} opt_offset If the target {@code location}
    94 * is defined as a {@link webdriver.WebElement}, this parameter defines an
    95 * offset within that element. The offset should be specified in pixels
    96 * relative to the top-left corner of the element's bounding box. If
    97 * omitted, the element's center will be used as the target offset.
    98 * @return {!webdriver.ActionSequence} A self reference.
    99 */
    100webdriver.ActionSequence.prototype.mouseMove = function(location, opt_offset) {
    101 var command = new webdriver.Command(webdriver.CommandName.MOVE_TO);
    102
    103 if (goog.isNumber(location.x)) {
    104 setOffset(/** @type {{x: number, y: number}} */(location));
    105 } else {
    106 // The interactions API expect the element ID to be encoded as a simple
    107 // string, not the usual JSON object.
    108 var id = /** @type {!webdriver.WebElement} */ (location).toWireValue().
    109 then(function(value) {
    110 return value['ELEMENT'];
    111 });
    112 command.setParameter('element', id);
    113 if (opt_offset) {
    114 setOffset(opt_offset);
    115 }
    116 }
    117
    118 this.schedule_('mouseMove', command);
    119 return this;
    120
    121 /** @param {{x: number, y: number}} offset The offset to use. */
    122 function setOffset(offset) {
    123 command.setParameter('xoffset', offset.x || 0);
    124 command.setParameter('yoffset', offset.y || 0);
    125 }
    126};
    127
    128
    129/**
    130 * Schedules a mouse action.
    131 * @param {string} description A simple descriptive label for the scheduled
    132 * action.
    133 * @param {!webdriver.CommandName} commandName The name of the command.
    134 * @param {(webdriver.WebElement|webdriver.Button)=} opt_elementOrButton Either
    135 * the element to interact with or the button to click with.
    136 * Defaults to {@link webdriver.Button.LEFT} if neither an element nor
    137 * button is specified.
    138 * @param {webdriver.Button=} opt_button The button to use. Defaults to
    139 * {@link webdriver.Button.LEFT}. Ignored if the previous argument is
    140 * provided as a button.
    141 * @return {!webdriver.ActionSequence} A self reference.
    142 * @private
    143 */
    144webdriver.ActionSequence.prototype.scheduleMouseAction_ = function(
    145 description, commandName, opt_elementOrButton, opt_button) {
    146 var button;
    147 if (goog.isNumber(opt_elementOrButton)) {
    148 button = opt_elementOrButton;
    149 } else {
    150 if (opt_elementOrButton) {
    151 this.mouseMove(
    152 /** @type {!webdriver.WebElement} */ (opt_elementOrButton));
    153 }
    154 button = goog.isDef(opt_button) ? opt_button : webdriver.Button.LEFT;
    155 }
    156
    157 var command = new webdriver.Command(commandName).
    158 setParameter('button', button);
    159 this.schedule_(description, command);
    160 return this;
    161};
    162
    163
    164/**
    165 * Presses a mouse button. The mouse button will not be released until
    166 * {@link #mouseUp} is called, regardless of whether that call is made in this
    167 * sequence or another. The behavior for out-of-order events (e.g. mouseDown,
    168 * click) is undefined.
    169 *
    170 * <p>If an element is provided, the mouse will first be moved to the center
    171 * of that element. This is equivalent to:
    172 * <pre><code>sequence.mouseMove(element).mouseDown()</code></pre>
    173 *
    174 * <p>Warning: this method currently only supports the left mouse button. See
    175 * http://code.google.com/p/selenium/issues/detail?id=4047
    176 *
    177 * @param {(webdriver.WebElement|webdriver.Button)=} opt_elementOrButton Either
    178 * the element to interact with or the button to click with.
    179 * Defaults to {@link webdriver.Button.LEFT} if neither an element nor
    180 * button is specified.
    181 * @param {webdriver.Button=} opt_button The button to use. Defaults to
    182 * {@link webdriver.Button.LEFT}. Ignored if a button is provided as the
    183 * first argument.
    184 * @return {!webdriver.ActionSequence} A self reference.
    185 */
    186webdriver.ActionSequence.prototype.mouseDown = function(opt_elementOrButton,
    187 opt_button) {
    188 return this.scheduleMouseAction_('mouseDown',
    189 webdriver.CommandName.MOUSE_DOWN, opt_elementOrButton, opt_button);
    190};
    191
    192
    193/**
    194 * Releases a mouse button. Behavior is undefined for calling this function
    195 * without a previous call to {@link #mouseDown}.
    196 *
    197 * <p>If an element is provided, the mouse will first be moved to the center
    198 * of that element. This is equivalent to:
    199 * <pre><code>sequence.mouseMove(element).mouseUp()</code></pre>
    200 *
    201 * <p>Warning: this method currently only supports the left mouse button. See
    202 * http://code.google.com/p/selenium/issues/detail?id=4047
    203 *
    204 * @param {(webdriver.WebElement|webdriver.Button)=} opt_elementOrButton Either
    205 * the element to interact with or the button to click with.
    206 * Defaults to {@link webdriver.Button.LEFT} if neither an element nor
    207 * button is specified.
    208 * @param {webdriver.Button=} opt_button The button to use. Defaults to
    209 * {@link webdriver.Button.LEFT}. Ignored if a button is provided as the
    210 * first argument.
    211 * @return {!webdriver.ActionSequence} A self reference.
    212 */
    213webdriver.ActionSequence.prototype.mouseUp = function(opt_elementOrButton,
    214 opt_button) {
    215 return this.scheduleMouseAction_('mouseUp',
    216 webdriver.CommandName.MOUSE_UP, opt_elementOrButton, opt_button);
    217};
    218
    219
    220/**
    221 * Convenience function for performing a "drag and drop" manuever. The target
    222 * element may be moved to the location of another element, or by an offset (in
    223 * pixels).
    224 * @param {!webdriver.WebElement} element The element to drag.
    225 * @param {(!webdriver.WebElement|{x: number, y: number})} location The
    226 * location to drag to, either as another WebElement or an offset in pixels.
    227 * @return {!webdriver.ActionSequence} A self reference.
    228 */
    229webdriver.ActionSequence.prototype.dragAndDrop = function(element, location) {
    230 return this.mouseDown(element).mouseMove(location).mouseUp();
    231};
    232
    233
    234/**
    235 * Clicks a mouse button.
    236 *
    237 * <p>If an element is provided, the mouse will first be moved to the center
    238 * of that element. This is equivalent to:
    239 * <pre><code>sequence.mouseMove(element).click()</code></pre>
    240 *
    241 * @param {(webdriver.WebElement|webdriver.Button)=} opt_elementOrButton Either
    242 * the element to interact with or the button to click with.
    243 * Defaults to {@link webdriver.Button.LEFT} if neither an element nor
    244 * button is specified.
    245 * @param {webdriver.Button=} opt_button The button to use. Defaults to
    246 * {@link webdriver.Button.LEFT}. Ignored if a button is provided as the
    247 * first argument.
    248 * @return {!webdriver.ActionSequence} A self reference.
    249 */
    250webdriver.ActionSequence.prototype.click = function(opt_elementOrButton,
    251 opt_button) {
    252 return this.scheduleMouseAction_('click',
    253 webdriver.CommandName.CLICK, opt_elementOrButton, opt_button);
    254};
    255
    256
    257/**
    258 * Double-clicks a mouse button.
    259 *
    260 * <p>If an element is provided, the mouse will first be moved to the center of
    261 * that element. This is equivalent to:
    262 * <pre><code>sequence.mouseMove(element).doubleClick()</code></pre>
    263 *
    264 * <p>Warning: this method currently only supports the left mouse button. See
    265 * http://code.google.com/p/selenium/issues/detail?id=4047
    266 *
    267 * @param {(webdriver.WebElement|webdriver.Button)=} opt_elementOrButton Either
    268 * the element to interact with or the button to click with.
    269 * Defaults to {@link webdriver.Button.LEFT} if neither an element nor
    270 * button is specified.
    271 * @param {webdriver.Button=} opt_button The button to use. Defaults to
    272 * {@link webdriver.Button.LEFT}. Ignored if a button is provided as the
    273 * first argument.
    274 * @return {!webdriver.ActionSequence} A self reference.
    275 */
    276webdriver.ActionSequence.prototype.doubleClick = function(opt_elementOrButton,
    277 opt_button) {
    278 return this.scheduleMouseAction_('doubleClick',
    279 webdriver.CommandName.DOUBLE_CLICK, opt_elementOrButton, opt_button);
    280};
    281
    282
    283/**
    284 * Schedules a keyboard action.
    285 * @param {string} description A simple descriptive label for the scheduled
    286 * action.
    287 * @param {!Array.<(string|!webdriver.Key)>} keys The keys to send.
    288 * @return {!webdriver.ActionSequence} A self reference.
    289 * @private
    290 */
    291webdriver.ActionSequence.prototype.scheduleKeyboardAction_ = function(
    292 description, keys) {
    293 var command =
    294 new webdriver.Command(webdriver.CommandName.SEND_KEYS_TO_ACTIVE_ELEMENT).
    295 setParameter('value', keys);
    296 this.schedule_(description, command);
    297 return this;
    298};
    299
    300
    301/**
    302 * Checks that a key is a modifier key.
    303 * @param {!webdriver.Key} key The key to check.
    304 * @throws {Error} If the key is not a modifier key.
    305 * @private
    306 */
    307webdriver.ActionSequence.checkModifierKey_ = function(key) {
    308 if (key !== webdriver.Key.ALT && key !== webdriver.Key.CONTROL &&
    309 key !== webdriver.Key.SHIFT && key !== webdriver.Key.COMMAND) {
    310 throw Error('Not a modifier key');
    311 }
    312};
    313
    314
    315/**
    316 * Performs a modifier key press. The modifier key is <em>not released</em>
    317 * until {@link #keyUp} or {@link #sendKeys} is called. The key press will be
    318 * targetted at the currently focused element.
    319 * @param {!webdriver.Key} key The modifier key to push. Must be one of
    320 * {ALT, CONTROL, SHIFT, COMMAND, META}.
    321 * @return {!webdriver.ActionSequence} A self reference.
    322 * @throws {Error} If the key is not a valid modifier key.
    323 */
    324webdriver.ActionSequence.prototype.keyDown = function(key) {
    325 webdriver.ActionSequence.checkModifierKey_(key);
    326 return this.scheduleKeyboardAction_('keyDown', [key]);
    327};
    328
    329
    330/**
    331 * Performs a modifier key release. The release is targetted at the currently
    332 * focused element.
    333 * @param {!webdriver.Key} key The modifier key to release. Must be one of
    334 * {ALT, CONTROL, SHIFT, COMMAND, META}.
    335 * @return {!webdriver.ActionSequence} A self reference.
    336 * @throws {Error} If the key is not a valid modifier key.
    337 */
    338webdriver.ActionSequence.prototype.keyUp = function(key) {
    339 webdriver.ActionSequence.checkModifierKey_(key);
    340 return this.scheduleKeyboardAction_('keyUp', [key]);
    341};
    342
    343
    344/**
    345 * Simulates typing multiple keys. Each modifier key encountered in the
    346 * sequence will not be released until it is encountered again. All key events
    347 * will be targetted at the currently focused element.
    348 * @param {...(string|!webdriver.Key|!Array.<(string|!webdriver.Key)>)} var_args
    349 * The keys to type.
    350 * @return {!webdriver.ActionSequence} A self reference.
    351 * @throws {Error} If the key is not a valid modifier key.
    352 */
    353webdriver.ActionSequence.prototype.sendKeys = function(var_args) {
    354 var keys = goog.array.flatten(goog.array.slice(arguments, 0));
    355 return this.scheduleKeyboardAction_('sendKeys', keys);
    356};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/builder.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/builder.js.src.html new file mode 100644 index 0000000..8e10924 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/builder.js.src.html @@ -0,0 +1 @@ +builder.js

    lib/webdriver/builder.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15goog.provide('webdriver.Builder');
    16
    17goog.require('goog.userAgent');
    18goog.require('webdriver.AbstractBuilder');
    19goog.require('webdriver.FirefoxDomExecutor');
    20goog.require('webdriver.WebDriver');
    21goog.require('webdriver.http.CorsClient');
    22goog.require('webdriver.http.Executor');
    23goog.require('webdriver.http.XhrClient');
    24goog.require('webdriver.process');
    25
    26
    27
    28/**
    29 * @constructor
    30 * @extends {webdriver.AbstractBuilder}
    31 */
    32webdriver.Builder = function() {
    33 goog.base(this);
    34
    35 /**
    36 * ID of an existing WebDriver session that new clients should use.
    37 * Initialized from the value of the
    38 * {@link webdriver.AbstractBuilder.SESSION_ID_ENV} environment variable, but
    39 * may be overridden using
    40 * {@link webdriver.AbstractBuilder#usingSession}.
    41 * @private {string}
    42 */
    43 this.sessionId_ =
    44 webdriver.process.getEnv(webdriver.Builder.SESSION_ID_ENV);
    45};
    46goog.inherits(webdriver.Builder, webdriver.AbstractBuilder);
    47
    48
    49/**
    50 * Environment variable that defines the session ID of an existing WebDriver
    51 * session to use when creating clients. If set, all new Builder instances will
    52 * default to creating clients that use this session. To create a new session,
    53 * use {@code #useExistingSession(boolean)}. The use of this environment
    54 * variable requires that {@link webdriver.AbstractBuilder.SERVER_URL_ENV} also
    55 * be set.
    56 * @type {string}
    57 * @const
    58 * @see webdriver.process.getEnv
    59 */
    60webdriver.Builder.SESSION_ID_ENV = 'wdsid';
    61
    62
    63/**
    64 * Configures the builder to create a client that will use an existing WebDriver
    65 * session.
    66 * @param {string} id The existing session ID to use.
    67 * @return {!webdriver.AbstractBuilder} This Builder instance for chain calling.
    68 */
    69webdriver.Builder.prototype.usingSession = function(id) {
    70 this.sessionId_ = id;
    71 return this;
    72};
    73
    74
    75/**
    76 * @return {string} The ID of the session, if any, this builder is configured
    77 * to reuse.
    78 */
    79webdriver.Builder.prototype.getSession = function() {
    80 return this.sessionId_;
    81};
    82
    83
    84/**
    85 * @override
    86 */
    87webdriver.Builder.prototype.build = function() {
    88 if (goog.userAgent.GECKO && document.readyState != 'complete') {
    89 throw Error('Cannot create driver instance before window.onload');
    90 }
    91
    92 var executor;
    93
    94 if (webdriver.FirefoxDomExecutor.isAvailable()) {
    95 executor = new webdriver.FirefoxDomExecutor();
    96 return webdriver.WebDriver.createSession(executor, this.getCapabilities());
    97 } else {
    98 var url = this.getServerUrl() ||
    99 webdriver.AbstractBuilder.DEFAULT_SERVER_URL;
    100 var client;
    101 if (url[0] == '/') {
    102 var origin = window.location.origin ||
    103 (window.location.protocol + '//' + window.location.host);
    104 client = new webdriver.http.XhrClient(origin + url);
    105 } else {
    106 client = new webdriver.http.CorsClient(url);
    107 }
    108 executor = new webdriver.http.Executor(client);
    109
    110 if (this.getSession()) {
    111 return webdriver.WebDriver.attachToSession(executor, this.getSession());
    112 } else {
    113 throw new Error('Unable to create a new client for this browser. The ' +
    114 'WebDriver session ID has not been defined.');
    115 }
    116 }
    117};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/button.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/button.js.src.html new file mode 100644 index 0000000..2a8728a --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/button.js.src.html @@ -0,0 +1 @@ +button.js

    lib/webdriver/button.js

    1// Copyright 2012 Selenium comitters
    2// Copyright 2012 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16goog.provide('webdriver.Button');
    17
    18
    19/**
    20 * Enumeration of the buttons used in the advanced interactions API.
    21 * @enum {number}
    22 */
    23webdriver.Button = {
    24 LEFT: 0,
    25 MIDDLE: 1,
    26 RIGHT: 2
    27};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/capabilities.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/capabilities.js.src.html new file mode 100644 index 0000000..bd1a54b --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/capabilities.js.src.html @@ -0,0 +1 @@ +capabilities.js

    lib/webdriver/capabilities.js

    1// Copyright 2013 Software Freedom Conservancy
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Defines the webdriver.Capabilities class.
    17 */
    18
    19goog.provide('webdriver.Browser');
    20goog.provide('webdriver.Capabilities');
    21goog.provide('webdriver.Capability');
    22
    23
    24
    25/**
    26 * Recognized browser names.
    27 * @enum {string}
    28 */
    29webdriver.Browser = {
    30 ANDROID: 'android',
    31 CHROME: 'chrome',
    32 FIREFOX: 'firefox',
    33 INTERNET_EXPLORER: 'internet explorer',
    34 IPAD: 'iPad',
    35 IPHONE: 'iPhone',
    36 OPERA: 'opera',
    37 PHANTOM_JS: 'phantomjs',
    38 SAFARI: 'safari',
    39 HTMLUNIT: 'htmlunit'
    40};
    41
    42
    43
    44/**
    45 * Common webdriver capability keys.
    46 * @enum {string}
    47 */
    48webdriver.Capability = {
    49
    50 /**
    51 * Indicates whether a driver should accept all SSL certs by default. This
    52 * capability only applies when requesting a new session. To query whether
    53 * a driver can handle insecure SSL certs, see
    54 * {@link webdriver.Capability.SECURE_SSL}.
    55 */
    56 ACCEPT_SSL_CERTS: 'acceptSslCerts',
    57
    58
    59 /**
    60 * The browser name. Common browser names are defined in the
    61 * {@link webdriver.Browser} enum.
    62 */
    63 BROWSER_NAME: 'browserName',
    64
    65 /**
    66 * Whether the driver is capable of handling modal alerts (e.g. alert,
    67 * confirm, prompt). To define how a driver <i>should</i> handle alerts,
    68 * use {@link webdriver.Capability.UNEXPECTED_ALERT_BEHAVIOR}.
    69 */
    70 HANDLES_ALERTS: 'handlesAlerts',
    71
    72 /**
    73 * Key for the logging driver logging preferences.
    74 */
    75 LOGGING_PREFS: 'loggingPrefs',
    76
    77 /**
    78 * Describes the platform the browser is running on. Will be one of
    79 * ANDROID, IOS, LINUX, MAC, UNIX, or WINDOWS. When <i>requesting</i> a
    80 * session, ANY may be used to indicate no platform preference (this is
    81 * semantically equivalent to omitting the platform capability).
    82 */
    83 PLATFORM: 'platform',
    84
    85 /**
    86 * Describes the proxy configuration to use for a new WebDriver session.
    87 */
    88 PROXY: 'proxy',
    89
    90 /** Whether the driver supports changing the brower's orientation. */
    91 ROTATABLE: 'rotatable',
    92
    93 /**
    94 * Whether a driver is only capable of handling secure SSL certs. To request
    95 * that a driver accept insecure SSL certs by default, use
    96 * {@link webdriver.Capability.ACCEPT_SSL_CERTS}.
    97 */
    98 SECURE_SSL: 'secureSsl',
    99
    100 /** Whether the driver supports manipulating the app cache. */
    101 SUPPORTS_APPLICATION_CACHE: 'applicationCacheEnabled',
    102
    103 /**
    104 * Whether the driver supports controlling the browser's internet
    105 * connectivity.
    106 */
    107 SUPPORTS_BROWSER_CONNECTION: 'browserConnectionEnabled',
    108
    109 /** Whether the driver supports locating elements with CSS selectors. */
    110 SUPPORTS_CSS_SELECTORS: 'cssSelectorsEnabled',
    111
    112 /** Whether the browser supports JavaScript. */
    113 SUPPORTS_JAVASCRIPT: 'javascriptEnabled',
    114
    115 /** Whether the driver supports controlling the browser's location info. */
    116 SUPPORTS_LOCATION_CONTEXT: 'locationContextEnabled',
    117
    118 /** Whether the driver supports taking screenshots. */
    119 TAKES_SCREENSHOT: 'takesScreenshot',
    120
    121 /**
    122 * Defines how the driver should handle unexpected alerts. The value should
    123 * be one of "accept", "dismiss", or "ignore.
    124 */
    125 UNEXPECTED_ALERT_BEHAVIOR: 'unexpectedAlertBehavior',
    126
    127 /** Defines the browser version. */
    128 VERSION: 'version'
    129};
    130
    131
    132
    133/**
    134 * @param {(webdriver.Capabilities|Object)=} opt_other Another set of
    135 * capabilities to merge into this instance.
    136 * @constructor
    137 */
    138webdriver.Capabilities = function(opt_other) {
    139
    140 /** @private {!Object} */
    141 this.caps_ = {};
    142
    143 if (opt_other) {
    144 this.merge(opt_other);
    145 }
    146};
    147
    148
    149/**
    150 * @return {!webdriver.Capabilities} A basic set of capabilities for Android.
    151 */
    152webdriver.Capabilities.android = function() {
    153 return new webdriver.Capabilities().
    154 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.ANDROID).
    155 set(webdriver.Capability.PLATFORM, 'ANDROID');
    156};
    157
    158
    159/**
    160 * @return {!webdriver.Capabilities} A basic set of capabilities for Chrome.
    161 */
    162webdriver.Capabilities.chrome = function() {
    163 return new webdriver.Capabilities().
    164 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.CHROME);
    165};
    166
    167
    168/**
    169 * @return {!webdriver.Capabilities} A basic set of capabilities for Firefox.
    170 */
    171webdriver.Capabilities.firefox = function() {
    172 return new webdriver.Capabilities().
    173 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.FIREFOX);
    174};
    175
    176
    177/**
    178 * @return {!webdriver.Capabilities} A basic set of capabilities for
    179 * Internet Explorer.
    180 */
    181webdriver.Capabilities.ie = function() {
    182 return new webdriver.Capabilities().
    183 set(webdriver.Capability.BROWSER_NAME,
    184 webdriver.Browser.INTERNET_EXPLORER).
    185 set(webdriver.Capability.PLATFORM, 'WINDOWS');
    186};
    187
    188
    189/**
    190 * @return {!webdriver.Capabilities} A basic set of capabilities for iPad.
    191 */
    192webdriver.Capabilities.ipad = function() {
    193 return new webdriver.Capabilities().
    194 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.IPAD).
    195 set(webdriver.Capability.PLATFORM, 'MAC');
    196};
    197
    198
    199/**
    200 * @return {!webdriver.Capabilities} A basic set of capabilities for iPhone.
    201 */
    202webdriver.Capabilities.iphone = function() {
    203 return new webdriver.Capabilities().
    204 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.IPHONE).
    205 set(webdriver.Capability.PLATFORM, 'MAC');
    206};
    207
    208
    209/**
    210 * @return {!webdriver.Capabilities} A basic set of capabilities for Opera.
    211 */
    212webdriver.Capabilities.opera = function() {
    213 return new webdriver.Capabilities().
    214 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.OPERA);
    215};
    216
    217
    218/**
    219 * @return {!webdriver.Capabilities} A basic set of capabilities for
    220 * PhantomJS.
    221 */
    222webdriver.Capabilities.phantomjs = function() {
    223 return new webdriver.Capabilities().
    224 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.PHANTOM_JS);
    225};
    226
    227
    228/**
    229 * @return {!webdriver.Capabilities} A basic set of capabilities for Safari.
    230 */
    231webdriver.Capabilities.safari = function() {
    232 return new webdriver.Capabilities().
    233 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.SAFARI);
    234};
    235
    236
    237/**
    238 * @return {!webdriver.Capabilities} A basic set of capabilities for HTMLUnit.
    239 */
    240webdriver.Capabilities.htmlunit = function() {
    241 return new webdriver.Capabilities().
    242 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.HTMLUNIT);
    243};
    244
    245
    246/**
    247 * @return {!webdriver.Capabilities} A basic set of capabilities for HTMLUnit
    248 * with enabled Javascript.
    249 */
    250webdriver.Capabilities.htmlunitwithjs = function() {
    251 return new webdriver.Capabilities().
    252 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.HTMLUNIT).
    253 set(webdriver.Capability.SUPPORTS_JAVASCRIPT, true);
    254};
    255
    256
    257/** @return {!Object} The JSON representation of this instance. */
    258webdriver.Capabilities.prototype.toJSON = function() {
    259 return this.caps_;
    260};
    261
    262
    263/**
    264 * Merges another set of capabilities into this instance. Any duplicates in
    265 * the provided set will override those already set on this instance.
    266 * @param {!(webdriver.Capabilities|Object)} other The capabilities to
    267 * merge into this instance.
    268 * @return {!webdriver.Capabilities} A self reference.
    269 */
    270webdriver.Capabilities.prototype.merge = function(other) {
    271 var caps = other instanceof webdriver.Capabilities ?
    272 other.caps_ : other;
    273 for (var key in caps) {
    274 if (caps.hasOwnProperty(key)) {
    275 this.set(key, caps[key]);
    276 }
    277 }
    278 return this;
    279};
    280
    281
    282/**
    283 * @param {string} key The capability to set.
    284 * @param {*} value The capability value. Capability values must be JSON
    285 * serializable. Pass {@code null} to unset the capability.
    286 * @return {!webdriver.Capabilities} A self reference.
    287 */
    288webdriver.Capabilities.prototype.set = function(key, value) {
    289 if (goog.isDefAndNotNull(value)) {
    290 this.caps_[key] = value;
    291 } else {
    292 delete this.caps_[key];
    293 }
    294 return this;
    295};
    296
    297
    298/**
    299 * @param {string} key The capability to return.
    300 * @return {*} The capability with the given key, or {@code null} if it has
    301 * not been set.
    302 */
    303webdriver.Capabilities.prototype.get = function(key) {
    304 var val = null;
    305 if (this.caps_.hasOwnProperty(key)) {
    306 val = this.caps_[key];
    307 }
    308 return goog.isDefAndNotNull(val) ? val : null;
    309};
    310
    311
    312/**
    313 * @param {string} key The capability to check.
    314 * @return {boolean} Whether the specified capability is set.
    315 */
    316webdriver.Capabilities.prototype.has = function(key) {
    317 return !!this.get(key);
    318};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/command.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/command.js.src.html new file mode 100644 index 0000000..a22ad8d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/command.js.src.html @@ -0,0 +1 @@ +command.js

    lib/webdriver/command.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Contains several classes for handling commands.
    17 */
    18
    19goog.provide('webdriver.Command');
    20goog.provide('webdriver.CommandExecutor');
    21goog.provide('webdriver.CommandName');
    22
    23
    24
    25/**
    26 * Describes a command to be executed by the WebDriverJS framework.
    27 * @param {!webdriver.CommandName} name The name of this command.
    28 * @constructor
    29 */
    30webdriver.Command = function(name) {
    31
    32 /**
    33 * The name of this command.
    34 * @private {!webdriver.CommandName}
    35 */
    36 this.name_ = name;
    37
    38 /**
    39 * The parameters to this command.
    40 * @private {!Object.<*>}
    41 */
    42 this.parameters_ = {};
    43};
    44
    45
    46/**
    47 * @return {!webdriver.CommandName} This command's name.
    48 */
    49webdriver.Command.prototype.getName = function() {
    50 return this.name_;
    51};
    52
    53
    54/**
    55 * Sets a parameter to send with this command.
    56 * @param {string} name The parameter name.
    57 * @param {*} value The parameter value.
    58 * @return {!webdriver.Command} A self reference.
    59 */
    60webdriver.Command.prototype.setParameter = function(name, value) {
    61 this.parameters_[name] = value;
    62 return this;
    63};
    64
    65
    66/**
    67 * Sets the parameters for this command.
    68 * @param {!Object.<*>} parameters The command parameters.
    69 * @return {!webdriver.Command} A self reference.
    70 */
    71webdriver.Command.prototype.setParameters = function(parameters) {
    72 this.parameters_ = parameters;
    73 return this;
    74};
    75
    76
    77/**
    78 * Returns a named command parameter.
    79 * @param {string} key The parameter key to look up.
    80 * @return {*} The parameter value, or undefined if it has not been set.
    81 */
    82webdriver.Command.prototype.getParameter = function(key) {
    83 return this.parameters_[key];
    84};
    85
    86
    87/**
    88 * @return {!Object.<*>} The parameters to send with this command.
    89 */
    90webdriver.Command.prototype.getParameters = function() {
    91 return this.parameters_;
    92};
    93
    94
    95/**
    96 * Enumeration of predefined names command names that all command processors
    97 * will support.
    98 * @enum {string}
    99 */
    100// TODO: Delete obsolete command names.
    101webdriver.CommandName = {
    102 GET_SERVER_STATUS: 'getStatus',
    103
    104 NEW_SESSION: 'newSession',
    105 GET_SESSIONS: 'getSessions',
    106 DESCRIBE_SESSION: 'getSessionCapabilities',
    107
    108 CLOSE: 'close',
    109 QUIT: 'quit',
    110
    111 GET_CURRENT_URL: 'getCurrentUrl',
    112 GET: 'get',
    113 GO_BACK: 'goBack',
    114 GO_FORWARD: 'goForward',
    115 REFRESH: 'refresh',
    116
    117 ADD_COOKIE: 'addCookie',
    118 GET_COOKIE: 'getCookie',
    119 GET_ALL_COOKIES: 'getCookies',
    120 DELETE_COOKIE: 'deleteCookie',
    121 DELETE_ALL_COOKIES: 'deleteAllCookies',
    122
    123 GET_ACTIVE_ELEMENT: 'getActiveElement',
    124 FIND_ELEMENT: 'findElement',
    125 FIND_ELEMENTS: 'findElements',
    126 FIND_CHILD_ELEMENT: 'findChildElement',
    127 FIND_CHILD_ELEMENTS: 'findChildElements',
    128
    129 CLEAR_ELEMENT: 'clearElement',
    130 CLICK_ELEMENT: 'clickElement',
    131 SEND_KEYS_TO_ELEMENT: 'sendKeysToElement',
    132 SUBMIT_ELEMENT: 'submitElement',
    133
    134 GET_CURRENT_WINDOW_HANDLE: 'getCurrentWindowHandle',
    135 GET_WINDOW_HANDLES: 'getWindowHandles',
    136 GET_WINDOW_POSITION: 'getWindowPosition',
    137 SET_WINDOW_POSITION: 'setWindowPosition',
    138 GET_WINDOW_SIZE: 'getWindowSize',
    139 SET_WINDOW_SIZE: 'setWindowSize',
    140 MAXIMIZE_WINDOW: 'maximizeWindow',
    141
    142 SWITCH_TO_WINDOW: 'switchToWindow',
    143 SWITCH_TO_FRAME: 'switchToFrame',
    144 GET_PAGE_SOURCE: 'getPageSource',
    145 GET_TITLE: 'getTitle',
    146
    147 EXECUTE_SCRIPT: 'executeScript',
    148 EXECUTE_ASYNC_SCRIPT: 'executeAsyncScript',
    149
    150 GET_ELEMENT_TEXT: 'getElementText',
    151 GET_ELEMENT_TAG_NAME: 'getElementTagName',
    152 IS_ELEMENT_SELECTED: 'isElementSelected',
    153 IS_ELEMENT_ENABLED: 'isElementEnabled',
    154 IS_ELEMENT_DISPLAYED: 'isElementDisplayed',
    155 GET_ELEMENT_LOCATION: 'getElementLocation',
    156 GET_ELEMENT_LOCATION_IN_VIEW: 'getElementLocationOnceScrolledIntoView',
    157 GET_ELEMENT_SIZE: 'getElementSize',
    158 GET_ELEMENT_ATTRIBUTE: 'getElementAttribute',
    159 GET_ELEMENT_VALUE_OF_CSS_PROPERTY: 'getElementValueOfCssProperty',
    160 ELEMENT_EQUALS: 'elementEquals',
    161
    162 SCREENSHOT: 'screenshot',
    163 IMPLICITLY_WAIT: 'implicitlyWait',
    164 SET_SCRIPT_TIMEOUT: 'setScriptTimeout',
    165 SET_TIMEOUT: 'setTimeout',
    166
    167 ACCEPT_ALERT: 'acceptAlert',
    168 DISMISS_ALERT: 'dismissAlert',
    169 GET_ALERT_TEXT: 'getAlertText',
    170 SET_ALERT_TEXT: 'setAlertValue',
    171
    172 EXECUTE_SQL: 'executeSQL',
    173 GET_LOCATION: 'getLocation',
    174 SET_LOCATION: 'setLocation',
    175 GET_APP_CACHE: 'getAppCache',
    176 GET_APP_CACHE_STATUS: 'getStatus',
    177 CLEAR_APP_CACHE: 'clearAppCache',
    178 IS_BROWSER_ONLINE: 'isBrowserOnline',
    179 SET_BROWSER_ONLINE: 'setBrowserOnline',
    180
    181 GET_LOCAL_STORAGE_ITEM: 'getLocalStorageItem',
    182 GET_LOCAL_STORAGE_KEYS: 'getLocalStorageKeys',
    183 SET_LOCAL_STORAGE_ITEM: 'setLocalStorageItem',
    184 REMOVE_LOCAL_STORAGE_ITEM: 'removeLocalStorageItem',
    185 CLEAR_LOCAL_STORAGE: 'clearLocalStorage',
    186 GET_LOCAL_STORAGE_SIZE: 'getLocalStorageSize',
    187
    188 GET_SESSION_STORAGE_ITEM: 'getSessionStorageItem',
    189 GET_SESSION_STORAGE_KEYS: 'getSessionStorageKey',
    190 SET_SESSION_STORAGE_ITEM: 'setSessionStorageItem',
    191 REMOVE_SESSION_STORAGE_ITEM: 'removeSessionStorageItem',
    192 CLEAR_SESSION_STORAGE: 'clearSessionStorage',
    193 GET_SESSION_STORAGE_SIZE: 'getSessionStorageSize',
    194
    195 SET_SCREEN_ORIENTATION: 'setScreenOrientation',
    196 GET_SCREEN_ORIENTATION: 'getScreenOrientation',
    197
    198 // These belong to the Advanced user interactions - an element is
    199 // optional for these commands.
    200 CLICK: 'mouseClick',
    201 DOUBLE_CLICK: 'mouseDoubleClick',
    202 MOUSE_DOWN: 'mouseButtonDown',
    203 MOUSE_UP: 'mouseButtonUp',
    204 MOVE_TO: 'mouseMoveTo',
    205 SEND_KEYS_TO_ACTIVE_ELEMENT: 'sendKeysToActiveElement',
    206
    207 // These belong to the Advanced Touch API
    208 TOUCH_SINGLE_TAP: 'touchSingleTap',
    209 TOUCH_DOWN: 'touchDown',
    210 TOUCH_UP: 'touchUp',
    211 TOUCH_MOVE: 'touchMove',
    212 TOUCH_SCROLL: 'touchScroll',
    213 TOUCH_DOUBLE_TAP: 'touchDoubleTap',
    214 TOUCH_LONG_PRESS: 'touchLongPress',
    215 TOUCH_FLICK: 'touchFlick',
    216
    217 GET_AVAILABLE_LOG_TYPES: 'getAvailableLogTypes',
    218 GET_LOG: 'getLog',
    219 GET_SESSION_LOGS: 'getSessionLogs'
    220};
    221
    222
    223
    224/**
    225 * Handles the execution of {@code webdriver.Command} objects.
    226 * @interface
    227 */
    228webdriver.CommandExecutor = function() {};
    229
    230
    231/**
    232 * Executes the given {@code command}. If there is an error executing the
    233 * command, the provided callback will be invoked with the offending error.
    234 * Otherwise, the callback will be invoked with a null Error and non-null
    235 * {@link bot.response.ResponseObject} object.
    236 * @param {!webdriver.Command} command The command to execute.
    237 * @param {function(Error, !bot.response.ResponseObject=)} callback the function
    238 * to invoke when the command response is ready.
    239 */
    240webdriver.CommandExecutor.prototype.execute = goog.abstractMethod;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/events.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/events.js.src.html new file mode 100644 index 0000000..c60d9c5 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/events.js.src.html @@ -0,0 +1 @@ +events.js

    lib/webdriver/events.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview A light weight event system modeled after Node's EventEmitter.
    17 */
    18
    19goog.provide('webdriver.EventEmitter');
    20
    21
    22
    23/**
    24 * Object that can emit events for others to listen for. This is used instead
    25 * of Closure's event system because it is much more light weight. The API is
    26 * based on Node's EventEmitters.
    27 * @constructor
    28 */
    29webdriver.EventEmitter = function() {
    30 /**
    31 * Map of events to registered listeners.
    32 * @private {!Object.<!Array.<{fn: !Function, oneshot: boolean,
    33 * scope: (Object|undefined)}>>}
    34 */
    35 this.events_ = {};
    36};
    37
    38
    39/**
    40 * Fires an event and calls all listeners.
    41 * @param {string} type The type of event to emit.
    42 * @param {...*} var_args Any arguments to pass to each listener.
    43 */
    44webdriver.EventEmitter.prototype.emit = function(type, var_args) {
    45 var args = Array.prototype.slice.call(arguments, 1);
    46 var listeners = this.events_[type];
    47 if (!listeners) {
    48 return;
    49 }
    50 for (var i = 0; i < listeners.length;) {
    51 var listener = listeners[i];
    52 listener.fn.apply(listener.scope, args);
    53 if (listeners[i] === listener) {
    54 if (listeners[i].oneshot) {
    55 listeners.splice(i, 1);
    56 } else {
    57 i += 1;
    58 }
    59 }
    60 }
    61};
    62
    63
    64/**
    65 * Returns a mutable list of listeners for a specific type of event.
    66 * @param {string} type The type of event to retrieve the listeners for.
    67 * @return {!Array.<{fn: !Function, oneshot: boolean,
    68 * scope: (Object|undefined)}>} The registered listeners for
    69 * the given event type.
    70 */
    71webdriver.EventEmitter.prototype.listeners = function(type) {
    72 var listeners = this.events_[type];
    73 if (!listeners) {
    74 listeners = this.events_[type] = [];
    75 }
    76 return listeners;
    77};
    78
    79
    80/**
    81 * Registers a listener.
    82 * @param {string} type The type of event to listen for.
    83 * @param {!Function} listenerFn The function to invoke when the event is fired.
    84 * @param {Object=} opt_scope The object in whose scope to invoke the listener.
    85 * @param {boolean=} opt_oneshot Whether the listener should be removed after
    86 * the first event is fired.
    87 * @return {!webdriver.EventEmitter} A self reference.
    88 * @private
    89 */
    90webdriver.EventEmitter.prototype.addListener_ = function(type, listenerFn,
    91 opt_scope, opt_oneshot) {
    92 var listeners = this.listeners(type);
    93 var n = listeners.length;
    94 for (var i = 0; i < n; ++i) {
    95 if (listeners[i].fn == listenerFn) {
    96 return this;
    97 }
    98 }
    99
    100 listeners.push({
    101 fn: listenerFn,
    102 scope: opt_scope,
    103 oneshot: !!opt_oneshot
    104 });
    105 return this;
    106};
    107
    108
    109/**
    110 * Registers a listener.
    111 * @param {string} type The type of event to listen for.
    112 * @param {!Function} listenerFn The function to invoke when the event is fired.
    113 * @param {Object=} opt_scope The object in whose scope to invoke the listener.
    114 * @return {!webdriver.EventEmitter} A self reference.
    115 */
    116webdriver.EventEmitter.prototype.addListener = function(type, listenerFn,
    117 opt_scope) {
    118 return this.addListener_(type, listenerFn, opt_scope);
    119};
    120
    121
    122/**
    123 * Registers a one-time listener which will be called only the first time an
    124 * event is emitted, after which it will be removed.
    125 * @param {string} type The type of event to listen for.
    126 * @param {!Function} listenerFn The function to invoke when the event is fired.
    127 * @param {Object=} opt_scope The object in whose scope to invoke the listener.
    128 * @return {!webdriver.EventEmitter} A self reference.
    129 */
    130webdriver.EventEmitter.prototype.once = function(type, listenerFn, opt_scope) {
    131 return this.addListener_(type, listenerFn, opt_scope, true);
    132};
    133
    134
    135/**
    136 * An alias for {@code #addListener()}.
    137 * @param {string} type The type of event to listen for.
    138 * @param {!Function} listenerFn The function to invoke when the event is fired.
    139 * @param {Object=} opt_scope The object in whose scope to invoke the listener.
    140 * @return {!webdriver.EventEmitter} A self reference.
    141 */
    142webdriver.EventEmitter.prototype.on =
    143 webdriver.EventEmitter.prototype.addListener;
    144
    145
    146/**
    147 * Removes a previously registered event listener.
    148 * @param {string} type The type of event to unregister.
    149 * @param {!Function} listenerFn The handler function to remove.
    150 * @return {!webdriver.EventEmitter} A self reference.
    151 */
    152webdriver.EventEmitter.prototype.removeListener = function(type, listenerFn) {
    153 var listeners = this.events_[type];
    154 if (listeners) {
    155 var n = listeners.length;
    156 for (var i = 0; i < n; ++i) {
    157 if (listeners[i].fn == listenerFn) {
    158 listeners.splice(i, 1);
    159 return this;
    160 }
    161 }
    162 }
    163 return this;
    164};
    165
    166
    167/**
    168 * Removes all listeners for a specific type of event. If no event is
    169 * specified, all listeners across all types will be removed.
    170 * @param {string=} opt_type The type of event to remove listeners from.
    171 * @return {!webdriver.EventEmitter} A self reference.
    172 */
    173webdriver.EventEmitter.prototype.removeAllListeners = function(opt_type) {
    174 goog.isDef(opt_type) ? delete this.events_[opt_type] : this.events_ = {};
    175 return this;
    176};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/firefoxdomexecutor.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/firefoxdomexecutor.js.src.html new file mode 100644 index 0000000..069f4dd --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/firefoxdomexecutor.js.src.html @@ -0,0 +1 @@ +firefoxdomexecutor.js

    lib/webdriver/firefoxdomexecutor.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15goog.provide('webdriver.FirefoxDomExecutor');
    16
    17goog.require('bot.response');
    18goog.require('goog.json');
    19goog.require('goog.userAgent.product');
    20goog.require('webdriver.Command');
    21goog.require('webdriver.CommandName');
    22
    23
    24
    25/**
    26 * @constructor
    27 * @implements {webdriver.CommandExecutor}
    28 */
    29webdriver.FirefoxDomExecutor = function() {
    30 if (!webdriver.FirefoxDomExecutor.isAvailable()) {
    31 throw Error(
    32 'The current environment does not support the FirefoxDomExecutor');
    33 }
    34
    35 /** @private {!Document} */
    36 this.doc_ = document;
    37
    38 /** @private {!Element} */
    39 this.docElement_ = document.documentElement;
    40
    41 this.docElement_.addEventListener(
    42 webdriver.FirefoxDomExecutor.EventType_.RESPONSE,
    43 goog.bind(this.onResponse_, this), false);
    44};
    45
    46
    47/**
    48 * @return {boolean} Whether the current environment supports the
    49 * FirefoxDomExecutor.
    50 */
    51webdriver.FirefoxDomExecutor.isAvailable = function() {
    52 return goog.userAgent.product.FIREFOX &&
    53 typeof document !== 'undefined' &&
    54 document.documentElement &&
    55 goog.isFunction(document.documentElement.hasAttribute) &&
    56 document.documentElement.hasAttribute('webdriver');
    57};
    58
    59
    60/**
    61 * Attributes used to communicate with the FirefoxDriver extension.
    62 * @enum {string}
    63 * @private
    64 */
    65webdriver.FirefoxDomExecutor.Attribute_ = {
    66 COMMAND: 'command',
    67 RESPONSE: 'response'
    68};
    69
    70
    71/**
    72 * Events used to communicate with the FirefoxDriver extension.
    73 * @enum {string}
    74 * @private
    75 */
    76webdriver.FirefoxDomExecutor.EventType_ = {
    77 COMMAND: 'webdriverCommand',
    78 RESPONSE: 'webdriverResponse'
    79};
    80
    81
    82/**
    83 * The pending command, if any.
    84 * @private {?{name:string, callback:!Function}}
    85 */
    86webdriver.FirefoxDomExecutor.prototype.pendingCommand_ = null;
    87
    88
    89/** @override */
    90webdriver.FirefoxDomExecutor.prototype.execute = function(command, callback) {
    91 if (this.pendingCommand_) {
    92 throw Error('Currently awaiting a command response!');
    93 }
    94
    95 this.pendingCommand_ = {
    96 name: command.getName(),
    97 callback: callback
    98 };
    99
    100 var parameters = command.getParameters();
    101
    102 // There are two means for communicating with the FirefoxDriver: via
    103 // HTTP using WebDriver's wire protocol and over the DOM using a custom
    104 // JSON protocol. This class uses the latter. When the FirefoxDriver receives
    105 // commands over HTTP, it builds a parameters object from the URL parameters.
    106 // When an element ID is sent in the URL, it'll be decoded as just id:string
    107 // instead of id:{ELEMENT:string}. When switching to a frame by element,
    108 // however, the element ID is not sent through the URL, so we must make sure
    109 // to encode that parameter properly here. It would be nice if we unified
    110 // the two protocols used by the FirefoxDriver...
    111 if (parameters['id'] &&
    112 parameters['id']['ELEMENT'] &&
    113 command.getName() != webdriver.CommandName.SWITCH_TO_FRAME) {
    114 parameters['id'] = parameters['id']['ELEMENT'];
    115 }
    116 var json = goog.json.serialize({
    117 'name': command.getName(),
    118 'sessionId': parameters['sessionId'],
    119 'parameters': parameters
    120 });
    121 this.docElement_.setAttribute(
    122 webdriver.FirefoxDomExecutor.Attribute_.COMMAND, json);
    123
    124 var event = this.doc_.createEvent('Event');
    125 event.initEvent(webdriver.FirefoxDomExecutor.EventType_.COMMAND,
    126 /*canBubble=*/true, /*cancelable=*/true);
    127
    128 this.docElement_.dispatchEvent(event);
    129};
    130
    131
    132/** @private */
    133webdriver.FirefoxDomExecutor.prototype.onResponse_ = function() {
    134 if (!this.pendingCommand_) {
    135 return; // Not expecting a response.
    136 }
    137
    138 var command = this.pendingCommand_;
    139 this.pendingCommand_ = null;
    140
    141 var json = this.docElement_.getAttribute(
    142 webdriver.FirefoxDomExecutor.Attribute_.RESPONSE);
    143 if (!json) {
    144 command.callback(Error('Empty command response!'));
    145 return;
    146 }
    147
    148 this.docElement_.removeAttribute(
    149 webdriver.FirefoxDomExecutor.Attribute_.COMMAND);
    150 this.docElement_.removeAttribute(
    151 webdriver.FirefoxDomExecutor.Attribute_.RESPONSE);
    152
    153 try {
    154 var response = bot.response.checkResponse(
    155 /** @type {!bot.response.ResponseObject} */ (goog.json.parse(json)));
    156 } catch (ex) {
    157 command.callback(ex);
    158 return;
    159 }
    160
    161 // Prior to Selenium 2.35.0, two commands are required to fully create a
    162 // session: one to allocate the session, and another to fetch the
    163 // capabilities.
    164 if (command.name == webdriver.CommandName.NEW_SESSION &&
    165 goog.isString(response['value'])) {
    166 var cmd = new webdriver.Command(webdriver.CommandName.DESCRIBE_SESSION).
    167 setParameter('sessionId', response['value']);
    168 this.execute(cmd, command.callback);
    169 } else {
    170 command.callback(null, response);
    171 }
    172};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/http/corsclient.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/http/corsclient.js.src.html new file mode 100644 index 0000000..f33da44 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/http/corsclient.js.src.html @@ -0,0 +1 @@ +corsclient.js

    lib/webdriver/http/corsclient.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15goog.provide('webdriver.http.CorsClient');
    16
    17goog.require('goog.json');
    18goog.require('webdriver.http.Response');
    19
    20
    21
    22/**
    23 * Communicates with a WebDriver server, which may be on a different domain,
    24 * using the <a href="http://www.w3.org/TR/cors/">cross-origin resource sharing
    25 * </a> (CORS) extension to WebDriver's JSON wire protocol.
    26 *
    27 * <p>Each command from the standard JSON protocol will be encoded in a
    28 * JSON object with the following form:
    29 * {method:string, path:string, data:!Object}
    30 *
    31 * <p>The encoded command is then sent as a POST request to the server's /xdrpc
    32 * endpoint. The server will decode the command, re-route it to the appropriate
    33 * handler, and then return the command's response as a standard JSON response
    34 * object. The JSON responses will <em>always</em> be returned with a 200
    35 * response from the server; clients must rely on the response's "status" field
    36 * to determine whether the command succeeded.
    37 *
    38 * <p>This client cannot be used with the standard wire protocol due to
    39 * limitations in the various browser implementations of the CORS specification:
    40 * <ul>
    41 * <li>IE's <a href="http://goo.gl/6l3kA">XDomainRequest</a> object is only
    42 * capable of generating the types of requests that may be generated through
    43 * a standard <a href="http://goo.gl/vgzAU">HTML form</a> - it can not send
    44 * DELETE requests, as is required in the wire protocol.
    45 * <li>WebKit's implementation of CORS does not follow the spec and forbids
    46 * redirects: https://bugs.webkit.org/show_bug.cgi?id=57600
    47 * This limitation appears to be intentional and is documented in WebKit's
    48 * Layout tests:
    49 * //LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects.html
    50 * <li>If the server does not return a 2xx response, IE and Opera's
    51 * implementations will fire the XDomainRequest/XMLHttpRequest object's
    52 * onerror handler, but without the corresponding response text returned by
    53 * the server. This renders IE and Opera incapable of handling command
    54 * failures in the standard JSON protocol.
    55 * </ul>
    56 *
    57 * @param {string} url URL for the WebDriver server to send commands to.
    58 * @constructor
    59 * @implements {webdriver.http.Client}
    60 * @see <a href="http://www.w3.org/TR/cors/">CORS Spec</a>
    61 * @see <a href="http://code.google.com/p/selenium/wiki/JsonWireProtocol">
    62 * JSON wire protocol</a>
    63 */
    64webdriver.http.CorsClient = function(url) {
    65 if (!webdriver.http.CorsClient.isAvailable()) {
    66 throw Error('The current environment does not support cross-origin ' +
    67 'resource sharing');
    68 }
    69
    70 /** @private {string} */
    71 this.url_ = url + webdriver.http.CorsClient.XDRPC_ENDPOINT;
    72};
    73
    74
    75/**
    76 * Resource URL to send commands to on the server.
    77 * @type {string}
    78 * @const
    79 */
    80webdriver.http.CorsClient.XDRPC_ENDPOINT = '/xdrpc';
    81
    82
    83/**
    84 * Tests whether the current environment supports cross-origin resource sharing.
    85 * @return {boolean} Whether cross-origin resource sharing is supported.
    86 * @see http://www.w3.org/TR/cors/
    87 */
    88webdriver.http.CorsClient.isAvailable = function() {
    89 return typeof XDomainRequest !== 'undefined' ||
    90 (typeof XMLHttpRequest !== 'undefined' &&
    91 goog.isBoolean(new XMLHttpRequest().withCredentials));
    92};
    93
    94
    95/** @override */
    96webdriver.http.CorsClient.prototype.send = function(request, callback) {
    97 try {
    98 var xhr = new (typeof XDomainRequest !== 'undefined' ?
    99 XDomainRequest : XMLHttpRequest);
    100 xhr.open('POST', this.url_, true);
    101
    102 xhr.onload = function() {
    103 callback(null, webdriver.http.Response.fromXmlHttpRequest(
    104 /** @type {!XMLHttpRequest} */ (xhr)));
    105 };
    106
    107 var url = this.url_;
    108 xhr.onerror = function() {
    109 callback(Error([
    110 'Unable to send request: POST ', url,
    111 '\nPerhaps the server did not respond to the preflight request ',
    112 'with valid access control headers?'
    113 ].join('')));
    114 };
    115
    116 // Define event handlers for all events on the XDomainRequest. Apparently,
    117 // if we don't do this, IE9+10 will silently abort our request. Yay IE.
    118 // Note, we're not using goog.nullFunction, because it tends to get
    119 // optimized away by the compiler, which leaves us where we were before.
    120 xhr.onprogress = xhr.ontimeout = function() {};
    121
    122 xhr.send(goog.json.serialize({
    123 'method': request.method,
    124 'path': request.path,
    125 'data': request.data
    126 }));
    127 } catch (ex) {
    128 callback(ex);
    129 }
    130};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/http/http.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/http/http.js.src.html new file mode 100644 index 0000000..291e8c3 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/http/http.js.src.html @@ -0,0 +1 @@ +http.js

    lib/webdriver/http/http.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Defines a {@code webdriver.CommandExecutor} that communicates
    17 * with a server over HTTP.
    18 */
    19
    20goog.provide('webdriver.http.Client');
    21goog.provide('webdriver.http.Executor');
    22goog.provide('webdriver.http.Request');
    23goog.provide('webdriver.http.Response');
    24
    25goog.require('bot.ErrorCode');
    26goog.require('goog.array');
    27goog.require('goog.json');
    28goog.require('webdriver.CommandName');
    29goog.require('webdriver.promise.Deferred');
    30
    31
    32
    33/**
    34 * Interface used for sending individual HTTP requests to the server.
    35 * @interface
    36 */
    37webdriver.http.Client = function() {
    38};
    39
    40
    41/**
    42 * Sends a request to the server. If an error occurs while sending the request,
    43 * such as a failure to connect to the server, the provided callback will be
    44 * invoked with a non-null {@code Error} describing the error. Otherwise, when
    45 * the server's response has been received, the callback will be invoked with a
    46 * null Error and non-null {@code webdriver.http.Response} object.
    47 *
    48 * @param {!webdriver.http.Request} request The request to send.
    49 * @param {function(Error, !webdriver.http.Response=)} callback the function to
    50 * invoke when the server's response is ready.
    51 */
    52webdriver.http.Client.prototype.send = function(request, callback) {
    53};
    54
    55
    56
    57/**
    58 * A command executor that communicates with a server using the WebDriver
    59 * command protocol.
    60 * @param {!webdriver.http.Client} client The client to use when sending
    61 * requests to the server.
    62 * @constructor
    63 * @implements {webdriver.CommandExecutor}
    64 */
    65webdriver.http.Executor = function(client) {
    66
    67 /**
    68 * Client used to communicate with the server.
    69 * @private {!webdriver.http.Client}
    70 */
    71 this.client_ = client;
    72};
    73
    74
    75/** @override */
    76webdriver.http.Executor.prototype.execute = function(command, callback) {
    77 var resource = webdriver.http.Executor.COMMAND_MAP_[command.getName()];
    78 if (!resource) {
    79 throw new Error('Unrecognized command: ' + command.getName());
    80 }
    81
    82 var parameters = command.getParameters();
    83 var path = webdriver.http.Executor.buildPath_(resource.path, parameters);
    84 var request = new webdriver.http.Request(resource.method, path, parameters);
    85
    86 this.client_.send(request, function(e, response) {
    87 var responseObj;
    88 if (!e) {
    89 try {
    90 responseObj = webdriver.http.Executor.parseHttpResponse_(
    91 /** @type {!webdriver.http.Response} */ (response));
    92 } catch (ex) {
    93 e = ex;
    94 }
    95 }
    96 callback(e, responseObj);
    97 });
    98};
    99
    100
    101/**
    102 * Builds a fully qualified path using the given set of command parameters. Each
    103 * path segment prefixed with ':' will be replaced by the value of the
    104 * corresponding parameter. All parameters spliced into the path will be
    105 * removed from the parameter map.
    106 * @param {string} path The original resource path.
    107 * @param {!Object.<*>} parameters The parameters object to splice into
    108 * the path.
    109 * @return {string} The modified path.
    110 * @private
    111 */
    112webdriver.http.Executor.buildPath_ = function(path, parameters) {
    113 var pathParameters = path.match(/\/:(\w+)\b/g);
    114 if (pathParameters) {
    115 for (var i = 0; i < pathParameters.length; ++i) {
    116 var key = pathParameters[i].substring(2); // Trim the /:
    117 if (key in parameters) {
    118 var value = parameters[key];
    119 // TODO: move webdriver.WebElement.ELEMENT definition to a
    120 // common file so we can reference it here without pulling in all of
    121 // webdriver.WebElement's dependencies.
    122 if (value && value['ELEMENT']) {
    123 // When inserting a WebElement into the URL, only use its ID value,
    124 // not the full JSON.
    125 value = value['ELEMENT'];
    126 }
    127 path = path.replace(pathParameters[i], '/' + value);
    128 delete parameters[key];
    129 } else {
    130 throw new Error('Missing required parameter: ' + key);
    131 }
    132 }
    133 }
    134 return path;
    135};
    136
    137
    138/**
    139 * Callback used to parse {@link webdriver.http.Response} objects from a
    140 * {@link webdriver.http.Client}.
    141 * @param {!webdriver.http.Response} httpResponse The HTTP response to parse.
    142 * @return {!bot.response.ResponseObject} The parsed response.
    143 * @private
    144 */
    145webdriver.http.Executor.parseHttpResponse_ = function(httpResponse) {
    146 try {
    147 return /** @type {!bot.response.ResponseObject} */ (goog.json.parse(
    148 httpResponse.body));
    149 } catch (ex) {
    150 // Whoops, looks like the server sent us a malformed response. We'll need
    151 // to manually build a response object based on the response code.
    152 }
    153
    154 var response = {
    155 'status': bot.ErrorCode.SUCCESS,
    156 'value': httpResponse.body.replace(/\r\n/g, '\n')
    157 };
    158
    159 if (!(httpResponse.status > 199 && httpResponse.status < 300)) {
    160 // 404 represents an unknown command; anything else is a generic unknown
    161 // error.
    162 response['status'] = httpResponse.status == 404 ?
    163 bot.ErrorCode.UNKNOWN_COMMAND :
    164 bot.ErrorCode.UNKNOWN_ERROR;
    165 }
    166
    167 return response;
    168};
    169
    170
    171/**
    172 * Maps command names to resource locator.
    173 * @private {!Object.<{method:string, path:string}>}
    174 * @const
    175 */
    176webdriver.http.Executor.COMMAND_MAP_ = (function() {
    177 return new Builder().
    178 put(webdriver.CommandName.GET_SERVER_STATUS, get('/status')).
    179 put(webdriver.CommandName.NEW_SESSION, post('/session')).
    180 put(webdriver.CommandName.GET_SESSIONS, get('/sessions')).
    181 put(webdriver.CommandName.DESCRIBE_SESSION, get('/session/:sessionId')).
    182 put(webdriver.CommandName.QUIT, del('/session/:sessionId')).
    183 put(webdriver.CommandName.CLOSE, del('/session/:sessionId/window')).
    184 put(webdriver.CommandName.GET_CURRENT_WINDOW_HANDLE,
    185 get('/session/:sessionId/window_handle')).
    186 put(webdriver.CommandName.GET_WINDOW_HANDLES,
    187 get('/session/:sessionId/window_handles')).
    188 put(webdriver.CommandName.GET_CURRENT_URL,
    189 get('/session/:sessionId/url')).
    190 put(webdriver.CommandName.GET, post('/session/:sessionId/url')).
    191 put(webdriver.CommandName.GO_BACK, post('/session/:sessionId/back')).
    192 put(webdriver.CommandName.GO_FORWARD,
    193 post('/session/:sessionId/forward')).
    194 put(webdriver.CommandName.REFRESH,
    195 post('/session/:sessionId/refresh')).
    196 put(webdriver.CommandName.ADD_COOKIE,
    197 post('/session/:sessionId/cookie')).
    198 put(webdriver.CommandName.GET_ALL_COOKIES,
    199 get('/session/:sessionId/cookie')).
    200 put(webdriver.CommandName.DELETE_ALL_COOKIES,
    201 del('/session/:sessionId/cookie')).
    202 put(webdriver.CommandName.DELETE_COOKIE,
    203 del('/session/:sessionId/cookie/:name')).
    204 put(webdriver.CommandName.FIND_ELEMENT,
    205 post('/session/:sessionId/element')).
    206 put(webdriver.CommandName.FIND_ELEMENTS,
    207 post('/session/:sessionId/elements')).
    208 put(webdriver.CommandName.GET_ACTIVE_ELEMENT,
    209 post('/session/:sessionId/element/active')).
    210 put(webdriver.CommandName.FIND_CHILD_ELEMENT,
    211 post('/session/:sessionId/element/:id/element')).
    212 put(webdriver.CommandName.FIND_CHILD_ELEMENTS,
    213 post('/session/:sessionId/element/:id/elements')).
    214 put(webdriver.CommandName.CLEAR_ELEMENT,
    215 post('/session/:sessionId/element/:id/clear')).
    216 put(webdriver.CommandName.CLICK_ELEMENT,
    217 post('/session/:sessionId/element/:id/click')).
    218 put(webdriver.CommandName.SEND_KEYS_TO_ELEMENT,
    219 post('/session/:sessionId/element/:id/value')).
    220 put(webdriver.CommandName.SUBMIT_ELEMENT,
    221 post('/session/:sessionId/element/:id/submit')).
    222 put(webdriver.CommandName.GET_ELEMENT_TEXT,
    223 get('/session/:sessionId/element/:id/text')).
    224 put(webdriver.CommandName.GET_ELEMENT_TAG_NAME,
    225 get('/session/:sessionId/element/:id/name')).
    226 put(webdriver.CommandName.IS_ELEMENT_SELECTED,
    227 get('/session/:sessionId/element/:id/selected')).
    228 put(webdriver.CommandName.IS_ELEMENT_ENABLED,
    229 get('/session/:sessionId/element/:id/enabled')).
    230 put(webdriver.CommandName.IS_ELEMENT_DISPLAYED,
    231 get('/session/:sessionId/element/:id/displayed')).
    232 put(webdriver.CommandName.GET_ELEMENT_LOCATION,
    233 get('/session/:sessionId/element/:id/location')).
    234 put(webdriver.CommandName.GET_ELEMENT_SIZE,
    235 get('/session/:sessionId/element/:id/size')).
    236 put(webdriver.CommandName.GET_ELEMENT_ATTRIBUTE,
    237 get('/session/:sessionId/element/:id/attribute/:name')).
    238 put(webdriver.CommandName.GET_ELEMENT_VALUE_OF_CSS_PROPERTY,
    239 get('/session/:sessionId/element/:id/css/:propertyName')).
    240 put(webdriver.CommandName.ELEMENT_EQUALS,
    241 get('/session/:sessionId/element/:id/equals/:other')).
    242 put(webdriver.CommandName.SWITCH_TO_WINDOW,
    243 post('/session/:sessionId/window')).
    244 put(webdriver.CommandName.MAXIMIZE_WINDOW,
    245 post('/session/:sessionId/window/:windowHandle/maximize')).
    246 put(webdriver.CommandName.GET_WINDOW_POSITION,
    247 get('/session/:sessionId/window/:windowHandle/position')).
    248 put(webdriver.CommandName.SET_WINDOW_POSITION,
    249 post('/session/:sessionId/window/:windowHandle/position')).
    250 put(webdriver.CommandName.GET_WINDOW_SIZE,
    251 get('/session/:sessionId/window/:windowHandle/size')).
    252 put(webdriver.CommandName.SET_WINDOW_SIZE,
    253 post('/session/:sessionId/window/:windowHandle/size')).
    254 put(webdriver.CommandName.SWITCH_TO_FRAME,
    255 post('/session/:sessionId/frame')).
    256 put(webdriver.CommandName.GET_PAGE_SOURCE,
    257 get('/session/:sessionId/source')).
    258 put(webdriver.CommandName.GET_TITLE,
    259 get('/session/:sessionId/title')).
    260 put(webdriver.CommandName.EXECUTE_SCRIPT,
    261 post('/session/:sessionId/execute')).
    262 put(webdriver.CommandName.EXECUTE_ASYNC_SCRIPT,
    263 post('/session/:sessionId/execute_async')).
    264 put(webdriver.CommandName.SCREENSHOT,
    265 get('/session/:sessionId/screenshot')).
    266 put(webdriver.CommandName.SET_TIMEOUT,
    267 post('/session/:sessionId/timeouts')).
    268 put(webdriver.CommandName.SET_SCRIPT_TIMEOUT,
    269 post('/session/:sessionId/timeouts/async_script')).
    270 put(webdriver.CommandName.IMPLICITLY_WAIT,
    271 post('/session/:sessionId/timeouts/implicit_wait')).
    272 put(webdriver.CommandName.MOVE_TO, post('/session/:sessionId/moveto')).
    273 put(webdriver.CommandName.CLICK, post('/session/:sessionId/click')).
    274 put(webdriver.CommandName.DOUBLE_CLICK,
    275 post('/session/:sessionId/doubleclick')).
    276 put(webdriver.CommandName.MOUSE_DOWN,
    277 post('/session/:sessionId/buttondown')).
    278 put(webdriver.CommandName.MOUSE_UP, post('/session/:sessionId/buttonup')).
    279 put(webdriver.CommandName.MOVE_TO, post('/session/:sessionId/moveto')).
    280 put(webdriver.CommandName.SEND_KEYS_TO_ACTIVE_ELEMENT,
    281 post('/session/:sessionId/keys')).
    282 put(webdriver.CommandName.ACCEPT_ALERT,
    283 post('/session/:sessionId/accept_alert')).
    284 put(webdriver.CommandName.DISMISS_ALERT,
    285 post('/session/:sessionId/dismiss_alert')).
    286 put(webdriver.CommandName.GET_ALERT_TEXT,
    287 get('/session/:sessionId/alert_text')).
    288 put(webdriver.CommandName.SET_ALERT_TEXT,
    289 post('/session/:sessionId/alert_text')).
    290 put(webdriver.CommandName.GET_LOG, post('/session/:sessionId/log')).
    291 put(webdriver.CommandName.GET_AVAILABLE_LOG_TYPES,
    292 get('/session/:sessionId/log/types')).
    293 put(webdriver.CommandName.GET_SESSION_LOGS, post('/logs')).
    294 build();
    295
    296 /** @constructor */
    297 function Builder() {
    298 var map = {};
    299
    300 this.put = function(name, resource) {
    301 map[name] = resource;
    302 return this;
    303 };
    304
    305 this.build = function() {
    306 return map;
    307 };
    308 }
    309
    310 function post(path) { return resource('POST', path); }
    311 function del(path) { return resource('DELETE', path); }
    312 function get(path) { return resource('GET', path); }
    313 function resource(method, path) { return {method: method, path: path}; }
    314})();
    315
    316
    317/**
    318 * Converts a headers object to a HTTP header block string.
    319 * @param {!Object.<string>} headers The headers object to convert.
    320 * @return {string} The headers as a string.
    321 * @private
    322 */
    323webdriver.http.headersToString_ = function(headers) {
    324 var ret = [];
    325 for (var key in headers) {
    326 ret.push(key + ': ' + headers[key]);
    327 }
    328 return ret.join('\n');
    329};
    330
    331
    332
    333/**
    334 * Describes a partial HTTP request. This class is a "partial" request and only
    335 * defines the path on the server to send a request to. It is each
    336 * {@code webdriver.http.Client}'s responsibility to build the full URL for the
    337 * final request.
    338 * @param {string} method The HTTP method to use for the request.
    339 * @param {string} path Path on the server to send the request to.
    340 * @param {Object=} opt_data This request's JSON data.
    341 * @constructor
    342 */
    343webdriver.http.Request = function(method, path, opt_data) {
    344
    345 /**
    346 * The HTTP method to use for the request.
    347 * @type {string}
    348 */
    349 this.method = method;
    350
    351 /**
    352 * The path on the server to send the request to.
    353 * @type {string}
    354 */
    355 this.path = path;
    356
    357 /**
    358 * This request's body.
    359 * @type {!Object}
    360 */
    361 this.data = opt_data || {};
    362
    363 /**
    364 * The headers to send with the request.
    365 * @type {!Object.<(string|number)>}
    366 */
    367 this.headers = {'Accept': 'application/json; charset=utf-8'};
    368};
    369
    370
    371/** @override */
    372webdriver.http.Request.prototype.toString = function() {
    373 return [
    374 this.method + ' ' + this.path + ' HTTP/1.1',
    375 webdriver.http.headersToString_(this.headers),
    376 '',
    377 goog.json.serialize(this.data)
    378 ].join('\n');
    379};
    380
    381
    382
    383/**
    384 * Represents a HTTP response.
    385 * @param {number} status The response code.
    386 * @param {!Object.<string>} headers The response headers. All header
    387 * names will be converted to lowercase strings for consistent lookups.
    388 * @param {string} body The response body.
    389 * @constructor
    390 */
    391webdriver.http.Response = function(status, headers, body) {
    392
    393 /**
    394 * The HTTP response code.
    395 * @type {number}
    396 */
    397 this.status = status;
    398
    399 /**
    400 * The response body.
    401 * @type {string}
    402 */
    403 this.body = body;
    404
    405 /**
    406 * The response body.
    407 * @type {!Object.<string>}
    408 */
    409 this.headers = {};
    410 for (var header in headers) {
    411 this.headers[header.toLowerCase()] = headers[header];
    412 }
    413};
    414
    415
    416/**
    417 * Builds a {@code webdriver.http.Response} from a {@code XMLHttpRequest} or
    418 * {@code XDomainRequest} response object.
    419 * @param {!(XDomainRequest|XMLHttpRequest)} xhr The request to parse.
    420 * @return {!webdriver.http.Response} The parsed response.
    421 */
    422webdriver.http.Response.fromXmlHttpRequest = function(xhr) {
    423 var headers = {};
    424
    425 // getAllResponseHeaders is only available on XMLHttpRequest objects.
    426 if (xhr.getAllResponseHeaders) {
    427 var tmp = xhr.getAllResponseHeaders();
    428 if (tmp) {
    429 tmp = tmp.replace(/\r\n/g, '\n').split('\n');
    430 goog.array.forEach(tmp, function(header) {
    431 var parts = header.split(/\s*:\s*/, 2);
    432 if (parts[0]) {
    433 headers[parts[0]] = parts[1] || '';
    434 }
    435 });
    436 }
    437 }
    438
    439 // If xhr is a XDomainRequest object, it will not have a status.
    440 // However, if we're parsing the response from a XDomainRequest, then
    441 // that request must have been a success, so we can assume status == 200.
    442 var status = xhr.status || 200;
    443 return new webdriver.http.Response(status, headers,
    444 xhr.responseText.replace(/\0/g, ''));
    445};
    446
    447
    448/** @override */
    449webdriver.http.Response.prototype.toString = function() {
    450 var headers = webdriver.http.headersToString_(this.headers);
    451 var ret = ['HTTP/1.1 ' + this.status, headers];
    452
    453 if (headers) {
    454 ret.push('');
    455 }
    456
    457 if (this.body) {
    458 ret.push(this.body);
    459 }
    460
    461 return ret.join('\n');
    462};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/http/xhrclient.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/http/xhrclient.js.src.html new file mode 100644 index 0000000..d810afe --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/http/xhrclient.js.src.html @@ -0,0 +1 @@ +xhrclient.js

    lib/webdriver/http/xhrclient.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/** @fileoverview A XHR client. */
    16
    17goog.provide('webdriver.http.XhrClient');
    18
    19goog.require('goog.json');
    20goog.require('goog.net.XmlHttp');
    21goog.require('webdriver.http.Response');
    22
    23
    24
    25/**
    26 * A HTTP client that sends requests using XMLHttpRequests.
    27 * @param {string} url URL for the WebDriver server to send commands to.
    28 * @constructor
    29 * @implements {webdriver.http.Client}
    30 */
    31webdriver.http.XhrClient = function(url) {
    32
    33 /** @private {string} */
    34 this.url_ = url;
    35};
    36
    37
    38/** @override */
    39webdriver.http.XhrClient.prototype.send = function(request, callback) {
    40 try {
    41 var xhr = /** @type {!XMLHttpRequest} */ (goog.net.XmlHttp());
    42 var url = this.url_ + request.path;
    43 xhr.open(request.method, url, true);
    44
    45 xhr.onload = function() {
    46 callback(null, webdriver.http.Response.fromXmlHttpRequest(xhr));
    47 };
    48
    49 xhr.onerror = function() {
    50 callback(Error([
    51 'Unable to send request: ', request.method, ' ', url,
    52 '\nOriginal request:\n', request
    53 ].join('')));
    54 };
    55
    56 for (var header in request.headers) {
    57 xhr.setRequestHeader(header, request.headers[header] + '');
    58 }
    59
    60 xhr.send(goog.json.serialize(request.data));
    61 } catch (ex) {
    62 callback(ex);
    63 }
    64};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/key.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/key.js.src.html new file mode 100644 index 0000000..4cb50ac --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/key.js.src.html @@ -0,0 +1 @@ +key.js

    lib/webdriver/key.js

    1// Copyright 2012 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15goog.provide('webdriver.Key');
    16
    17
    18/**
    19 * Representations of pressable keys that aren't text. These are stored in
    20 * the Unicode PUA (Private Use Area) code points, 0xE000-0xF8FF. Refer to
    21 * http://www.google.com.au/search?&q=unicode+pua&btnG=Search
    22 *
    23 * @enum {string}
    24 */
    25webdriver.Key = {
    26 NULL: '\uE000',
    27 CANCEL: '\uE001', // ^break
    28 HELP: '\uE002',
    29 BACK_SPACE: '\uE003',
    30 TAB: '\uE004',
    31 CLEAR: '\uE005',
    32 RETURN: '\uE006',
    33 ENTER: '\uE007',
    34 SHIFT: '\uE008',
    35 CONTROL: '\uE009',
    36 ALT: '\uE00A',
    37 PAUSE: '\uE00B',
    38 ESCAPE: '\uE00C',
    39 SPACE: '\uE00D',
    40 PAGE_UP: '\uE00E',
    41 PAGE_DOWN: '\uE00F',
    42 END: '\uE010',
    43 HOME: '\uE011',
    44 ARROW_LEFT: '\uE012',
    45 LEFT: '\uE012',
    46 ARROW_UP: '\uE013',
    47 UP: '\uE013',
    48 ARROW_RIGHT: '\uE014',
    49 RIGHT: '\uE014',
    50 ARROW_DOWN: '\uE015',
    51 DOWN: '\uE015',
    52 INSERT: '\uE016',
    53 DELETE: '\uE017',
    54 SEMICOLON: '\uE018',
    55 EQUALS: '\uE019',
    56
    57 NUMPAD0: '\uE01A', // number pad keys
    58 NUMPAD1: '\uE01B',
    59 NUMPAD2: '\uE01C',
    60 NUMPAD3: '\uE01D',
    61 NUMPAD4: '\uE01E',
    62 NUMPAD5: '\uE01F',
    63 NUMPAD6: '\uE020',
    64 NUMPAD7: '\uE021',
    65 NUMPAD8: '\uE022',
    66 NUMPAD9: '\uE023',
    67 MULTIPLY: '\uE024',
    68 ADD: '\uE025',
    69 SEPARATOR: '\uE026',
    70 SUBTRACT: '\uE027',
    71 DECIMAL: '\uE028',
    72 DIVIDE: '\uE029',
    73
    74 F1: '\uE031', // function keys
    75 F2: '\uE032',
    76 F3: '\uE033',
    77 F4: '\uE034',
    78 F5: '\uE035',
    79 F6: '\uE036',
    80 F7: '\uE037',
    81 F8: '\uE038',
    82 F9: '\uE039',
    83 F10: '\uE03A',
    84 F11: '\uE03B',
    85 F12: '\uE03C',
    86
    87 COMMAND: '\uE03D', // Apple command key
    88 META: '\uE03D' // alias for Windows key
    89};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/locators.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/locators.js.src.html new file mode 100644 index 0000000..6587c12 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/locators.js.src.html @@ -0,0 +1 @@ +locators.js

    lib/webdriver/locators.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Factory methods for the supported locator strategies.
    17 */
    18
    19goog.provide('webdriver.By');
    20goog.provide('webdriver.Locator');
    21goog.provide('webdriver.Locator.Strategy');
    22
    23goog.require('goog.array');
    24goog.require('goog.object');
    25goog.require('goog.string');
    26
    27
    28
    29/**
    30 * An element locator.
    31 * @param {string} using The type of strategy to use for this locator.
    32 * @param {string} value The search target of this locator.
    33 * @constructor
    34 */
    35webdriver.Locator = function(using, value) {
    36
    37 /**
    38 * The search strategy to use when searching for an element.
    39 * @type {string}
    40 */
    41 this.using = using;
    42
    43 /**
    44 * The search target for this locator.
    45 * @type {string}
    46 */
    47 this.value = value;
    48};
    49
    50
    51/**
    52 * Creates a factory function for a {@link webdriver.Locator}.
    53 * @param {string} type The type of locator for the factory.
    54 * @return {function(string): !webdriver.Locator} The new factory function.
    55 * @private
    56 */
    57webdriver.Locator.factory_ = function(type) {
    58 return function(value) {
    59 return new webdriver.Locator(type, value);
    60 };
    61};
    62
    63
    64/**
    65 * A collection of factory functions for creating {@link webdriver.Locator}
    66 * instances.
    67 */
    68webdriver.By = {};
    69// Exported to the global scope for legacy reasons.
    70goog.exportSymbol('By', webdriver.By);
    71
    72
    73/**
    74 * Short-hand expressions for the primary element locator strategies.
    75 * For example the following two statements are equivalent:
    76 * <code><pre>
    77 * var e1 = driver.findElement(webdriver.By.id('foo'));
    78 * var e2 = driver.findElement({id: 'foo'});
    79 * </pre></code>
    80 *
    81 * <p>Care should be taken when using JavaScript minifiers (such as the
    82 * Closure compiler), as locator hashes will always be parsed using
    83 * the un-obfuscated properties listed below.
    84 *
    85 * @typedef {(
    86 * {className: string}|
    87 * {css: string}|
    88 * {id: string}|
    89 * {js: string}|
    90 * {linkText: string}|
    91 * {name: string}|
    92 * {partialLinkText: string}|
    93 * {tagName: string}|
    94 * {xpath: string})}
    95 */
    96webdriver.By.Hash;
    97
    98
    99/**
    100 * Locates elements that have a specific class name. The returned locator
    101 * is equivalent to searching for elements with the CSS selector ".clazz".
    102 *
    103 * @param {string} className The class name to search for.
    104 * @return {!webdriver.Locator} The new locator.
    105 * @see http://www.w3.org/TR/2011/WD-html5-20110525/elements.html#classes
    106 * @see http://www.w3.org/TR/CSS2/selector.html#class-html
    107 */
    108webdriver.By.className = webdriver.Locator.factory_('class name');
    109
    110
    111/**
    112 * Locates elements using a CSS selector. For browsers that do not support
    113 * CSS selectors, WebDriver implementations may return an
    114 * {@link bot.Error.State.INVALID_SELECTOR invalid selector} error. An
    115 * implementation may, however, emulate the CSS selector API.
    116 *
    117 * @param {string} selector The CSS selector to use.
    118 * @return {!webdriver.Locator} The new locator.
    119 * @see http://www.w3.org/TR/CSS2/selector.html
    120 */
    121webdriver.By.css = webdriver.Locator.factory_('css selector');
    122
    123
    124/**
    125 * Locates an element by its ID.
    126 *
    127 * @param {string} id The ID to search for.
    128 * @return {!webdriver.Locator} The new locator.
    129 */
    130webdriver.By.id = webdriver.Locator.factory_('id');
    131
    132
    133/**
    134 * Locates link elements whose {@link webdriver.WebElement#getText visible
    135 * text} matches the given string.
    136 *
    137 * @param {string} text The link text to search for.
    138 * @return {!webdriver.Locator} The new locator.
    139 */
    140webdriver.By.linkText = webdriver.Locator.factory_('link text');
    141
    142
    143/**
    144 * Locates an elements by evaluating a
    145 * {@link webdriver.WebDriver#executeScript JavaScript expression}.
    146 * The result of this expression must be an element or list of elements.
    147 *
    148 * @param {!(string|Function)} script The script to execute.
    149 * @param {...*} var_args The arguments to pass to the script.
    150 * @return {function(!webdriver.WebDriver): !webdriver.promise.Promise} A new,
    151 * JavaScript-based locator function.
    152 */
    153webdriver.By.js = function(script, var_args) {
    154 var args = goog.array.slice(arguments, 0);
    155 return function(driver) {
    156 return driver.executeScript.apply(driver, args);
    157 };
    158};
    159
    160
    161/**
    162 * Locates elements whose {@code name} attribute has the given value.
    163 *
    164 * @param {string} name The name attribute to search for.
    165 * @return {!webdriver.Locator} The new locator.
    166 */
    167webdriver.By.name = webdriver.Locator.factory_('name');
    168
    169
    170/**
    171 * Locates link elements whose {@link webdriver.WebElement#getText visible
    172 * text} contains the given substring.
    173 *
    174 * @param {string} text The substring to check for in a link's visible text.
    175 * @return {!webdriver.Locator} The new locator.
    176 */
    177webdriver.By.partialLinkText = webdriver.Locator.factory_(
    178 'partial link text');
    179
    180
    181/**
    182 * Locates elements with a given tag name. The returned locator is
    183 * equivalent to using the {@code getElementsByTagName} DOM function.
    184 *
    185 * @param {string} text The substring to check for in a link's visible text.
    186 * @return {!webdriver.Locator} The new locator.
    187 * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html
    188 */
    189webdriver.By.tagName = webdriver.Locator.factory_('tag name');
    190
    191
    192/**
    193 * Locates elements matching a XPath selector. Care should be taken when
    194 * using an XPath selector with a {@link webdriver.WebElement} as WebDriver
    195 * will respect the context in the specified in the selector. For example,
    196 * given the selector {@code "//div"}, WebDriver will search from the
    197 * document root regardless of whether the locator was used with a
    198 * WebElement.
    199 *
    200 * @param {string} xpath The XPath selector to use.
    201 * @return {!webdriver.Locator} The new locator.
    202 * @see http://www.w3.org/TR/xpath/
    203 */
    204webdriver.By.xpath = webdriver.Locator.factory_('xpath');
    205
    206
    207/**
    208 * Maps {@link webdriver.By.Hash} keys to the appropriate factory function.
    209 * @type {!Object.<string, function(string): !(Function|webdriver.Locator)>}
    210 * @const
    211 */
    212webdriver.Locator.Strategy = {
    213 'className': webdriver.By.className,
    214 'css': webdriver.By.css,
    215 'id': webdriver.By.id,
    216 'js': webdriver.By.js,
    217 'linkText': webdriver.By.linkText,
    218 'name': webdriver.By.name,
    219 'partialLinkText': webdriver.By.partialLinkText,
    220 'tagName': webdriver.By.tagName,
    221 'xpath': webdriver.By.xpath
    222};
    223
    224
    225/**
    226 * Verifies that a {@code value} is a valid locator to use for searching for
    227 * elements on the page.
    228 *
    229 * @param {*} value The value to check is a valid locator.
    230 * @return {!(webdriver.Locator|Function)} A valid locator object or function.
    231 * @throws {TypeError} If the given value is an invalid locator.
    232 */
    233webdriver.Locator.checkLocator = function(value) {
    234 if (goog.isFunction(value) || value instanceof webdriver.Locator) {
    235 return value;
    236 }
    237 for (var key in value) {
    238 if (value.hasOwnProperty(key) &&
    239 webdriver.Locator.Strategy.hasOwnProperty(key)) {
    240 return webdriver.Locator.Strategy[key](value[key]);
    241 }
    242 }
    243 throw new TypeError('Invalid locator');
    244};
    245
    246
    247
    248/** @override */
    249webdriver.Locator.prototype.toString = function() {
    250 return 'By.' + this.using.replace(/ ([a-z])/g, function(all, match) {
    251 return match.toUpperCase();
    252 }) + '(' + goog.string.quote(this.value) + ')';
    253};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/logging.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/logging.js.src.html new file mode 100644 index 0000000..b9153c0 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/logging.js.src.html @@ -0,0 +1 @@ +logging.js

    lib/webdriver/logging.js

    1// Copyright 2013 Selenium comitters
    2// Copyright 2013 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16goog.provide('webdriver.logging');
    17goog.provide('webdriver.logging.Preferences');
    18
    19goog.require('goog.object');
    20
    21
    22/**
    23 * Log level names from WebDriver's JSON wire protocol.
    24 * @enum {string}
    25 */
    26webdriver.logging.LevelName = {
    27 ALL: 'ALL',
    28 DEBUG: 'DEBUG',
    29 INFO: 'INFO',
    30 WARNING: 'WARNING',
    31 SEVERE: 'SEVERE',
    32 OFF: 'OFF'
    33};
    34
    35
    36/**
    37 * Logging levels.
    38 * @enum {{value: number, name: webdriver.logging.LevelName}}
    39 */
    40webdriver.logging.Level = {
    41 ALL: {value: Number.MIN_VALUE, name: webdriver.logging.LevelName.ALL},
    42 DEBUG: {value: 700, name: webdriver.logging.LevelName.DEBUG},
    43 INFO: {value: 800, name: webdriver.logging.LevelName.INFO},
    44 WARNING: {value: 900, name: webdriver.logging.LevelName.WARNING},
    45 SEVERE: {value: 1000, name: webdriver.logging.LevelName.SEVERE},
    46 OFF: {value: Number.MAX_VALUE, name: webdriver.logging.LevelName.OFF}
    47};
    48
    49
    50/**
    51 * Converts a level name or value to a {@link webdriver.logging.Level} value.
    52 * If the name/value is not recognized, {@link webdriver.logging.Level.ALL}
    53 * will be returned.
    54 * @param {(number|string)} nameOrValue The log level name, or value, to
    55 * convert .
    56 * @return {!webdriver.logging.Level} The converted level.
    57 */
    58webdriver.logging.getLevel = function(nameOrValue) {
    59 var predicate = goog.isString(nameOrValue) ?
    60 function(val) { return val.name === nameOrValue; } :
    61 function(val) { return val.value === nameOrValue; };
    62
    63 return goog.object.findValue(webdriver.logging.Level, predicate) ||
    64 webdriver.logging.Level.ALL;
    65};
    66
    67
    68/**
    69 * Common log types.
    70 * @enum {string}
    71 */
    72webdriver.logging.Type = {
    73 /** Logs originating from the browser. */
    74 BROWSER: 'browser',
    75 /** Logs from a WebDriver client. */
    76 CLIENT: 'client',
    77 /** Logs from a WebDriver implementation. */
    78 DRIVER: 'driver',
    79 /** Logs related to performance. */
    80 PERFORMANCE: 'performance',
    81 /** Logs from the remote server. */
    82 SERVER: 'server'
    83};
    84
    85
    86/**
    87 * A hash describing log preferences.
    88 * @typedef {Object.<webdriver.logging.Type, webdriver.logging.LevelName>}
    89 */
    90webdriver.logging.Preferences;
    91
    92
    93/**
    94 * A single log entry.
    95 * @param {(!webdriver.logging.Level|string)} level The entry level.
    96 * @param {string} message The log message.
    97 * @param {number=} opt_timestamp The time this entry was generated, in
    98 * milliseconds since 0:00:00, January 1, 1970 UTC. If omitted, the
    99 * current time will be used.
    100 * @param {string=} opt_type The log type, if known.
    101 * @constructor
    102 */
    103webdriver.logging.Entry = function(level, message, opt_timestamp, opt_type) {
    104
    105 /** @type {!webdriver.logging.Level} */
    106 this.level =
    107 goog.isString(level) ? webdriver.logging.getLevel(level) : level;
    108
    109 /** @type {string} */
    110 this.message = message;
    111
    112 /** @type {number} */
    113 this.timestamp = goog.isNumber(opt_timestamp) ? opt_timestamp : goog.now();
    114
    115 /** @type {string} */
    116 this.type = opt_type || '';
    117};
    118
    119
    120/**
    121 * @return {{level: string, message: string, timestamp: number,
    122 * type: string}} The JSON representation of this entry.
    123 */
    124webdriver.logging.Entry.prototype.toJSON = function() {
    125 return {
    126 'level': this.level.name,
    127 'message': this.message,
    128 'timestamp': this.timestamp,
    129 'type': this.type
    130 };
    131};
    132
    133
    134/**
    135 * Converts a {@link goog.debug.LogRecord} into a
    136 * {@link webdriver.logging.Entry}.
    137 * @param {!goog.debug.LogRecord} logRecord The record to convert.
    138 * @param {string=} opt_type The log type.
    139 * @return {!webdriver.logging.Entry} The converted entry.
    140 */
    141webdriver.logging.Entry.fromClosureLogRecord = function(logRecord, opt_type) {
    142 var closureLevel = logRecord.getLevel();
    143 var level = webdriver.logging.Level.SEVERE;
    144
    145 if (closureLevel.value <= webdriver.logging.Level.DEBUG.value) {
    146 level = webdriver.logging.Level.DEBUG;
    147 } else if (closureLevel.value <= webdriver.logging.Level.INFO.value) {
    148 level = webdriver.logging.Level.INFO;
    149 } else if (closureLevel.value <= webdriver.logging.Level.WARNING.value) {
    150 level = webdriver.logging.Level.WARNING;
    151 }
    152
    153 return new webdriver.logging.Entry(
    154 level,
    155 '[' + logRecord.getLoggerName() + '] ' + logRecord.getMessage(),
    156 logRecord.getMillis(),
    157 opt_type);
    158};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/process.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/process.js.src.html new file mode 100644 index 0000000..e0d858c --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/process.js.src.html @@ -0,0 +1 @@ +process.js

    lib/webdriver/process.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Provides access to the current process' environment variables.
    17 * When running in node, this is simply a wrapper for {@code process.env}.
    18 * When running in a browser, environment variables are loaded by parsing the
    19 * current URL's query string. Variables that have more than one variable will
    20 * be initialized to the JSON representation of the array of all values,
    21 * otherwise the variable will be initialized to a sole string value. If a
    22 * variable does not have any values, but is nonetheless present in the query
    23 * string, it will be initialized to an empty string.
    24 * After the initial parsing, environment variables must be queried and set
    25 * through the API defined in this file.
    26 */
    27
    28goog.provide('webdriver.process');
    29
    30goog.require('goog.Uri');
    31goog.require('goog.array');
    32goog.require('goog.json');
    33
    34
    35/**
    36 * @return {boolean} Whether the current process is Node's native process
    37 * object.
    38 */
    39webdriver.process.isNative = function() {
    40 return webdriver.process.IS_NATIVE_PROCESS_;
    41};
    42
    43
    44/**
    45 * Queries for a named environment variable.
    46 * @param {string} name The name of the environment variable to look up.
    47 * @param {string=} opt_default The default value if the named variable is not
    48 * defined.
    49 * @return {string} The queried environment variable.
    50 */
    51webdriver.process.getEnv = function(name, opt_default) {
    52 var value = webdriver.process.PROCESS_.env[name];
    53 return goog.isDefAndNotNull(value) ? value : opt_default;
    54};
    55
    56
    57/**
    58 * Sets an environment value. If the new value is either null or undefined, the
    59 * environment variable will be cleared.
    60 * @param {string} name The value to set.
    61 * @param {*} value The new value; will be coerced to a string.
    62 */
    63webdriver.process.setEnv = function(name, value) {
    64 webdriver.process.PROCESS_.env[name] =
    65 goog.isDefAndNotNull(value) ? value + '' : null;
    66};
    67
    68
    69/**
    70 * Whether the current environment is using Node's native process object.
    71 * @private {boolean}
    72 * @const
    73 */
    74webdriver.process.IS_NATIVE_PROCESS_ = typeof process !== 'undefined';
    75
    76
    77/**
    78 * Initializes a process object for use in a browser window.
    79 * @param {!Window=} opt_window The window object to initialize the process
    80 * from; if not specified, will default to the current window. Should only
    81 * be set for unit testing.
    82 * @return {!Object} The new process object.
    83 * @private
    84 */
    85webdriver.process.initBrowserProcess_ = function(opt_window) {
    86 var process = {'env': {}};
    87
    88 var win = opt_window;
    89 if (!win && typeof window != 'undefined') {
    90 win = window;
    91 }
    92
    93 // Initialize the global error handler.
    94 if (win) {
    95 // Initialize the environment variable map by parsing the current URL query
    96 // string.
    97 if (win.location) {
    98 var data = new goog.Uri(win.location).getQueryData();
    99 goog.array.forEach(data.getKeys(), function(key) {
    100 var values = data.getValues(key);
    101 process.env[key] = values.length == 0 ? '' :
    102 values.length == 1 ? values[0] :
    103 goog.json.serialize(values);
    104 });
    105 }
    106 }
    107
    108 return process;
    109};
    110
    111
    112/**
    113 * The global process object to use. Will either be Node's global
    114 * {@code process} object, or an approximation of it for use in a browser
    115 * environment.
    116 * @private {!Object}
    117 * @const
    118 */
    119webdriver.process.PROCESS_ = webdriver.process.IS_NATIVE_PROCESS_ ? process :
    120 webdriver.process.initBrowserProcess_();
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/promise.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/promise.js.src.html new file mode 100644 index 0000000..753654d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/promise.js.src.html @@ -0,0 +1 @@ +promise.js

    lib/webdriver/promise.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @license Portions of this code are from the Dojo toolkit, received under the
    17 * BSD License:
    18 * Redistribution and use in source and binary forms, with or without
    19 * modification, are permitted provided that the following conditions are met:
    20 *
    21 * * Redistributions of source code must retain the above copyright notice,
    22 * this list of conditions and the following disclaimer.
    23 * * Redistributions in binary form must reproduce the above copyright notice,
    24 * this list of conditions and the following disclaimer in the documentation
    25 * and/or other materials provided with the distribution.
    26 * * Neither the name of the Dojo Foundation nor the names of its contributors
    27 * may be used to endorse or promote products derived from this software
    28 * without specific prior written permission.
    29 *
    30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    31 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    34 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    38 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    40 * POSSIBILITY OF SUCH DAMAGE.
    41 */
    42
    43/**
    44 * @fileoverview A promise implementation based on the CommonJS promise/A and
    45 * promise/B proposals. For more information, see
    46 * http://wiki.commonjs.org/wiki/Promises.
    47 */
    48
    49goog.provide('webdriver.promise');
    50goog.provide('webdriver.promise.ControlFlow');
    51goog.provide('webdriver.promise.ControlFlow.Timer');
    52goog.provide('webdriver.promise.Deferred');
    53goog.provide('webdriver.promise.Promise');
    54
    55goog.require('goog.array');
    56goog.require('goog.debug.Error');
    57goog.require('goog.object');
    58goog.require('webdriver.EventEmitter');
    59goog.require('webdriver.stacktrace.Snapshot');
    60
    61
    62
    63/**
    64 * Represents the eventual value of a completed operation. Each promise may be
    65 * in one of three states: pending, resolved, or rejected. Each promise starts
    66 * in the pending state and may make a single transition to either a
    67 * fulfilled or failed state.
    68 *
    69 * <p/>This class is based on the Promise/A proposal from CommonJS. Additional
    70 * functions are provided for API compatibility with Dojo Deferred objects.
    71 *
    72 * @constructor
    73 * @template T
    74 * @see http://wiki.commonjs.org/wiki/Promises/A
    75 */
    76webdriver.promise.Promise = function() {
    77};
    78
    79
    80/**
    81 * Cancels the computation of this promise's value, rejecting the promise in the
    82 * process.
    83 * @param {*} reason The reason this promise is being cancelled. If not an
    84 * {@code Error}, one will be created using the value's string
    85 * representation.
    86 */
    87webdriver.promise.Promise.prototype.cancel = function(reason) {
    88 throw new TypeError('Unimplemented function: "cancel"');
    89};
    90
    91
    92/** @return {boolean} Whether this promise's value is still being computed. */
    93webdriver.promise.Promise.prototype.isPending = function() {
    94 throw new TypeError('Unimplemented function: "isPending"');
    95};
    96
    97
    98/**
    99 * Registers listeners for when this instance is resolved. This function most
    100 * overridden by subtypes.
    101 *
    102 * @param {?(function(T): (R|webdriver.promise.Promise.<R>))=} opt_callback The
    103 * function to call if this promise is successfully resolved. The function
    104 * should expect a single argument: the promise's resolved value.
    105 * @param {?(function(*): (R|webdriver.promise.Promise.<R>))=} opt_errback The
    106 * function to call if this promise is rejected. The function should expect
    107 * a single argument: the rejection reason.
    108 * @return {!webdriver.promise.Promise.<R>} A new promise which will be
    109 * resolved with the result of the invoked callback.
    110 * @template R
    111 */
    112webdriver.promise.Promise.prototype.then = function(
    113 opt_callback, opt_errback) {
    114 throw new TypeError('Unimplemented function: "then"');
    115};
    116
    117
    118/**
    119 * Registers a listener for when this promise is rejected. This is synonymous
    120 * with the {@code catch} clause in a synchronous API:
    121 * <pre><code>
    122 * // Synchronous API:
    123 * try {
    124 * doSynchronousWork();
    125 * } catch (ex) {
    126 * console.error(ex);
    127 * }
    128 *
    129 * // Asynchronous promise API:
    130 * doAsynchronousWork().thenCatch(function(ex) {
    131 * console.error(ex);
    132 * });
    133 * </code></pre>
    134 *
    135 * @param {function(*): (R|webdriver.promise.Promise.<R>)} errback The function
    136 * to call if this promise is rejected. The function should expect a single
    137 * argument: the rejection reason.
    138 * @return {!webdriver.promise.Promise.<R>} A new promise which will be
    139 * resolved with the result of the invoked callback.
    140 * @template R
    141 */
    142webdriver.promise.Promise.prototype.thenCatch = function(errback) {
    143 return this.then(null, errback);
    144};
    145
    146
    147/**
    148 * Registers a listener to invoke when this promise is resolved, regardless
    149 * of whether the promise's value was successfully computed. This function
    150 * is synonymous with the {@code finally} clause in a synchronous API:
    151 * <pre><code>
    152 * // Synchronous API:
    153 * try {
    154 * doSynchronousWork();
    155 * } finally {
    156 * cleanUp();
    157 * }
    158 *
    159 * // Asynchronous promise API:
    160 * doAsynchronousWork().thenFinally(cleanUp);
    161 * </code></pre>
    162 *
    163 * <b>Note:</b> similar to the {@code finally} clause, if the registered
    164 * callback returns a rejected promise or throws an error, it will silently
    165 * replace the rejection error (if any) from this promise:
    166 * <pre><code>
    167 * try {
    168 * throw Error('one');
    169 * } finally {
    170 * throw Error('two'); // Hides Error: one
    171 * }
    172 *
    173 * webdriver.promise.rejected(Error('one'))
    174 * .thenFinally(function() {
    175 * throw Error('two'); // Hides Error: one
    176 * });
    177 * </code></pre>
    178 *
    179 *
    180 * @param {function(): (R|webdriver.promise.Promise.<R>)} callback The function
    181 * to call when this promise is resolved.
    182 * @return {!webdriver.promise.Promise.<R>} A promise that will be fulfilled
    183 * with the callback result.
    184 * @template R
    185 */
    186webdriver.promise.Promise.prototype.thenFinally = function(callback) {
    187 return this.then(callback, function(err) {
    188 var value = callback();
    189 if (webdriver.promise.isPromise(value)) {
    190 return value.then(function() {
    191 throw err;
    192 });
    193 }
    194 throw err;
    195 });
    196};
    197
    198
    199
    200/**
    201 * Represents a value that will be resolved at some point in the future. This
    202 * class represents the protected "producer" half of a Promise - each Deferred
    203 * has a {@code promise} property that may be returned to consumers for
    204 * registering callbacks, reserving the ability to resolve the deferred to the
    205 * producer.
    206 *
    207 * <p>If this Deferred is rejected and there are no listeners registered before
    208 * the next turn of the event loop, the rejection will be passed to the
    209 * {@link webdriver.promise.ControlFlow} as an unhandled failure.
    210 *
    211 * <p>If this Deferred is cancelled, the cancellation reason will be forward to
    212 * the Deferred's canceller function (if provided). The canceller may return a
    213 * truth-y value to override the reason provided for rejection.
    214 *
    215 * @param {Function=} opt_canceller Function to call when cancelling the
    216 * computation of this instance's value.
    217 * @param {webdriver.promise.ControlFlow=} opt_flow The control flow
    218 * this instance was created under. This should only be provided during
    219 * unit tests.
    220 * @constructor
    221 * @extends {webdriver.promise.Promise.<T>}
    222 * @template T
    223 */
    224webdriver.promise.Deferred = function(opt_canceller, opt_flow) {
    225 /* NOTE: This class's implementation diverges from the prototypical style
    226 * used in the rest of the atoms library. This was done intentionally to
    227 * protect the internal Deferred state from consumers, as outlined by
    228 * http://wiki.commonjs.org/wiki/Promises
    229 */
    230 goog.base(this);
    231
    232 var flow = opt_flow || webdriver.promise.controlFlow();
    233
    234 /**
    235 * The listeners registered with this Deferred. Each element in the list will
    236 * be a 3-tuple of the callback function, errback function, and the
    237 * corresponding deferred object.
    238 * @type {!Array.<!webdriver.promise.Deferred.Listener_>}
    239 */
    240 var listeners = [];
    241
    242 /**
    243 * Whether this Deferred's resolution was ever handled by a listener.
    244 * If the Deferred is rejected and its value is not handled by a listener
    245 * before the next turn of the event loop, the error will be passed to the
    246 * global error handler.
    247 * @type {boolean}
    248 */
    249 var handled = false;
    250
    251 /**
    252 * Key for the timeout used to delay reproting an unhandled rejection to the
    253 * parent {@link webdriver.promise.ControlFlow}.
    254 * @type {?number}
    255 */
    256 var pendingRejectionKey = null;
    257
    258 /**
    259 * This Deferred's current state.
    260 * @type {!webdriver.promise.Deferred.State_}
    261 */
    262 var state = webdriver.promise.Deferred.State_.PENDING;
    263
    264 /**
    265 * This Deferred's resolved value; set when the state transitions from
    266 * {@code webdriver.promise.Deferred.State_.PENDING}.
    267 * @type {*}
    268 */
    269 var value;
    270
    271 /** @return {boolean} Whether this promise's value is still pending. */
    272 function isPending() {
    273 return state == webdriver.promise.Deferred.State_.PENDING;
    274 }
    275
    276 /**
    277 * Removes all of the listeners previously registered on this deferred.
    278 * @throws {Error} If this deferred has already been resolved.
    279 */
    280 function removeAll() {
    281 listeners = [];
    282 }
    283
    284 /**
    285 * Resolves this deferred. If the new value is a promise, this function will
    286 * wait for it to be resolved before notifying the registered listeners.
    287 * @param {!webdriver.promise.Deferred.State_} newState The deferred's new
    288 * state.
    289 * @param {*} newValue The deferred's new value.
    290 */
    291 function resolve(newState, newValue) {
    292 if (webdriver.promise.Deferred.State_.PENDING !== state) {
    293 return;
    294 }
    295
    296 state = webdriver.promise.Deferred.State_.BLOCKED;
    297
    298 if (webdriver.promise.isPromise(newValue) && newValue !== self) {
    299 var onFulfill = goog.partial(notifyAll, newState);
    300 var onReject = goog.partial(
    301 notifyAll, webdriver.promise.Deferred.State_.REJECTED);
    302 if (newValue instanceof webdriver.promise.Deferred) {
    303 newValue.then(onFulfill, onReject);
    304 } else {
    305 webdriver.promise.asap(newValue, onFulfill, onReject);
    306 }
    307
    308 } else {
    309 notifyAll(newState, newValue);
    310 }
    311 }
    312
    313 /**
    314 * Notifies all of the listeners registered with this Deferred that its state
    315 * has changed.
    316 * @param {!webdriver.promise.Deferred.State_} newState The deferred's new
    317 * state.
    318 * @param {*} newValue The deferred's new value.
    319 */
    320 function notifyAll(newState, newValue) {
    321 if (newState === webdriver.promise.Deferred.State_.REJECTED &&
    322 // We cannot check instanceof Error since the object may have been
    323 // created in a different JS context.
    324 goog.isObject(newValue) && goog.isString(newValue.message)) {
    325 newValue = flow.annotateError(/** @type {!Error} */(newValue));
    326 }
    327
    328 state = newState;
    329 value = newValue;
    330 while (listeners.length) {
    331 notify(listeners.shift());
    332 }
    333
    334 if (!handled && state == webdriver.promise.Deferred.State_.REJECTED) {
    335 pendingRejectionKey = propagateError(value);
    336 }
    337 }
    338
    339 /**
    340 * Propagates an unhandled rejection to the parent ControlFlow in a
    341 * future turn of the JavaScript event loop.
    342 * @param {*} error The error value to report.
    343 * @return {number} The key for the registered timeout.
    344 */
    345 function propagateError(error) {
    346 flow.pendingRejections_ += 1;
    347 return flow.timer.setTimeout(function() {
    348 flow.pendingRejections_ -= 1;
    349 flow.abortFrame_(error);
    350 }, 0);
    351 }
    352
    353 /**
    354 * Notifies a single listener of this Deferred's change in state.
    355 * @param {!webdriver.promise.Deferred.Listener_} listener The listener to
    356 * notify.
    357 */
    358 function notify(listener) {
    359 var func = state == webdriver.promise.Deferred.State_.RESOLVED ?
    360 listener.callback : listener.errback;
    361 if (func) {
    362 flow.runInNewFrame_(goog.partial(func, value),
    363 listener.fulfill, listener.reject);
    364 } else if (state == webdriver.promise.Deferred.State_.REJECTED) {
    365 listener.reject(value);
    366 } else {
    367 listener.fulfill(value);
    368 }
    369 }
    370
    371 /**
    372 * The consumer promise for this instance. Provides protected access to the
    373 * callback registering functions.
    374 * @type {!webdriver.promise.Promise.<T>}
    375 */
    376 var promise = new webdriver.promise.Promise();
    377
    378 /**
    379 * Registers a callback on this Deferred.
    380 *
    381 * @param {?(function(T): (R|webdriver.promise.Promise.<R>))=} opt_callback .
    382 * @param {?(function(*): (R|webdriver.promise.Promise.<R>))=} opt_errback .
    383 * @return {!webdriver.promise.Promise.<R>} A new promise representing the
    384 * result of the callback.
    385 * @template R
    386 * @see webdriver.promise.Promise#then
    387 */
    388 function then(opt_callback, opt_errback) {
    389 // Avoid unnecessary allocations if we weren't given any callback functions.
    390 if (!opt_callback && !opt_errback) {
    391 return promise;
    392 }
    393
    394 // The moment a listener is registered, we consider this deferred to be
    395 // handled; the callback must handle any rejection errors.
    396 handled = true;
    397 if (pendingRejectionKey) {
    398 flow.pendingRejections_ -= 1;
    399 flow.timer.clearTimeout(pendingRejectionKey);
    400 }
    401
    402 var deferred = new webdriver.promise.Deferred(cancel, flow);
    403 var listener = {
    404 callback: opt_callback,
    405 errback: opt_errback,
    406 fulfill: deferred.fulfill,
    407 reject: deferred.reject
    408 };
    409
    410 if (state == webdriver.promise.Deferred.State_.PENDING ||
    411 state == webdriver.promise.Deferred.State_.BLOCKED) {
    412 listeners.push(listener);
    413 } else {
    414 notify(listener);
    415 }
    416
    417 return deferred.promise;
    418 }
    419
    420 var self = this;
    421
    422 /**
    423 * Resolves this promise with the given value. If the value is itself a
    424 * promise and not a reference to this deferred, this instance will wait for
    425 * it before resolving.
    426 * @param {T=} opt_value The fulfilled value.
    427 */
    428 function fulfill(opt_value) {
    429 resolve(webdriver.promise.Deferred.State_.RESOLVED, opt_value);
    430 }
    431
    432 /**
    433 * Rejects this promise. If the error is itself a promise, this instance will
    434 * be chained to it and be rejected with the error's resolved value.
    435 * @param {*=} opt_error The rejection reason, typically either a
    436 * {@code Error} or a {@code string}.
    437 */
    438 function reject(opt_error) {
    439 resolve(webdriver.promise.Deferred.State_.REJECTED, opt_error);
    440 }
    441
    442 /**
    443 * Attempts to cancel the computation of this instance's value. This attempt
    444 * will silently fail if this instance has already resolved.
    445 * @param {*=} opt_reason The reason for cancelling this promise.
    446 */
    447 function cancel(opt_reason) {
    448 if (!isPending()) {
    449 return;
    450 }
    451
    452 if (opt_canceller) {
    453 opt_reason = opt_canceller(opt_reason) || opt_reason;
    454 }
    455
    456 reject(opt_reason);
    457 }
    458
    459 this.promise = promise;
    460 this.promise.then = this.then = then;
    461 this.promise.cancel = this.cancel = cancel;
    462 this.promise.isPending = this.isPending = isPending;
    463 this.fulfill = fulfill;
    464 this.reject = this.errback = reject;
    465
    466 // Only expose this function to our internal classes.
    467 // TODO: find a cleaner way of handling this.
    468 if (this instanceof webdriver.promise.Task_) {
    469 this.removeAll = removeAll;
    470 }
    471
    472 // Export symbols necessary for the contract on this object to work in
    473 // compiled mode.
    474 goog.exportProperty(this, 'then', this.then);
    475 goog.exportProperty(this, 'cancel', cancel);
    476 goog.exportProperty(this, 'fulfill', fulfill);
    477 goog.exportProperty(this, 'reject', reject);
    478 goog.exportProperty(this, 'isPending', isPending);
    479 goog.exportProperty(this, 'promise', this.promise);
    480 goog.exportProperty(this.promise, 'then', this.then);
    481 goog.exportProperty(this.promise, 'cancel', cancel);
    482 goog.exportProperty(this.promise, 'isPending', isPending);
    483};
    484goog.inherits(webdriver.promise.Deferred, webdriver.promise.Promise);
    485
    486
    487/**
    488 * Type definition for a listener registered on a Deferred object.
    489 * @typedef {{callback:(Function|undefined),
    490 * errback:(Function|undefined),
    491 * fulfill: function(*), reject: function(*)}}
    492 * @private
    493 */
    494webdriver.promise.Deferred.Listener_;
    495
    496
    497/**
    498 * The three states a {@link webdriver.promise.Deferred} object may be in.
    499 * @enum {number}
    500 * @private
    501 */
    502webdriver.promise.Deferred.State_ = {
    503 REJECTED: -1,
    504 PENDING: 0,
    505 BLOCKED: 1,
    506 RESOLVED: 2
    507};
    508
    509
    510/**
    511 * Tests if a value is an Error-like object. This is more than an straight
    512 * instanceof check since the value may originate from another context.
    513 * @param {*} value The value to test.
    514 * @return {boolean} Whether the value is an error.
    515 * @private
    516 */
    517webdriver.promise.isError_ = function(value) {
    518 return value instanceof Error ||
    519 goog.isObject(value) &&
    520 (Object.prototype.toString.call(value) === '[object Error]' ||
    521 // A special test for goog.testing.JsUnitException.
    522 value.isJsUnitException);
    523
    524};
    525
    526
    527/**
    528 * Determines whether a {@code value} should be treated as a promise.
    529 * Any object whose "then" property is a function will be considered a promise.
    530 *
    531 * @param {*} value The value to test.
    532 * @return {boolean} Whether the value is a promise.
    533 */
    534webdriver.promise.isPromise = function(value) {
    535 return !!value && goog.isObject(value) &&
    536 // Use array notation so the Closure compiler does not obfuscate away our
    537 // contract.
    538 goog.isFunction(value['then']);
    539};
    540
    541
    542/**
    543 * Creates a promise that will be resolved at a set time in the future.
    544 * @param {number} ms The amount of time, in milliseconds, to wait before
    545 * resolving the promise.
    546 * @return {!webdriver.promise.Promise} The promise.
    547 */
    548webdriver.promise.delayed = function(ms) {
    549 var timer = webdriver.promise.controlFlow().timer;
    550 var key;
    551 var deferred = new webdriver.promise.Deferred(function() {
    552 timer.clearTimeout(key);
    553 });
    554 key = timer.setTimeout(deferred.fulfill, ms);
    555 return deferred.promise;
    556};
    557
    558
    559/**
    560 * Creates a new deferred object.
    561 * @param {Function=} opt_canceller Function to call when cancelling the
    562 * computation of this instance's value.
    563 * @return {!webdriver.promise.Deferred.<T>} The new deferred object.
    564 * @template T
    565 */
    566webdriver.promise.defer = function(opt_canceller) {
    567 return new webdriver.promise.Deferred(opt_canceller);
    568};
    569
    570
    571/**
    572 * Creates a promise that has been resolved with the given value.
    573 * @param {T=} opt_value The resolved value.
    574 * @return {!webdriver.promise.Promise.<T>} The resolved promise.
    575 * @template T
    576 */
    577webdriver.promise.fulfilled = function(opt_value) {
    578 if (opt_value instanceof webdriver.promise.Promise) {
    579 return opt_value;
    580 }
    581 var deferred = new webdriver.promise.Deferred();
    582 deferred.fulfill(opt_value);
    583 return deferred.promise;
    584};
    585
    586
    587/**
    588 * Creates a promise that has been rejected with the given reason.
    589 * @param {*=} opt_reason The rejection reason; may be any value, but is
    590 * usually an Error or a string.
    591 * @return {!webdriver.promise.Promise.<T>} The rejected promise.
    592 * @template T
    593 */
    594webdriver.promise.rejected = function(opt_reason) {
    595 var deferred = new webdriver.promise.Deferred();
    596 deferred.reject(opt_reason);
    597 return deferred.promise;
    598};
    599
    600
    601/**
    602 * Wraps a function that is assumed to be a node-style callback as its final
    603 * argument. This callback takes two arguments: an error value (which will be
    604 * null if the call succeeded), and the success value as the second argument.
    605 * If the call fails, the returned promise will be rejected, otherwise it will
    606 * be resolved with the result.
    607 * @param {!Function} fn The function to wrap.
    608 * @return {!webdriver.promise.Promise} A promise that will be resolved with the
    609 * result of the provided function's callback.
    610 */
    611webdriver.promise.checkedNodeCall = function(fn) {
    612 var deferred = new webdriver.promise.Deferred(function() {
    613 throw Error('This Deferred may not be cancelled');
    614 });
    615 try {
    616 fn(function(error, value) {
    617 error ? deferred.reject(error) : deferred.fulfill(value);
    618 });
    619 } catch (ex) {
    620 deferred.reject(ex);
    621 }
    622 return deferred.promise;
    623};
    624
    625
    626/**
    627 * Registers an observer on a promised {@code value}, returning a new promise
    628 * that will be resolved when the value is. If {@code value} is not a promise,
    629 * then the return promise will be immediately resolved.
    630 * @param {*} value The value to observe.
    631 * @param {Function=} opt_callback The function to call when the value is
    632 * resolved successfully.
    633 * @param {Function=} opt_errback The function to call when the value is
    634 * rejected.
    635 * @return {!webdriver.promise.Promise} A new promise.
    636 */
    637webdriver.promise.when = function(value, opt_callback, opt_errback) {
    638 if (value instanceof webdriver.promise.Promise) {
    639 return value.then(opt_callback, opt_errback);
    640 }
    641
    642 var deferred = new webdriver.promise.Deferred();
    643
    644 webdriver.promise.asap(value, deferred.fulfill, deferred.reject);
    645
    646 return deferred.then(opt_callback, opt_errback);
    647};
    648
    649
    650/**
    651 * Invokes the appropriate callback function as soon as a promised
    652 * {@code value} is resolved. This function is similar to
    653 * {@link webdriver.promise.when}, except it does not return a new promise.
    654 * @param {*} value The value to observe.
    655 * @param {Function} callback The function to call when the value is
    656 * resolved successfully.
    657 * @param {Function=} opt_errback The function to call when the value is
    658 * rejected.
    659 */
    660webdriver.promise.asap = function(value, callback, opt_errback) {
    661 if (webdriver.promise.isPromise(value)) {
    662 value.then(callback, opt_errback);
    663
    664 // Maybe a Dojo-like deferred object?
    665 } else if (!!value && goog.isObject(value) &&
    666 goog.isFunction(value.addCallbacks)) {
    667 value.addCallbacks(callback, opt_errback);
    668
    669 // A raw value, return a resolved promise.
    670 } else if (callback) {
    671 callback(value);
    672 }
    673};
    674
    675
    676/**
    677 * Given an array of promises, will return a promise that will be fulfilled
    678 * with the fulfillment values of the input array's values. If any of the
    679 * input array's promises are rejected, the returned promise will be rejected
    680 * with the same reason.
    681 *
    682 * @param {!Array.<(T|!webdriver.promise.Promise.<T>)>} arr An array of
    683 * promises to wait on.
    684 * @return {!webdriver.promise.Promise.<!Array.<T>>} A promise that is
    685 * fulfilled with an array containing the fulfilled values of the
    686 * input array, or rejected with the same reason as the first
    687 * rejected value.
    688 * @template T
    689 */
    690webdriver.promise.all = function(arr) {
    691 var n = arr.length;
    692 if (!n) {
    693 return webdriver.promise.fulfilled([]);
    694 }
    695
    696 var toFulfill = n;
    697 var result = webdriver.promise.defer();
    698 var values = [];
    699
    700 var onFulfill = function(index, value) {
    701 values[index] = value;
    702 toFulfill--;
    703 if (toFulfill == 0) {
    704 result.fulfill(values);
    705 }
    706 };
    707
    708 for (var i = 0; i < n; ++i) {
    709 webdriver.promise.asap(
    710 arr[i], goog.partial(onFulfill, i), result.reject);
    711 }
    712
    713 return result.promise;
    714};
    715
    716
    717/**
    718 * Calls a function for each element in an array and inserts the result into a
    719 * new array, which is used as the fulfillment value of the promise returned
    720 * by this function.
    721 *
    722 * <p>If the return value of the mapping function is a promise, this function
    723 * will wait for it to be fulfilled before inserting it into the new array.
    724 *
    725 * <p>If the mapping function throws or returns a rejected promise, the
    726 * promise returned by this function will be rejected with the same reason.
    727 * Only the first failure will be reported; all subsequent errors will be
    728 * silently ignored.
    729 *
    730 * @param {!(Array.<TYPE>|webdriver.promise.Promise.<!Array.<TYPE>>)} arr The
    731 * array to iterator over, or a promise that will resolve to said array.
    732 * @param {function(this: SELF, TYPE, number, !Array.<TYPE>): ?} fn The
    733 * function to call for each element in the array. This function should
    734 * expect three arguments (the element, the index, and the array itself.
    735 * @param {SELF=} opt_self The object to be used as the value of 'this' within
    736 * {@code fn}.
    737 * @template TYPE, SELF
    738 */
    739webdriver.promise.map = function(arr, fn, opt_self) {
    740 return webdriver.promise.when(arr, function(arr) {
    741 var result = goog.array.map(arr, fn, opt_self);
    742 return webdriver.promise.all(result);
    743 });
    744};
    745
    746
    747/**
    748 * Calls a function for each element in an array, and if the function returns
    749 * true adds the element to a new array.
    750 *
    751 * <p>If the return value of the filter function is a promise, this function
    752 * will wait for it to be fulfilled before determining whether to insert the
    753 * element into the new array.
    754 *
    755 * <p>If the filter function throws or returns a rejected promise, the promise
    756 * returned by this function will be rejected with the same reason. Only the
    757 * first failure will be reported; all subsequent errors will be silently
    758 * ignored.
    759 *
    760 * @param {!(Array.<TYPE>|webdriver.promise.Promise.<!Array.<TYPE>>)} arr The
    761 * array to iterator over, or a promise that will resolve to said array.
    762 * @param {function(this: SELF, TYPE, number, !Array.<TYPE>): (
    763 * boolean|webdriver.promise.Promise.<boolean>)} fn The function
    764 * to call for each element in the array.
    765 * @param {SELF=} opt_self The object to be used as the value of 'this' within
    766 * {@code fn}.
    767 * @template TYPE, SELF
    768 */
    769webdriver.promise.filter = function(arr, fn, opt_self) {
    770 return webdriver.promise.when(arr, function(arr) {
    771 var originalValues = goog.array.clone(arr);
    772 return webdriver.promise.map(arr, fn, opt_self).then(function(include) {
    773 return goog.array.filter(originalValues, function(value, index) {
    774 return include[index];
    775 });
    776 });
    777 });
    778};
    779
    780
    781/**
    782 * Returns a promise that will be resolved with the input value in a
    783 * fully-resolved state. If the value is an array, each element will be fully
    784 * resolved. Likewise, if the value is an object, all keys will be fully
    785 * resolved. In both cases, all nested arrays and objects will also be
    786 * fully resolved. All fields are resolved in place; the returned promise will
    787 * resolve on {@code value} and not a copy.
    788 *
    789 * Warning: This function makes no checks against objects that contain
    790 * cyclical references:
    791 * <pre><code>
    792 * var value = {};
    793 * value['self'] = value;
    794 * webdriver.promise.fullyResolved(value); // Stack overflow.
    795 * </code></pre>
    796 *
    797 * @param {*} value The value to fully resolve.
    798 * @return {!webdriver.promise.Promise} A promise for a fully resolved version
    799 * of the input value.
    800 */
    801webdriver.promise.fullyResolved = function(value) {
    802 if (webdriver.promise.isPromise(value)) {
    803 return webdriver.promise.when(value, webdriver.promise.fullyResolveValue_);
    804 }
    805 return webdriver.promise.fullyResolveValue_(value);
    806};
    807
    808
    809/**
    810 * @param {*} value The value to fully resolve. If a promise, assumed to
    811 * already be resolved.
    812 * @return {!webdriver.promise.Promise} A promise for a fully resolved version
    813 * of the input value.
    814 * @private
    815 */
    816webdriver.promise.fullyResolveValue_ = function(value) {
    817 switch (goog.typeOf(value)) {
    818 case 'array':
    819 return webdriver.promise.fullyResolveKeys_(
    820 /** @type {!Array} */ (value));
    821
    822 case 'object':
    823 if (webdriver.promise.isPromise(value)) {
    824 // We get here when the original input value is a promise that
    825 // resolves to itself. When the user provides us with such a promise,
    826 // trust that it counts as a "fully resolved" value and return it.
    827 // Of course, since it's already a promise, we can just return it
    828 // to the user instead of wrapping it in another promise.
    829 return /** @type {!webdriver.promise.Promise} */ (value);
    830 }
    831
    832 if (goog.isNumber(value.nodeType) &&
    833 goog.isObject(value.ownerDocument) &&
    834 goog.isNumber(value.ownerDocument.nodeType)) {
    835 // DOM node; return early to avoid infinite recursion. Should we
    836 // only support objects with a certain level of nesting?
    837 return webdriver.promise.fulfilled(value);
    838 }
    839
    840 return webdriver.promise.fullyResolveKeys_(
    841 /** @type {!Object} */ (value));
    842
    843 default: // boolean, function, null, number, string, undefined
    844 return webdriver.promise.fulfilled(value);
    845 }
    846};
    847
    848
    849/**
    850 * @param {!(Array|Object)} obj the object to resolve.
    851 * @return {!webdriver.promise.Promise} A promise that will be resolved with the
    852 * input object once all of its values have been fully resolved.
    853 * @private
    854 */
    855webdriver.promise.fullyResolveKeys_ = function(obj) {
    856 var isArray = goog.isArray(obj);
    857 var numKeys = isArray ? obj.length : goog.object.getCount(obj);
    858 if (!numKeys) {
    859 return webdriver.promise.fulfilled(obj);
    860 }
    861
    862 var numResolved = 0;
    863 var deferred = new webdriver.promise.Deferred();
    864
    865 // In pre-IE9, goog.array.forEach will not iterate properly over arrays
    866 // containing undefined values because "index in array" returns false
    867 // when array[index] === undefined (even for x = [undefined, 1]). To get
    868 // around this, we need to use our own forEach implementation.
    869 // DO NOT REMOVE THIS UNTIL WE NO LONGER SUPPORT IE8. This cannot be
    870 // reproduced in IE9 by changing the browser/document modes, it requires an
    871 // actual pre-IE9 browser. Yay, IE!
    872 var forEachKey = !isArray ? goog.object.forEach : function(arr, fn) {
    873 var n = arr.length;
    874 for (var i = 0; i < n; ++i) {
    875 fn.call(null, arr[i], i, arr);
    876 }
    877 };
    878
    879 forEachKey(obj, function(partialValue, key) {
    880 var type = goog.typeOf(partialValue);
    881 if (type != 'array' && type != 'object') {
    882 maybeResolveValue();
    883 return;
    884 }
    885
    886 webdriver.promise.fullyResolved(partialValue).then(
    887 function(resolvedValue) {
    888 obj[key] = resolvedValue;
    889 maybeResolveValue();
    890 },
    891 deferred.reject);
    892 });
    893
    894 return deferred.promise;
    895
    896 function maybeResolveValue() {
    897 if (++numResolved == numKeys) {
    898 deferred.fulfill(obj);
    899 }
    900 }
    901};
    902
    903
    904//////////////////////////////////////////////////////////////////////////////
    905//
    906// webdriver.promise.ControlFlow
    907//
    908//////////////////////////////////////////////////////////////////////////////
    909
    910
    911
    912/**
    913 * Handles the execution of scheduled tasks, each of which may be an
    914 * asynchronous operation. The control flow will ensure tasks are executed in
    915 * the ordered scheduled, starting each task only once those before it have
    916 * completed.
    917 *
    918 * <p>Each task scheduled within this flow may return a
    919 * {@link webdriver.promise.Promise} to indicate it is an asynchronous
    920 * operation. The ControlFlow will wait for such promises to be resolved before
    921 * marking the task as completed.
    922 *
    923 * <p>Tasks and each callback registered on a {@link webdriver.promise.Deferred}
    924 * will be run in their own ControlFlow frame. Any tasks scheduled within a
    925 * frame will have priority over previously scheduled tasks. Furthermore, if
    926 * any of the tasks in the frame fails, the remainder of the tasks in that frame
    927 * will be discarded and the failure will be propagated to the user through the
    928 * callback/task's promised result.
    929 *
    930 * <p>Each time a ControlFlow empties its task queue, it will fire an
    931 * {@link webdriver.promise.ControlFlow.EventType.IDLE} event. Conversely,
    932 * whenever the flow terminates due to an unhandled error, it will remove all
    933 * remaining tasks in its queue and fire an
    934 * {@link webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION} event. If
    935 * there are no listeners registered with the flow, the error will be
    936 * rethrown to the global error handler.
    937 *
    938 * @param {webdriver.promise.ControlFlow.Timer=} opt_timer The timer object
    939 * to use. Should only be set for testing.
    940 * @constructor
    941 * @extends {webdriver.EventEmitter}
    942 */
    943webdriver.promise.ControlFlow = function(opt_timer) {
    944 webdriver.EventEmitter.call(this);
    945
    946 /**
    947 * The timer used by this instance.
    948 * @type {webdriver.promise.ControlFlow.Timer}
    949 */
    950 this.timer = opt_timer || webdriver.promise.ControlFlow.defaultTimer;
    951
    952 /**
    953 * A list of recent tasks. Each time a new task is started, or a frame is
    954 * completed, the previously recorded task is removed from this list. If
    955 * there are multiple tasks, task N+1 is considered a sub-task of task
    956 * N.
    957 * @private {!Array.<!webdriver.promise.Task_>}
    958 */
    959 this.history_ = [];
    960};
    961goog.inherits(webdriver.promise.ControlFlow, webdriver.EventEmitter);
    962
    963
    964/**
    965 * @typedef {{clearInterval: function(number),
    966 * clearTimeout: function(number),
    967 * setInterval: function(!Function, number): number,
    968 * setTimeout: function(!Function, number): number}}
    969 */
    970webdriver.promise.ControlFlow.Timer;
    971
    972
    973/**
    974 * The default timer object, which uses the global timer functions.
    975 * @type {webdriver.promise.ControlFlow.Timer}
    976 */
    977webdriver.promise.ControlFlow.defaultTimer = (function() {
    978 // The default timer functions may be defined as free variables for the
    979 // current context, so do not reference them using "window" or
    980 // "goog.global". Also, we must invoke them in a closure, and not using
    981 // bind(), so we do not get "TypeError: Illegal invocation" (WebKit) or
    982 // "Invalid calling object" (IE) errors.
    983 return {
    984 clearInterval: wrap(clearInterval),
    985 clearTimeout: wrap(clearTimeout),
    986 setInterval: wrap(setInterval),
    987 setTimeout: wrap(setTimeout)
    988 };
    989
    990 function wrap(fn) {
    991 return function() {
    992 // Cannot use .call() or .apply() since we do not know which variable
    993 // the function is bound to, and using the wrong one will generate
    994 // an error.
    995 return fn(arguments[0], arguments[1]);
    996 };
    997 }
    998})();
    999
    1000
    1001/**
    1002 * Events that may be emitted by an {@link webdriver.promise.ControlFlow}.
    1003 * @enum {string}
    1004 */
    1005webdriver.promise.ControlFlow.EventType = {
    1006
    1007 /** Emitted when all tasks have been successfully executed. */
    1008 IDLE: 'idle',
    1009
    1010 /** Emitted whenever a new task has been scheduled. */
    1011 SCHEDULE_TASK: 'scheduleTask',
    1012
    1013 /**
    1014 * Emitted whenever a control flow aborts due to an unhandled promise
    1015 * rejection. This event will be emitted along with the offending rejection
    1016 * reason. Upon emitting this event, the control flow will empty its task
    1017 * queue and revert to its initial state.
    1018 */
    1019 UNCAUGHT_EXCEPTION: 'uncaughtException'
    1020};
    1021
    1022
    1023/**
    1024 * How often, in milliseconds, the event loop should run.
    1025 * @type {number}
    1026 * @const
    1027 */
    1028webdriver.promise.ControlFlow.EVENT_LOOP_FREQUENCY = 10;
    1029
    1030
    1031/**
    1032 * Tracks the active execution frame for this instance. Lazily initialized
    1033 * when the first task is scheduled.
    1034 * @private {webdriver.promise.Frame_}
    1035 */
    1036webdriver.promise.ControlFlow.prototype.activeFrame_ = null;
    1037
    1038
    1039/**
    1040 * A reference to the frame in which new tasks should be scheduled. If
    1041 * {@code null}, tasks will be scheduled within the active frame. When forcing
    1042 * a function to run in the context of a new frame, this pointer is used to
    1043 * ensure tasks are scheduled within the newly created frame, even though it
    1044 * won't be active yet.
    1045 * @private {webdriver.promise.Frame_}
    1046 * @see {#runInNewFrame_}
    1047 */
    1048webdriver.promise.ControlFlow.prototype.schedulingFrame_ = null;
    1049
    1050
    1051/**
    1052 * Timeout ID set when the flow is about to shutdown without any errors
    1053 * being detected. Upon shutting down, the flow will emit an
    1054 * {@link webdriver.promise.ControlFlow.EventType.IDLE} event. Idle events
    1055 * always follow a brief timeout in order to catch latent errors from the last
    1056 * completed task. If this task had a callback registered, but no errback, and
    1057 * the task fails, the unhandled failure would not be reported by the promise
    1058 * system until the next turn of the event loop:
    1059 *
    1060 * // Schedule 1 task that fails.
    1061 * var result = webriver.promise.controlFlow().schedule('example',
    1062 * function() { return webdriver.promise.rejected('failed'); });
    1063 * // Set a callback on the result. This delays reporting the unhandled
    1064 * // failure for 1 turn of the event loop.
    1065 * result.then(goog.nullFunction);
    1066 *
    1067 * @private {?number}
    1068 */
    1069webdriver.promise.ControlFlow.prototype.shutdownId_ = null;
    1070
    1071
    1072/**
    1073 * Interval ID for this instance's event loop.
    1074 * @private {?number}
    1075 */
    1076webdriver.promise.ControlFlow.prototype.eventLoopId_ = null;
    1077
    1078
    1079/**
    1080 * The number of "pending" promise rejections.
    1081 *
    1082 * <p>Each time a promise is rejected and is not handled by a listener, it will
    1083 * schedule a 0-based timeout to check if it is still unrejected in the next
    1084 * turn of the JS-event loop. This allows listeners to attach to, and handle,
    1085 * the rejected promise at any point in same turn of the event loop that the
    1086 * promise was rejected.
    1087 *
    1088 * <p>When this flow's own event loop triggers, it will not run if there
    1089 * are any outstanding promise rejections. This allows unhandled promises to
    1090 * be reported before a new task is started, ensuring the error is reported to
    1091 * the current task queue.
    1092 *
    1093 * @private {number}
    1094 */
    1095webdriver.promise.ControlFlow.prototype.pendingRejections_ = 0;
    1096
    1097
    1098/**
    1099 * The number of aborted frames since the last time a task was executed or a
    1100 * frame completed successfully.
    1101 * @private {number}
    1102 */
    1103webdriver.promise.ControlFlow.prototype.numAbortedFrames_ = 0;
    1104
    1105
    1106/**
    1107 * Resets this instance, clearing its queue and removing all event listeners.
    1108 */
    1109webdriver.promise.ControlFlow.prototype.reset = function() {
    1110 this.activeFrame_ = null;
    1111 this.clearHistory();
    1112 this.removeAllListeners();
    1113 this.cancelShutdown_();
    1114 this.cancelEventLoop_();
    1115};
    1116
    1117
    1118/**
    1119 * Returns a summary of the recent task activity for this instance. This
    1120 * includes the most recently completed task, as well as any parent tasks. In
    1121 * the returned summary, the task at index N is considered a sub-task of the
    1122 * task at index N+1.
    1123 * @return {!Array.<string>} A summary of this instance's recent task
    1124 * activity.
    1125 */
    1126webdriver.promise.ControlFlow.prototype.getHistory = function() {
    1127 var pendingTasks = [];
    1128 var currentFrame = this.activeFrame_;
    1129 while (currentFrame) {
    1130 var task = currentFrame.getPendingTask();
    1131 if (task) {
    1132 pendingTasks.push(task);
    1133 }
    1134 // A frame's parent node will always be another frame.
    1135 currentFrame =
    1136 /** @type {webdriver.promise.Frame_} */ (currentFrame.getParent());
    1137 }
    1138
    1139 var fullHistory = goog.array.concat(this.history_, pendingTasks);
    1140 return goog.array.map(fullHistory, function(task) {
    1141 return task.toString();
    1142 });
    1143};
    1144
    1145
    1146/** Clears this instance's task history. */
    1147webdriver.promise.ControlFlow.prototype.clearHistory = function() {
    1148 this.history_ = [];
    1149};
    1150
    1151
    1152/**
    1153 * Removes a completed task from this instance's history record. If any
    1154 * tasks remain from aborted frames, those will be removed as well.
    1155 * @private
    1156 */
    1157webdriver.promise.ControlFlow.prototype.trimHistory_ = function() {
    1158 if (this.numAbortedFrames_) {
    1159 goog.array.splice(this.history_,
    1160 this.history_.length - this.numAbortedFrames_,
    1161 this.numAbortedFrames_);
    1162 this.numAbortedFrames_ = 0;
    1163 }
    1164 this.history_.pop();
    1165};
    1166
    1167
    1168/**
    1169 * Property used to track whether an error has been annotated by
    1170 * {@link webdriver.promise.ControlFlow#annotateError}.
    1171 * @private {string}
    1172 * @const
    1173 */
    1174webdriver.promise.ControlFlow.ANNOTATION_PROPERTY_ =
    1175 'webdriver_promise_error_';
    1176
    1177
    1178/**
    1179 * Appends a summary of this instance's recent task history to the given
    1180 * error's stack trace. This function will also ensure the error's stack trace
    1181 * is in canonical form.
    1182 * @param {!(Error|goog.testing.JsUnitException)} e The error to annotate.
    1183 * @return {!(Error|goog.testing.JsUnitException)} The annotated error.
    1184 */
    1185webdriver.promise.ControlFlow.prototype.annotateError = function(e) {
    1186 if (!!e[webdriver.promise.ControlFlow.ANNOTATION_PROPERTY_]) {
    1187 return e;
    1188 }
    1189
    1190 var history = this.getHistory();
    1191 if (history.length) {
    1192 e = webdriver.stacktrace.format(e);
    1193
    1194 /** @type {!Error} */(e).stack += [
    1195 '\n==== async task ====\n',
    1196 history.join('\n==== async task ====\n')
    1197 ].join('');
    1198
    1199 e[webdriver.promise.ControlFlow.ANNOTATION_PROPERTY_] = true;
    1200 }
    1201
    1202 return e;
    1203};
    1204
    1205
    1206/**
    1207 * @return {string} The scheduled tasks still pending with this instance.
    1208 */
    1209webdriver.promise.ControlFlow.prototype.getSchedule = function() {
    1210 return this.activeFrame_ ? this.activeFrame_.getRoot().toString() : '[]';
    1211};
    1212
    1213
    1214/**
    1215 * Schedules a task for execution. If there is nothing currently in the
    1216 * queue, the task will be executed in the next turn of the event loop.
    1217 *
    1218 * @param {function(): (T|webdriver.promise.Promise.<T>)} fn The function to
    1219 * call to start the task. If the function returns a
    1220 * {@link webdriver.promise.Promise}, this instance will wait for it to be
    1221 * resolved before starting the next task.
    1222 * @param {string=} opt_description A description of the task.
    1223 * @return {!webdriver.promise.Promise.<T>} A promise that will be resolved
    1224 * with the result of the action.
    1225 * @template T
    1226 */
    1227webdriver.promise.ControlFlow.prototype.execute = function(
    1228 fn, opt_description) {
    1229 this.cancelShutdown_();
    1230
    1231 if (!this.activeFrame_) {
    1232 this.activeFrame_ = new webdriver.promise.Frame_(this);
    1233 }
    1234
    1235 // Trim an extra frame off the generated stack trace for the call to this
    1236 // function.
    1237 var snapshot = new webdriver.stacktrace.Snapshot(1);
    1238 var task = new webdriver.promise.Task_(
    1239 this, fn, opt_description || '', snapshot);
    1240 var scheduleIn = this.schedulingFrame_ || this.activeFrame_;
    1241 scheduleIn.addChild(task);
    1242
    1243 this.emit(webdriver.promise.ControlFlow.EventType.SCHEDULE_TASK, opt_description);
    1244
    1245 this.scheduleEventLoopStart_();
    1246 return task.promise;
    1247};
    1248
    1249
    1250/**
    1251 * Inserts a {@code setTimeout} into the command queue. This is equivalent to
    1252 * a thread sleep in a synchronous programming language.
    1253 *
    1254 * @param {number} ms The timeout delay, in milliseconds.
    1255 * @param {string=} opt_description A description to accompany the timeout.
    1256 * @return {!webdriver.promise.Promise} A promise that will be resolved with
    1257 * the result of the action.
    1258 */
    1259webdriver.promise.ControlFlow.prototype.timeout = function(
    1260 ms, opt_description) {
    1261 return this.execute(function() {
    1262 return webdriver.promise.delayed(ms);
    1263 }, opt_description);
    1264};
    1265
    1266
    1267/**
    1268 * Schedules a task that shall wait for a condition to hold. Each condition
    1269 * function may return any value, but it will always be evaluated as a boolean.
    1270 *
    1271 * <p>Condition functions may schedule sub-tasks with this instance, however,
    1272 * their execution time will be factored into whether a wait has timed out.
    1273 *
    1274 * <p>In the event a condition returns a Promise, the polling loop will wait for
    1275 * it to be resolved before evaluating whether the condition has been satisfied.
    1276 * The resolution time for a promise is factored into whether a wait has timed
    1277 * out.
    1278 *
    1279 * <p>If the condition function throws, or returns a rejected promise, the
    1280 * wait task will fail.
    1281 *
    1282 * @param {!Function} condition The condition function to poll.
    1283 * @param {number} timeout How long to wait, in milliseconds, for the condition
    1284 * to hold before timing out.
    1285 * @param {string=} opt_message An optional error message to include if the
    1286 * wait times out; defaults to the empty string.
    1287 * @return {!webdriver.promise.Promise} A promise that will be resolved when the
    1288 * condition has been satisified. The promise shall be rejected if the wait
    1289 * times out waiting for the condition.
    1290 */
    1291webdriver.promise.ControlFlow.prototype.wait = function(
    1292 condition, timeout, opt_message) {
    1293 var sleep = Math.min(timeout, 100);
    1294 var self = this;
    1295
    1296 return this.execute(function() {
    1297 var startTime = goog.now();
    1298 var waitResult = new webdriver.promise.Deferred();
    1299 var waitFrame = self.activeFrame_;
    1300 waitFrame.isWaiting = true;
    1301 pollCondition();
    1302 return waitResult.promise;
    1303
    1304 function pollCondition() {
    1305 self.runInNewFrame_(condition, function(value) {
    1306 var elapsed = goog.now() - startTime;
    1307 if (!!value) {
    1308 waitFrame.isWaiting = false;
    1309 waitResult.fulfill(value);
    1310 } else if (elapsed >= timeout) {
    1311 waitResult.reject(new Error((opt_message ? opt_message + '\n' : '') +
    1312 'Wait timed out after ' + elapsed + 'ms'));
    1313 } else {
    1314 self.timer.setTimeout(pollCondition, sleep);
    1315 }
    1316 }, waitResult.reject, true);
    1317 }
    1318 }, opt_message);
    1319};
    1320
    1321
    1322/**
    1323 * Schedules a task that will wait for another promise to resolve. The resolved
    1324 * promise's value will be returned as the task result.
    1325 * @param {!webdriver.promise.Promise} promise The promise to wait on.
    1326 * @return {!webdriver.promise.Promise} A promise that will resolve when the
    1327 * task has completed.
    1328 */
    1329webdriver.promise.ControlFlow.prototype.await = function(promise) {
    1330 return this.execute(function() {
    1331 return promise;
    1332 });
    1333};
    1334
    1335
    1336/**
    1337 * Schedules the interval for this instance's event loop, if necessary.
    1338 * @private
    1339 */
    1340webdriver.promise.ControlFlow.prototype.scheduleEventLoopStart_ = function() {
    1341 if (!this.eventLoopId_) {
    1342 this.eventLoopId_ = this.timer.setInterval(
    1343 goog.bind(this.runEventLoop_, this),
    1344 webdriver.promise.ControlFlow.EVENT_LOOP_FREQUENCY);
    1345 }
    1346};
    1347
    1348
    1349/**
    1350 * Cancels the event loop, if necessary.
    1351 * @private
    1352 */
    1353webdriver.promise.ControlFlow.prototype.cancelEventLoop_ = function() {
    1354 if (this.eventLoopId_) {
    1355 this.timer.clearInterval(this.eventLoopId_);
    1356 this.eventLoopId_ = null;
    1357 }
    1358};
    1359
    1360
    1361/**
    1362 * Executes the next task for the current frame. If the current frame has no
    1363 * more tasks, the frame's result will be resolved, returning control to the
    1364 * frame's creator. This will terminate the flow if the completed frame was at
    1365 * the top of the stack.
    1366 * @private
    1367 */
    1368webdriver.promise.ControlFlow.prototype.runEventLoop_ = function() {
    1369 // If we get here and there are pending promise rejections, then those
    1370 // promises are queued up to run as soon as this (JS) event loop terminates.
    1371 // Short-circuit our loop to give those promises a chance to run. Otherwise,
    1372 // we might start a new task only to have it fail because of one of these
    1373 // pending rejections.
    1374 if (this.pendingRejections_) {
    1375 return;
    1376 }
    1377
    1378 // If the flow aborts due to an unhandled exception after we've scheduled
    1379 // another turn of the execution loop, we can end up in here with no tasks
    1380 // left. This is OK, just quietly return.
    1381 if (!this.activeFrame_) {
    1382 this.commenceShutdown_();
    1383 return;
    1384 }
    1385
    1386 var task;
    1387 if (this.activeFrame_.getPendingTask() || !(task = this.getNextTask_())) {
    1388 // Either the current frame is blocked on a pending task, or we don't have
    1389 // a task to finish because we've completed a frame. When completing a
    1390 // frame, we must abort the event loop to allow the frame's promise's
    1391 // callbacks to execute.
    1392 return;
    1393 }
    1394
    1395 var activeFrame = this.activeFrame_;
    1396 activeFrame.setPendingTask(task);
    1397 var markTaskComplete = goog.bind(function() {
    1398 this.history_.push(/** @type {!webdriver.promise.Task_} */ (task));
    1399 activeFrame.setPendingTask(null);
    1400 }, this);
    1401
    1402 this.trimHistory_();
    1403 var self = this;
    1404 this.runInNewFrame_(task.execute, function(result) {
    1405 markTaskComplete();
    1406 task.fulfill(result);
    1407 }, function(error) {
    1408 markTaskComplete();
    1409
    1410 if (!webdriver.promise.isError_(error) &&
    1411 !webdriver.promise.isPromise(error)) {
    1412 error = Error(error);
    1413 }
    1414
    1415 task.reject(self.annotateError(/** @type {!Error} */ (error)));
    1416 }, true);
    1417};
    1418
    1419
    1420/**
    1421 * @return {webdriver.promise.Task_} The next task to execute, or
    1422 * {@code null} if a frame was resolved.
    1423 * @private
    1424 */
    1425webdriver.promise.ControlFlow.prototype.getNextTask_ = function() {
    1426 var firstChild = this.activeFrame_.getFirstChild();
    1427 if (!firstChild) {
    1428 if (!this.activeFrame_.isWaiting) {
    1429 this.resolveFrame_(this.activeFrame_);
    1430 }
    1431 return null;
    1432 }
    1433
    1434 if (firstChild instanceof webdriver.promise.Frame_) {
    1435 this.activeFrame_ = firstChild;
    1436 return this.getNextTask_();
    1437 }
    1438
    1439 firstChild.getParent().removeChild(firstChild);
    1440 return firstChild;
    1441};
    1442
    1443
    1444/**
    1445 * @param {!webdriver.promise.Frame_} frame The frame to resolve.
    1446 * @private
    1447 */
    1448webdriver.promise.ControlFlow.prototype.resolveFrame_ = function(frame) {
    1449 if (this.activeFrame_ === frame) {
    1450 // Frame parent is always another frame, but the compiler is not smart
    1451 // enough to recognize this.
    1452 this.activeFrame_ =
    1453 /** @type {webdriver.promise.Frame_} */ (frame.getParent());
    1454 }
    1455
    1456 if (frame.getParent()) {
    1457 frame.getParent().removeChild(frame);
    1458 }
    1459 this.trimHistory_();
    1460 frame.fulfill();
    1461
    1462 if (!this.activeFrame_) {
    1463 this.commenceShutdown_();
    1464 }
    1465};
    1466
    1467
    1468/**
    1469 * Aborts the current frame. The frame, and all of the tasks scheduled within it
    1470 * will be discarded. If this instance does not have an active frame, it will
    1471 * immediately terminate all execution.
    1472 * @param {*} error The reason the frame is being aborted; typically either
    1473 * an Error or string.
    1474 * @private
    1475 */
    1476webdriver.promise.ControlFlow.prototype.abortFrame_ = function(error) {
    1477 // Annotate the error value if it is Error-like.
    1478 if (webdriver.promise.isError_(error)) {
    1479 this.annotateError(/** @type {!Error} */ (error));
    1480 }
    1481 this.numAbortedFrames_++;
    1482
    1483 if (!this.activeFrame_) {
    1484 this.abortNow_(error);
    1485 return;
    1486 }
    1487
    1488 // Frame parent is always another frame, but the compiler is not smart
    1489 // enough to recognize this.
    1490 var parent = /** @type {webdriver.promise.Frame_} */ (
    1491 this.activeFrame_.getParent());
    1492 if (parent) {
    1493 parent.removeChild(this.activeFrame_);
    1494 }
    1495
    1496 var frame = this.activeFrame_;
    1497 this.activeFrame_ = parent;
    1498 frame.reject(error);
    1499};
    1500
    1501
    1502/**
    1503 * Executes a function in a new frame. If the function does not schedule any new
    1504 * tasks, the frame will be discarded and the function's result returned
    1505 * immediately. Otherwise, a promise will be returned. This promise will be
    1506 * resolved with the function's result once all of the tasks scheduled within
    1507 * the function have been completed. If the function's frame is aborted, the
    1508 * returned promise will be rejected.
    1509 *
    1510 * @param {!Function} fn The function to execute.
    1511 * @param {function(*)} callback The function to call with a successful result.
    1512 * @param {function(*)} errback The function to call if there is an error.
    1513 * @param {boolean=} opt_activate Whether the active frame should be updated to
    1514 * the newly created frame so tasks are treated as sub-tasks.
    1515 * @private
    1516 */
    1517webdriver.promise.ControlFlow.prototype.runInNewFrame_ = function(
    1518 fn, callback, errback, opt_activate) {
    1519 var newFrame = new webdriver.promise.Frame_(this),
    1520 self = this,
    1521 oldFrame = this.activeFrame_;
    1522
    1523 try {
    1524 if (!this.activeFrame_) {
    1525 this.activeFrame_ = newFrame;
    1526 } else {
    1527 this.activeFrame_.addChild(newFrame);
    1528 }
    1529
    1530 // Activate the new frame to force tasks to be treated as sub-tasks of
    1531 // the parent frame.
    1532 if (opt_activate) {
    1533 this.activeFrame_ = newFrame;
    1534 }
    1535
    1536 try {
    1537 this.schedulingFrame_ = newFrame;
    1538 webdriver.promise.pushFlow_(this);
    1539 var result = fn();
    1540 } finally {
    1541 webdriver.promise.popFlow_();
    1542 this.schedulingFrame_ = null;
    1543 }
    1544 newFrame.lockFrame();
    1545
    1546 // If there was nothing scheduled in the new frame we can discard the
    1547 // frame and return immediately.
    1548 if (!newFrame.children_.length) {
    1549 removeNewFrame();
    1550 webdriver.promise.asap(result, callback, errback);
    1551 return;
    1552 }
    1553
    1554 newFrame.then(function() {
    1555 webdriver.promise.asap(result, callback, errback);
    1556 }, function(e) {
    1557 if (result instanceof webdriver.promise.Promise && result.isPending()) {
    1558 result.cancel(e);
    1559 e = result;
    1560 }
    1561 errback(e);
    1562 });
    1563 } catch (ex) {
    1564 removeNewFrame(new webdriver.promise.CanceledTaskError_(ex));
    1565 errback(ex);
    1566 }
    1567
    1568 /**
    1569 * @param {webdriver.promise.CanceledTaskError_=} opt_err If provided, the
    1570 * error that triggered the removal of this frame.
    1571 */
    1572 function removeNewFrame(opt_err) {
    1573 var parent = newFrame.getParent();
    1574 if (parent) {
    1575 parent.removeChild(newFrame);
    1576 }
    1577
    1578 if (opt_err) {
    1579 newFrame.cancelRemainingTasks(opt_err);
    1580 }
    1581 self.activeFrame_ = oldFrame;
    1582 }
    1583};
    1584
    1585
    1586/**
    1587 * Commences the shutdown sequence for this instance. After one turn of the
    1588 * event loop, this object will emit the
    1589 * {@link webdriver.promise.ControlFlow.EventType.IDLE} event to signal
    1590 * listeners that it has completed. During this wait, if another task is
    1591 * scheduled, the shutdown will be aborted.
    1592 * @private
    1593 */
    1594webdriver.promise.ControlFlow.prototype.commenceShutdown_ = function() {
    1595 if (!this.shutdownId_) {
    1596 // Go ahead and stop the event loop now. If we're in here, then there are
    1597 // no more frames with tasks to execute. If we waited to cancel the event
    1598 // loop in our timeout below, the event loop could trigger *before* the
    1599 // timeout, generating an error from there being no frames.
    1600 // If #execute is called before the timeout below fires, it will cancel
    1601 // the timeout and restart the event loop.
    1602 this.cancelEventLoop_();
    1603
    1604 var self = this;
    1605 self.shutdownId_ = self.timer.setTimeout(function() {
    1606 self.shutdownId_ = null;
    1607 self.emit(webdriver.promise.ControlFlow.EventType.IDLE);
    1608 }, 0);
    1609 }
    1610};
    1611
    1612
    1613/**
    1614 * Cancels the shutdown sequence if it is currently scheduled.
    1615 * @private
    1616 */
    1617webdriver.promise.ControlFlow.prototype.cancelShutdown_ = function() {
    1618 if (this.shutdownId_) {
    1619 this.timer.clearTimeout(this.shutdownId_);
    1620 this.shutdownId_ = null;
    1621 }
    1622};
    1623
    1624
    1625/**
    1626 * Aborts this flow, abandoning all remaining tasks. If there are
    1627 * listeners registered, an {@code UNCAUGHT_EXCEPTION} will be emitted with the
    1628 * offending {@code error}, otherwise, the {@code error} will be rethrown to the
    1629 * global error handler.
    1630 * @param {*} error Object describing the error that caused the flow to
    1631 * abort; usually either an Error or string value.
    1632 * @private
    1633 */
    1634webdriver.promise.ControlFlow.prototype.abortNow_ = function(error) {
    1635 this.activeFrame_ = null;
    1636 this.cancelShutdown_();
    1637 this.cancelEventLoop_();
    1638
    1639 var listeners = this.listeners(
    1640 webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
    1641 if (!listeners.length) {
    1642 this.timer.setTimeout(function() {
    1643 throw error;
    1644 }, 0);
    1645 } else {
    1646 this.emit(webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
    1647 error);
    1648 }
    1649};
    1650
    1651
    1652
    1653/**
    1654 * A single node in an {@link webdriver.promise.ControlFlow}'s task tree.
    1655 * @param {!webdriver.promise.ControlFlow} flow The flow this instance belongs
    1656 * to.
    1657 * @constructor
    1658 * @extends {webdriver.promise.Deferred}
    1659 * @private
    1660 */
    1661webdriver.promise.Node_ = function(flow) {
    1662 webdriver.promise.Deferred.call(this, null, flow);
    1663};
    1664goog.inherits(webdriver.promise.Node_, webdriver.promise.Deferred);
    1665
    1666
    1667/**
    1668 * This node's parent.
    1669 * @private {webdriver.promise.Node_}
    1670 */
    1671webdriver.promise.Node_.prototype.parent_ = null;
    1672
    1673
    1674/** @return {webdriver.promise.Node_} This node's parent. */
    1675webdriver.promise.Node_.prototype.getParent = function() {
    1676 return this.parent_;
    1677};
    1678
    1679
    1680/**
    1681 * @param {webdriver.promise.Node_} parent This node's new parent.
    1682 */
    1683webdriver.promise.Node_.prototype.setParent = function(parent) {
    1684 this.parent_ = parent;
    1685};
    1686
    1687
    1688/**
    1689 * @return {!webdriver.promise.Node_} The root of this node's tree.
    1690 */
    1691webdriver.promise.Node_.prototype.getRoot = function() {
    1692 var root = this;
    1693 while (root.parent_) {
    1694 root = root.parent_;
    1695 }
    1696 return root;
    1697};
    1698
    1699
    1700
    1701/**
    1702 * An execution frame within a {@link webdriver.promise.ControlFlow}. Each
    1703 * frame represents the execution context for either a
    1704 * {@link webdriver.promise.Task_} or a callback on a
    1705 * {@link webdriver.promise.Deferred}.
    1706 *
    1707 * <p>Each frame may contain sub-frames. If child N is a sub-frame, then the
    1708 * items queued within it are given priority over child N+1.
    1709 *
    1710 * @param {!webdriver.promise.ControlFlow} flow The flow this instance belongs
    1711 * to.
    1712 * @constructor
    1713 * @extends {webdriver.promise.Node_}
    1714 * @private
    1715 */
    1716webdriver.promise.Frame_ = function(flow) {
    1717 webdriver.promise.Node_.call(this, flow);
    1718
    1719 var reject = goog.bind(this.reject, this);
    1720 var cancelRemainingTasks = goog.bind(this.cancelRemainingTasks, this);
    1721
    1722 /** @override */
    1723 this.reject = function(e) {
    1724 cancelRemainingTasks(new webdriver.promise.CanceledTaskError_(e));
    1725 reject(e);
    1726 };
    1727
    1728 /**
    1729 * @private {!Array.<!(webdriver.promise.Frame_|webdriver.promise.Task_)>}
    1730 */
    1731 this.children_ = [];
    1732};
    1733goog.inherits(webdriver.promise.Frame_, webdriver.promise.Node_);
    1734
    1735
    1736/**
    1737 * The task currently being executed within this frame.
    1738 * @private {webdriver.promise.Task_}
    1739 */
    1740webdriver.promise.Frame_.prototype.pendingTask_ = null;
    1741
    1742
    1743/**
    1744 * Whether this frame is active. A frame is considered active once one of its
    1745 * descendants has been removed for execution.
    1746 *
    1747 * Adding a sub-frame as a child to an active frame is an indication that
    1748 * a callback to a {@link webdriver.promise.Deferred} is being invoked and any
    1749 * tasks scheduled within it should have priority over previously scheduled
    1750 * tasks:
    1751 * <code><pre>
    1752 * var flow = webdriver.promise.controlFlow();
    1753 * flow.execute('start here', goog.nullFunction).then(function() {
    1754 * flow.execute('this should execute 2nd', goog.nullFunction);
    1755 * });
    1756 * flow.execute('this should execute last', goog.nullFunction);
    1757 * </pre></code>
    1758 *
    1759 * @private {boolean}
    1760 */
    1761webdriver.promise.Frame_.prototype.isActive_ = false;
    1762
    1763
    1764/**
    1765 * Whether this frame is currently locked. A locked frame represents a callback
    1766 * or task function which has run to completion and scheduled all of its tasks.
    1767 *
    1768 * <p>Once a frame becomes {@link #isActive_ active}, any new frames which are
    1769 * added represent callbacks on a {@link webdriver.promise.Deferred}, whose
    1770 * tasks must be given priority over previously scheduled tasks.
    1771 *
    1772 * @private {boolean}
    1773 */
    1774webdriver.promise.Frame_.prototype.isLocked_ = false;
    1775
    1776
    1777/**
    1778 * A reference to the last node inserted in this frame.
    1779 * @private {webdriver.promise.Node_}
    1780 */
    1781webdriver.promise.Frame_.prototype.lastInsertedChild_ = null;
    1782
    1783
    1784/**
    1785 * Marks all of the tasks that are descendants of this frame in the execution
    1786 * tree as cancelled. This is necessary for callbacks scheduled asynchronous.
    1787 * For example:
    1788 *
    1789 * var someResult;
    1790 * webdriver.promise.createFlow(function(flow) {
    1791 * someResult = flow.execute(function() {});
    1792 * throw Error();
    1793 * }).addErrback(function(err) {
    1794 * console.log('flow failed: ' + err);
    1795 * someResult.then(function() {
    1796 * console.log('task succeeded!');
    1797 * }, function(err) {
    1798 * console.log('task failed! ' + err);
    1799 * });
    1800 * });
    1801 * // flow failed: Error: boom
    1802 * // task failed! CanceledTaskError: Task discarded due to a previous
    1803 * // task failure: Error: boom
    1804 *
    1805 * @param {!webdriver.promise.CanceledTaskError_} error The cancellation
    1806 * error.
    1807 */
    1808webdriver.promise.Frame_.prototype.cancelRemainingTasks = function(error) {
    1809 goog.array.forEach(this.children_, function(child) {
    1810 if (child instanceof webdriver.promise.Frame_) {
    1811 child.cancelRemainingTasks(error);
    1812 } else {
    1813 // None of the previously registered listeners should be notified that
    1814 // the task is being canceled, however, we need at least one errback
    1815 // to prevent the cancellation from bubbling up.
    1816 child.removeAll();
    1817 child.thenCatch(goog.nullFunction);
    1818 child.cancel(error);
    1819 }
    1820 });
    1821};
    1822
    1823
    1824/**
    1825 * @return {webdriver.promise.Task_} The task currently executing
    1826 * within this frame, if any.
    1827 */
    1828webdriver.promise.Frame_.prototype.getPendingTask = function() {
    1829 return this.pendingTask_;
    1830};
    1831
    1832
    1833/**
    1834 * @param {webdriver.promise.Task_} task The task currently
    1835 * executing within this frame, if any.
    1836 */
    1837webdriver.promise.Frame_.prototype.setPendingTask = function(task) {
    1838 this.pendingTask_ = task;
    1839};
    1840
    1841
    1842/** Locks this frame. */
    1843webdriver.promise.Frame_.prototype.lockFrame = function() {
    1844 this.isLocked_ = true;
    1845};
    1846
    1847
    1848/**
    1849 * Adds a new node to this frame.
    1850 * @param {!(webdriver.promise.Frame_|webdriver.promise.Task_)} node
    1851 * The node to insert.
    1852 */
    1853webdriver.promise.Frame_.prototype.addChild = function(node) {
    1854 if (this.lastInsertedChild_ &&
    1855 this.lastInsertedChild_ instanceof webdriver.promise.Frame_ &&
    1856 !this.lastInsertedChild_.isLocked_) {
    1857 this.lastInsertedChild_.addChild(node);
    1858 return;
    1859 }
    1860
    1861 node.setParent(this);
    1862
    1863 if (this.isActive_ && node instanceof webdriver.promise.Frame_) {
    1864 var index = 0;
    1865 if (this.lastInsertedChild_ instanceof
    1866 webdriver.promise.Frame_) {
    1867 index = goog.array.indexOf(this.children_, this.lastInsertedChild_) + 1;
    1868 }
    1869 goog.array.insertAt(this.children_, node, index);
    1870 this.lastInsertedChild_ = node;
    1871 return;
    1872 }
    1873
    1874 this.lastInsertedChild_ = node;
    1875 this.children_.push(node);
    1876};
    1877
    1878
    1879/**
    1880 * @return {(webdriver.promise.Frame_|webdriver.promise.Task_)} This frame's
    1881 * fist child.
    1882 */
    1883webdriver.promise.Frame_.prototype.getFirstChild = function() {
    1884 this.isActive_ = true;
    1885 this.lastInsertedChild_ = null;
    1886 return this.children_[0];
    1887};
    1888
    1889
    1890/**
    1891 * Removes a child from this frame.
    1892 * @param {!(webdriver.promise.Frame_|webdriver.promise.Task_)} child
    1893 * The child to remove.
    1894 */
    1895webdriver.promise.Frame_.prototype.removeChild = function(child) {
    1896 var index = goog.array.indexOf(this.children_, child);
    1897 child.setParent(null);
    1898 goog.array.removeAt(this.children_, index);
    1899 if (this.lastInsertedChild_ === child) {
    1900 this.lastInsertedChild_ = null;
    1901 }
    1902};
    1903
    1904
    1905/** @override */
    1906webdriver.promise.Frame_.prototype.toString = function() {
    1907 return '[' + goog.array.map(this.children_, function(child) {
    1908 return child.toString();
    1909 }).join(', ') + ']';
    1910};
    1911
    1912
    1913
    1914/**
    1915 * A task to be executed by a {@link webdriver.promise.ControlFlow}.
    1916 *
    1917 * @param {!webdriver.promise.ControlFlow} flow The flow this instances belongs
    1918 * to.
    1919 * @param {!Function} fn The function to call when the task executes. If it
    1920 * returns a {@code webdriver.promise.Promise}, the flow will wait
    1921 * for it to be resolved before starting the next task.
    1922 * @param {string} description A description of the task for debugging.
    1923 * @param {!webdriver.stacktrace.Snapshot} snapshot A snapshot of the stack
    1924 * when this task was scheduled.
    1925 * @constructor
    1926 * @extends {webdriver.promise.Node_}
    1927 * @private
    1928 */
    1929webdriver.promise.Task_ = function(flow, fn, description, snapshot) {
    1930 webdriver.promise.Node_.call(this, flow);
    1931
    1932 /**
    1933 * Executes this task.
    1934 * @type {!Function}
    1935 */
    1936 this.execute = fn;
    1937
    1938 /** @private {string} */
    1939 this.description_ = description;
    1940
    1941 /** @private {!webdriver.stacktrace.Snapshot} */
    1942 this.snapshot_ = snapshot;
    1943};
    1944goog.inherits(webdriver.promise.Task_, webdriver.promise.Node_);
    1945
    1946
    1947/** @return {string} This task's description. */
    1948webdriver.promise.Task_.prototype.getDescription = function() {
    1949 return this.description_;
    1950};
    1951
    1952
    1953/** @override */
    1954webdriver.promise.Task_.prototype.toString = function() {
    1955 var stack = this.snapshot_.getStacktrace();
    1956 var ret = this.description_;
    1957 if (stack.length) {
    1958 if (this.description_) {
    1959 ret += '\n';
    1960 }
    1961 ret += stack.join('\n');
    1962 }
    1963 return ret;
    1964};
    1965
    1966
    1967
    1968/**
    1969 * Special error used to signal when a task is canceled because a previous
    1970 * task in the same frame failed.
    1971 * @param {*} err The error that caused the task cancellation.
    1972 * @constructor
    1973 * @extends {goog.debug.Error}
    1974 * @private
    1975 */
    1976webdriver.promise.CanceledTaskError_ = function(err) {
    1977 goog.base(this, 'Task discarded due to a previous task failure: ' + err);
    1978};
    1979goog.inherits(webdriver.promise.CanceledTaskError_, goog.debug.Error);
    1980
    1981
    1982/** @override */
    1983webdriver.promise.CanceledTaskError_.prototype.name = 'CanceledTaskError';
    1984
    1985
    1986
    1987/**
    1988 * The default flow to use if no others are active.
    1989 * @private {!webdriver.promise.ControlFlow}
    1990 */
    1991webdriver.promise.defaultFlow_ = new webdriver.promise.ControlFlow();
    1992
    1993
    1994/**
    1995 * A stack of active control flows, with the top of the stack used to schedule
    1996 * commands. When there are multiple flows on the stack, the flow at index N
    1997 * represents a callback triggered within a task owned by the flow at index
    1998 * N-1.
    1999 * @private {!Array.<!webdriver.promise.ControlFlow>}
    2000 */
    2001webdriver.promise.activeFlows_ = [];
    2002
    2003
    2004/**
    2005 * Changes the default flow to use when no others are active.
    2006 * @param {!webdriver.promise.ControlFlow} flow The new default flow.
    2007 * @throws {Error} If the default flow is not currently active.
    2008 */
    2009webdriver.promise.setDefaultFlow = function(flow) {
    2010 if (webdriver.promise.activeFlows_.length) {
    2011 throw Error('You may only change the default flow while it is active');
    2012 }
    2013 webdriver.promise.defaultFlow_ = flow;
    2014};
    2015
    2016
    2017/**
    2018 * @return {!webdriver.promise.ControlFlow} The currently active control flow.
    2019 */
    2020webdriver.promise.controlFlow = function() {
    2021 return /** @type {!webdriver.promise.ControlFlow} */ (
    2022 goog.array.peek(webdriver.promise.activeFlows_) ||
    2023 webdriver.promise.defaultFlow_);
    2024};
    2025
    2026
    2027/**
    2028 * @param {!webdriver.promise.ControlFlow} flow The new flow.
    2029 * @private
    2030 */
    2031webdriver.promise.pushFlow_ = function(flow) {
    2032 webdriver.promise.activeFlows_.push(flow);
    2033};
    2034
    2035
    2036/** @private */
    2037webdriver.promise.popFlow_ = function() {
    2038 webdriver.promise.activeFlows_.pop();
    2039};
    2040
    2041
    2042/**
    2043 * Creates a new control flow. The provided callback will be invoked as the
    2044 * first task within the new flow, with the flow as its sole argument. Returns
    2045 * a promise that resolves to the callback result.
    2046 * @param {function(!webdriver.promise.ControlFlow)} callback The entry point
    2047 * to the newly created flow.
    2048 * @return {!webdriver.promise.Promise} A promise that resolves to the callback
    2049 * result.
    2050 */
    2051webdriver.promise.createFlow = function(callback) {
    2052 var flow = new webdriver.promise.ControlFlow(
    2053 webdriver.promise.defaultFlow_.timer);
    2054 return flow.execute(function() {
    2055 return callback(flow);
    2056 });
    2057};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/session.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/session.js.src.html new file mode 100644 index 0000000..bc91970 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/session.js.src.html @@ -0,0 +1 @@ +session.js

    lib/webdriver/session.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15goog.provide('webdriver.Session');
    16
    17goog.require('webdriver.Capabilities');
    18
    19
    20
    21/**
    22 * Contains information about a WebDriver session.
    23 * @param {string} id The session ID.
    24 * @param {!(Object|webdriver.Capabilities)} capabilities The session
    25 * capabilities.
    26 * @constructor
    27 */
    28webdriver.Session = function(id, capabilities) {
    29
    30 /** @private {string} */
    31 this.id_ = id;
    32
    33 /** @private {!webdriver.Capabilities} */
    34 this.caps_ = new webdriver.Capabilities().merge(capabilities);
    35};
    36
    37
    38/**
    39 * @return {string} This session's ID.
    40 */
    41webdriver.Session.prototype.getId = function() {
    42 return this.id_;
    43};
    44
    45
    46/**
    47 * @return {!webdriver.Capabilities} This session's capabilities.
    48 */
    49webdriver.Session.prototype.getCapabilities = function() {
    50 return this.caps_;
    51};
    52
    53
    54/**
    55 * Retrieves the value of a specific capability.
    56 * @param {string} key The capability to retrieve.
    57 * @return {*} The capability value.
    58 */
    59webdriver.Session.prototype.getCapability = function(key) {
    60 return this.caps_.get(key);
    61};
    62
    63
    64/**
    65 * Returns the JSON representation of this object, which is just the string
    66 * session ID.
    67 * @return {string} The JSON representation of this Session.
    68 */
    69webdriver.Session.prototype.toJSON = function() {
    70 return this.getId();
    71};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/stacktrace.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/stacktrace.js.src.html new file mode 100644 index 0000000..a36330e --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/stacktrace.js.src.html @@ -0,0 +1 @@ +stacktrace.js

    lib/webdriver/stacktrace.js

    1// Copyright 2009 The Closure Library Authors. All Rights Reserved.
    2// Copyright 2012 Selenium comitters
    3// Copyright 2012 Software Freedom Conservancy
    4//
    5// Licensed under the Apache License, Version 2.0 (the "License");
    6// you may not use this file except in compliance with the License.
    7// You may obtain a copy of the License at
    8//
    9// http://www.apache.org/licenses/LICENSE-2.0
    10//
    11// Unless required by applicable law or agreed to in writing, software
    12// distributed under the License is distributed on an "AS-IS" BASIS,
    13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14// See the License for the specific language governing permissions and
    15// limitations under the License.
    16
    17/**
    18 * @fileoverview Tools for parsing and pretty printing error stack traces. This
    19 * file is based on goog.testing.stacktrace.
    20 */
    21
    22goog.provide('webdriver.stacktrace');
    23goog.provide('webdriver.stacktrace.Snapshot');
    24
    25goog.require('goog.array');
    26goog.require('goog.string');
    27goog.require('goog.userAgent');
    28
    29
    30
    31/**
    32 * Stores a snapshot of the stack trace at the time this instance was created.
    33 * The stack trace will always be adjusted to exclude this function call.
    34 * @param {number=} opt_slice The number of frames to remove from the top of
    35 * the generated stack trace.
    36 * @constructor
    37 */
    38webdriver.stacktrace.Snapshot = function(opt_slice) {
    39
    40 /** @private {number} */
    41 this.slice_ = opt_slice || 0;
    42
    43 var error;
    44 if (webdriver.stacktrace.CAN_CAPTURE_STACK_TRACE_) {
    45 error = Error();
    46 Error.captureStackTrace(error, webdriver.stacktrace.Snapshot);
    47 } else {
    48 // Remove 1 extra frame for the call to this constructor.
    49 this.slice_ += 1;
    50 // IE will only create a stack trace when the Error is thrown.
    51 // We use null.x() to throw an exception instead of throw this.error_
    52 // because the closure compiler may optimize throws to a function call
    53 // in an attempt to minimize the binary size which in turn has the side
    54 // effect of adding an unwanted stack frame.
    55 try {
    56 null.x();
    57 } catch (e) {
    58 error = e;
    59 }
    60 }
    61
    62 /**
    63 * The error's stacktrace. This must be accessed immediately to ensure Opera
    64 * computes the context correctly.
    65 * @private {string}
    66 */
    67 this.stack_ = webdriver.stacktrace.getStack_(error);
    68};
    69
    70
    71/**
    72 * Whether the current environment supports the Error.captureStackTrace
    73 * function (as of 10/17/2012, only V8).
    74 * @private {boolean}
    75 * @const
    76 */
    77webdriver.stacktrace.CAN_CAPTURE_STACK_TRACE_ =
    78 goog.isFunction(Error.captureStackTrace);
    79
    80
    81/**
    82 * Whether the current browser supports stack traces.
    83 *
    84 * @type {boolean}
    85 * @const
    86 */
    87webdriver.stacktrace.BROWSER_SUPPORTED =
    88 webdriver.stacktrace.CAN_CAPTURE_STACK_TRACE_ || (function() {
    89 try {
    90 throw Error();
    91 } catch (e) {
    92 return !!e.stack;
    93 }
    94 })();
    95
    96
    97/**
    98 * The parsed stack trace. This list is lazily generated the first time it is
    99 * accessed.
    100 * @private {Array.<!webdriver.stacktrace.Frame>}
    101 */
    102webdriver.stacktrace.Snapshot.prototype.parsedStack_ = null;
    103
    104
    105/**
    106 * @return {!Array.<!webdriver.stacktrace.Frame>} The parsed stack trace.
    107 */
    108webdriver.stacktrace.Snapshot.prototype.getStacktrace = function() {
    109 if (goog.isNull(this.parsedStack_)) {
    110 this.parsedStack_ = webdriver.stacktrace.parse_(this.stack_);
    111 if (this.slice_) {
    112 this.parsedStack_ = goog.array.slice(this.parsedStack_, this.slice_);
    113 }
    114 delete this.slice_;
    115 delete this.stack_;
    116 }
    117 return this.parsedStack_;
    118};
    119
    120
    121
    122/**
    123 * Class representing one stack frame.
    124 * @param {(string|undefined)} context Context object, empty in case of global
    125 * functions or if the browser doesn't provide this information.
    126 * @param {(string|undefined)} name Function name, empty in case of anonymous
    127 * functions.
    128 * @param {(string|undefined)} alias Alias of the function if available. For
    129 * example the function name will be 'c' and the alias will be 'b' if the
    130 * function is defined as <code>a.b = function c() {};</code>.
    131 * @param {(string|undefined)} path File path or URL including line number and
    132 * optionally column number separated by colons.
    133 * @constructor
    134 */
    135webdriver.stacktrace.Frame = function(context, name, alias, path) {
    136
    137 /** @private {string} */
    138 this.context_ = context || '';
    139
    140 /** @private {string} */
    141 this.name_ = name || '';
    142
    143 /** @private {string} */
    144 this.alias_ = alias || '';
    145
    146 /** @private {string} */
    147 this.path_ = path || '';
    148
    149 /** @private {string} */
    150 this.url_ = this.path_;
    151
    152 /** @private {number} */
    153 this.line_ = -1;
    154
    155 /** @private {number} */
    156 this.column_ = -1;
    157
    158 if (path) {
    159 var match = /:(\d+)(?::(\d+))?$/.exec(path);
    160 if (match) {
    161 this.line_ = Number(match[1]);
    162 this.column = Number(match[2] || -1);
    163 this.url_ = path.substr(0, match.index);
    164 }
    165 }
    166};
    167
    168
    169/**
    170 * Constant for an anonymous frame.
    171 * @private {!webdriver.stacktrace.Frame}
    172 * @const
    173 */
    174webdriver.stacktrace.ANONYMOUS_FRAME_ =
    175 new webdriver.stacktrace.Frame('', '', '', '');
    176
    177
    178/**
    179 * @return {string} The function name or empty string if the function is
    180 * anonymous and the object field which it's assigned to is unknown.
    181 */
    182webdriver.stacktrace.Frame.prototype.getName = function() {
    183 return this.name_;
    184};
    185
    186
    187/**
    188 * @return {string} The url or empty string if it is unknown.
    189 */
    190webdriver.stacktrace.Frame.prototype.getUrl = function() {
    191 return this.url_;
    192};
    193
    194
    195/**
    196 * @return {number} The line number if known or -1 if it is unknown.
    197 */
    198webdriver.stacktrace.Frame.prototype.getLine = function() {
    199 return this.line_;
    200};
    201
    202
    203/**
    204 * @return {number} The column number if known and -1 if it is unknown.
    205 */
    206webdriver.stacktrace.Frame.prototype.getColumn = function() {
    207 return this.column_;
    208};
    209
    210
    211/**
    212 * @return {boolean} Whether the stack frame contains an anonymous function.
    213 */
    214webdriver.stacktrace.Frame.prototype.isAnonymous = function() {
    215 return !this.name_ || this.context_ == '[object Object]';
    216};
    217
    218
    219/**
    220 * Converts this frame to its string representation using V8's stack trace
    221 * format: http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
    222 * @return {string} The string representation of this frame.
    223 * @override
    224 */
    225webdriver.stacktrace.Frame.prototype.toString = function() {
    226 var context = this.context_;
    227 if (context && context !== 'new ') {
    228 context += '.';
    229 }
    230 context += this.name_;
    231 context += this.alias_ ? ' [as ' + this.alias_ + ']' : '';
    232
    233 var path = this.path_ || '<anonymous>';
    234 return ' at ' + (context ? context + ' (' + path + ')' : path);
    235};
    236
    237
    238/**
    239 * Maximum length of a string that can be matched with a RegExp on
    240 * Firefox 3x. Exceeding this approximate length will cause string.match
    241 * to exceed Firefox's stack quota. This situation can be encountered
    242 * when goog.globalEval is invoked with a long argument; such as
    243 * when loading a module.
    244 * @private {number}
    245 * @const
    246 */
    247webdriver.stacktrace.MAX_FIREFOX_FRAMESTRING_LENGTH_ = 500000;
    248
    249
    250/**
    251 * RegExp pattern for JavaScript identifiers. We don't support Unicode
    252 * identifiers defined in ECMAScript v3.
    253 * @private {string}
    254 * @const
    255 */
    256webdriver.stacktrace.IDENTIFIER_PATTERN_ = '[a-zA-Z_$][\\w$]*';
    257
    258
    259/**
    260 * Pattern for a matching the type on a fully-qualified name. Forms an
    261 * optional sub-match on the type. For example, in "foo.bar.baz", will match on
    262 * "foo.bar".
    263 * @private {string}
    264 * @const
    265 */
    266webdriver.stacktrace.CONTEXT_PATTERN_ =
    267 '(' + webdriver.stacktrace.IDENTIFIER_PATTERN_ +
    268 '(?:\\.' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + ')*)\\.';
    269
    270
    271/**
    272 * Pattern for matching a fully qualified name. Will create two sub-matches:
    273 * the type (optional), and the name. For example, in "foo.bar.baz", will
    274 * match on ["foo.bar", "baz"].
    275 * @private {string}
    276 * @const
    277 */
    278webdriver.stacktrace.QUALIFIED_NAME_PATTERN_ =
    279 '(?:' + webdriver.stacktrace.CONTEXT_PATTERN_ + ')?' +
    280 '(' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + ')';
    281
    282
    283/**
    284 * RegExp pattern for function name alias in the V8 stack trace.
    285 * @private {string}
    286 * @const
    287 */
    288webdriver.stacktrace.V8_ALIAS_PATTERN_ =
    289 '(?: \\[as (' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + ')\\])?';
    290
    291
    292/**
    293 * RegExp pattern for function names and constructor calls in the V8 stack
    294 * trace.
    295 * @private {string}
    296 * @const
    297 */
    298webdriver.stacktrace.V8_FUNCTION_NAME_PATTERN_ =
    299 '(?:' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + '|<anonymous>)';
    300
    301
    302/**
    303 * RegExp pattern for the context of a function call in V8. Creates two
    304 * submatches, only one of which will ever match: either the namespace
    305 * identifier (with optional "new" keyword in the case of a constructor call),
    306 * or just the "new " phrase for a top level constructor call.
    307 * @private {string}
    308 * @const
    309 */
    310webdriver.stacktrace.V8_CONTEXT_PATTERN_ =
    311 '(?:((?:new )?(?:\\[object Object\\]|' +
    312 webdriver.stacktrace.IDENTIFIER_PATTERN_ +
    313 '(?:\\.' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + ')*)' +
    314 ')\\.|(new ))';
    315
    316
    317/**
    318 * RegExp pattern for function call in the V8 stack trace.
    319 * Creates 3 submatches with context object (optional), function name and
    320 * function alias (optional).
    321 * @private {string}
    322 * @const
    323 */
    324webdriver.stacktrace.V8_FUNCTION_CALL_PATTERN_ =
    325 ' (?:' + webdriver.stacktrace.V8_CONTEXT_PATTERN_ + ')?' +
    326 '(' + webdriver.stacktrace.V8_FUNCTION_NAME_PATTERN_ + ')' +
    327 webdriver.stacktrace.V8_ALIAS_PATTERN_;
    328
    329
    330/**
    331 * RegExp pattern for an URL + position inside the file.
    332 * @private {string}
    333 * @const
    334 */
    335webdriver.stacktrace.URL_PATTERN_ =
    336 '((?:http|https|file)://[^\\s]+|javascript:.*)';
    337
    338
    339/**
    340 * RegExp pattern for a location string in a V8 stack frame. Creates two
    341 * submatches for the location, one for enclosed in parentheticals and on
    342 * where the location appears alone (which will only occur if the location is
    343 * the only information in the frame).
    344 * @private {string}
    345 * @const
    346 * @see http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
    347 */
    348webdriver.stacktrace.V8_LOCATION_PATTERN_ = ' (?:\\((.*)\\)|(.*))';
    349
    350
    351/**
    352 * Regular expression for parsing one stack frame in V8.
    353 * @private {!RegExp}
    354 * @const
    355 */
    356webdriver.stacktrace.V8_STACK_FRAME_REGEXP_ = new RegExp('^ at' +
    357 '(?:' + webdriver.stacktrace.V8_FUNCTION_CALL_PATTERN_ + ')?' +
    358 webdriver.stacktrace.V8_LOCATION_PATTERN_ + '$');
    359
    360
    361/**
    362 * RegExp pattern for function names in the Firefox stack trace.
    363 * Firefox has extended identifiers to deal with inner functions and anonymous
    364 * functions: https://bugzilla.mozilla.org/show_bug.cgi?id=433529#c9
    365 * @private {string}
    366 * @const
    367 */
    368webdriver.stacktrace.FIREFOX_FUNCTION_NAME_PATTERN_ =
    369 webdriver.stacktrace.IDENTIFIER_PATTERN_ + '[\\w./<$]*';
    370
    371
    372/**
    373 * RegExp pattern for function call in the Firefox stack trace.
    374 * Creates a submatch for the function name.
    375 * @private {string}
    376 * @const
    377 */
    378webdriver.stacktrace.FIREFOX_FUNCTION_CALL_PATTERN_ =
    379 '(' + webdriver.stacktrace.FIREFOX_FUNCTION_NAME_PATTERN_ + ')?' +
    380 '(?:\\(.*\\))?@';
    381
    382
    383/**
    384 * Regular expression for parsing one stack frame in Firefox.
    385 * @private {!RegExp}
    386 * @const
    387 */
    388webdriver.stacktrace.FIREFOX_STACK_FRAME_REGEXP_ = new RegExp('^' +
    389 webdriver.stacktrace.FIREFOX_FUNCTION_CALL_PATTERN_ +
    390 '(?::0|' + webdriver.stacktrace.URL_PATTERN_ + ')$');
    391
    392
    393/**
    394 * RegExp pattern for an anonymous function call in an Opera stack frame.
    395 * Creates 2 (optional) submatches: the context object and function name.
    396 * @private {string}
    397 * @const
    398 */
    399webdriver.stacktrace.OPERA_ANONYMOUS_FUNCTION_NAME_PATTERN_ =
    400 '<anonymous function(?:\\: ' +
    401 webdriver.stacktrace.QUALIFIED_NAME_PATTERN_ + ')?>';
    402
    403
    404/**
    405 * RegExp pattern for a function call in an Opera stack frame.
    406 * Creates 3 (optional) submatches: the function name (if not anonymous),
    407 * the aliased context object and the function name (if anonymous).
    408 * @private {string}
    409 * @const
    410 */
    411webdriver.stacktrace.OPERA_FUNCTION_CALL_PATTERN_ =
    412 '(?:(?:(' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + ')|' +
    413 webdriver.stacktrace.OPERA_ANONYMOUS_FUNCTION_NAME_PATTERN_ +
    414 ')(?:\\(.*\\)))?@';
    415
    416
    417/**
    418 * Regular expression for parsing on stack frame in Opera 11.68+
    419 * @private {!RegExp}
    420 * @const
    421 */
    422webdriver.stacktrace.OPERA_STACK_FRAME_REGEXP_ = new RegExp('^' +
    423 webdriver.stacktrace.OPERA_FUNCTION_CALL_PATTERN_ +
    424 webdriver.stacktrace.URL_PATTERN_ + '?$');
    425
    426
    427/**
    428 * RegExp pattern for function call in a Chakra (IE) stack trace. This
    429 * expression allows for identifiers like 'Anonymous function', 'eval code',
    430 * and 'Global code'.
    431 * @private {string}
    432 * @const
    433 */
    434webdriver.stacktrace.CHAKRA_FUNCTION_CALL_PATTERN_ = '(' +
    435 webdriver.stacktrace.IDENTIFIER_PATTERN_ + '(?:\\s+\\w+)*)';
    436
    437
    438/**
    439 * Regular expression for parsing on stack frame in Chakra (IE).
    440 * @private {!RegExp}
    441 * @const
    442 */
    443webdriver.stacktrace.CHAKRA_STACK_FRAME_REGEXP_ = new RegExp('^ at ' +
    444 webdriver.stacktrace.CHAKRA_FUNCTION_CALL_PATTERN_ +
    445 '\\s*(?:\\((.*)\\))$');
    446
    447
    448/**
    449 * Placeholder for an unparsable frame in a stack trace generated by
    450 * {@link goog.testing.stacktrace}.
    451 * @private {string}
    452 * @const
    453 */
    454webdriver.stacktrace.UNKNOWN_CLOSURE_FRAME_ = '> (unknown)';
    455
    456
    457/**
    458 * Representation of an anonymous frame in a stack trace generated by
    459 * {@link goog.testing.stacktrace}.
    460 * @private {string}
    461 * @const
    462 */
    463webdriver.stacktrace.ANONYMOUS_CLOSURE_FRAME_ = '> anonymous';
    464
    465
    466/**
    467 * Pattern for a function call in a Closure stack trace. Creates three optional
    468 * submatches: the context, function name, and alias.
    469 * @private {string}
    470 * @const
    471 */
    472webdriver.stacktrace.CLOSURE_FUNCTION_CALL_PATTERN_ =
    473 webdriver.stacktrace.QUALIFIED_NAME_PATTERN_ +
    474 '(?:\\(.*\\))?' + // Ignore arguments if present.
    475 webdriver.stacktrace.V8_ALIAS_PATTERN_;
    476
    477
    478/**
    479 * Regular expression for parsing a stack frame generated by Closure's
    480 * {@link goog.testing.stacktrace}.
    481 * @private {!RegExp}
    482 * @const
    483 */
    484webdriver.stacktrace.CLOSURE_STACK_FRAME_REGEXP_ = new RegExp('^> ' +
    485 '(?:' + webdriver.stacktrace.CLOSURE_FUNCTION_CALL_PATTERN_ +
    486 '(?: at )?)?' +
    487 '(?:(.*:\\d+:\\d+)|' + webdriver.stacktrace.URL_PATTERN_ + ')?$');
    488
    489
    490/**
    491 * Parses one stack frame.
    492 * @param {string} frameStr The stack frame as string.
    493 * @return {webdriver.stacktrace.Frame} Stack frame object or null if the
    494 * parsing failed.
    495 * @private
    496 */
    497webdriver.stacktrace.parseStackFrame_ = function(frameStr) {
    498 var m = frameStr.match(webdriver.stacktrace.V8_STACK_FRAME_REGEXP_);
    499 if (m) {
    500 return new webdriver.stacktrace.Frame(
    501 m[1] || m[2], m[3], m[4], m[5] || m[6]);
    502 }
    503
    504 if (frameStr.length >
    505 webdriver.stacktrace.MAX_FIREFOX_FRAMESTRING_LENGTH_) {
    506 return webdriver.stacktrace.parseLongFirefoxFrame_(frameStr);
    507 }
    508
    509 m = frameStr.match(webdriver.stacktrace.FIREFOX_STACK_FRAME_REGEXP_);
    510 if (m) {
    511 return new webdriver.stacktrace.Frame('', m[1], '', m[2]);
    512 }
    513
    514 m = frameStr.match(webdriver.stacktrace.OPERA_STACK_FRAME_REGEXP_);
    515 if (m) {
    516 return new webdriver.stacktrace.Frame(m[2], m[1] || m[3], '', m[4]);
    517 }
    518
    519 m = frameStr.match(webdriver.stacktrace.CHAKRA_STACK_FRAME_REGEXP_);
    520 if (m) {
    521 return new webdriver.stacktrace.Frame('', m[1], '', m[2]);
    522 }
    523
    524 if (frameStr == webdriver.stacktrace.UNKNOWN_CLOSURE_FRAME_ ||
    525 frameStr == webdriver.stacktrace.ANONYMOUS_CLOSURE_FRAME_) {
    526 return webdriver.stacktrace.ANONYMOUS_FRAME_;
    527 }
    528
    529 m = frameStr.match(webdriver.stacktrace.CLOSURE_STACK_FRAME_REGEXP_);
    530 if (m) {
    531 return new webdriver.stacktrace.Frame(m[1], m[2], m[3], m[4] || m[5]);
    532 }
    533
    534 return null;
    535};
    536
    537
    538/**
    539 * Parses a long firefox stack frame.
    540 * @param {string} frameStr The stack frame as string.
    541 * @return {!webdriver.stacktrace.Frame} Stack frame object.
    542 * @private
    543 */
    544webdriver.stacktrace.parseLongFirefoxFrame_ = function(frameStr) {
    545 var firstParen = frameStr.indexOf('(');
    546 var lastAmpersand = frameStr.lastIndexOf('@');
    547 var lastColon = frameStr.lastIndexOf(':');
    548 var functionName = '';
    549 if ((firstParen >= 0) && (firstParen < lastAmpersand)) {
    550 functionName = frameStr.substring(0, firstParen);
    551 }
    552 var loc = '';
    553 if ((lastAmpersand >= 0) && (lastAmpersand + 1 < lastColon)) {
    554 loc = frameStr.substring(lastAmpersand + 1);
    555 }
    556 return new webdriver.stacktrace.Frame('', functionName, '', loc);
    557};
    558
    559
    560/**
    561 * Get an error's stack trace with the error string trimmed.
    562 * V8 prepends the string representation of an error to its stack trace.
    563 * This function trims the string so that the stack trace can be parsed
    564 * consistently with the other JS engines.
    565 * @param {(Error|goog.testing.JsUnitException)} error The error.
    566 * @return {string} The stack trace string.
    567 * @private
    568 */
    569webdriver.stacktrace.getStack_ = function(error) {
    570 if (!error) {
    571 return '';
    572 }
    573 var stack = error.stack || error.stackTrace || '';
    574 var errorStr = error + '\n';
    575 if (goog.string.startsWith(stack, errorStr)) {
    576 stack = stack.substring(errorStr.length);
    577 }
    578 return stack;
    579};
    580
    581
    582/**
    583 * Formats an error's stack trace.
    584 * @param {!(Error|goog.testing.JsUnitException)} error The error to format.
    585 * @return {!(Error|goog.testing.JsUnitException)} The formatted error.
    586 */
    587webdriver.stacktrace.format = function(error) {
    588 var stack = webdriver.stacktrace.getStack_(error);
    589 var frames = webdriver.stacktrace.parse_(stack);
    590
    591 // Older versions of IE simply return [object Error] for toString(), so
    592 // only use that as a last resort.
    593 var errorStr = '';
    594 if (error.message) {
    595 errorStr = (error.name ? error.name + ': ' : '') + error.message;
    596 } else {
    597 errorStr = error.toString();
    598 }
    599
    600 // Ensure the error is in the V8 style with the error's string representation
    601 // prepended to the stack.
    602 error.stack = errorStr + '\n' + frames.join('\n');
    603 return error;
    604};
    605
    606
    607/**
    608 * Parses an Error object's stack trace.
    609 * @param {string} stack The stack trace.
    610 * @return {!Array.<!webdriver.stacktrace.Frame>} Stack frames. The
    611 * unrecognized frames will be nulled out.
    612 * @private
    613 */
    614webdriver.stacktrace.parse_ = function(stack) {
    615 if (!stack) {
    616 return [];
    617 }
    618
    619 var lines = stack.
    620 replace(/\s*$/, '').
    621 split('\n');
    622 var frames = [];
    623 for (var i = 0; i < lines.length; i++) {
    624 var frame = webdriver.stacktrace.parseStackFrame_(lines[i]);
    625 // The first two frames will be:
    626 // webdriver.stacktrace.Snapshot()
    627 // webdriver.stacktrace.get()
    628 // In the case of Opera, sometimes an extra frame is injected in the next
    629 // frame with a reported line number of zero. The next line detects that
    630 // case and skips that frame.
    631 if (!(goog.userAgent.OPERA && i == 2 && frame.getLine() == 0)) {
    632 frames.push(frame || webdriver.stacktrace.ANONYMOUS_FRAME_);
    633 }
    634 }
    635 return frames;
    636};
    637
    638
    639/**
    640 * Gets the native stack trace if available otherwise follows the call chain.
    641 * The generated trace will exclude all frames up to and including the call to
    642 * this function.
    643 * @return {!Array.<!webdriver.stacktrace.Frame>} The frames of the stack trace.
    644 */
    645webdriver.stacktrace.get = function() {
    646 return new webdriver.stacktrace.Snapshot(1).getStacktrace();
    647};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/testing/asserts.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/testing/asserts.js.src.html new file mode 100644 index 0000000..5d37bbd --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/testing/asserts.js.src.html @@ -0,0 +1 @@ +asserts.js

    lib/webdriver/testing/asserts.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Assertions and expectation utilities for use in WebDriver test
    17 * cases.
    18 */
    19
    20goog.provide('webdriver.testing.Assertion');
    21goog.provide('webdriver.testing.ContainsMatcher');
    22goog.provide('webdriver.testing.NegatedAssertion');
    23goog.provide('webdriver.testing.assert');
    24goog.provide('webdriver.testing.asserts');
    25
    26goog.require('goog.array');
    27goog.require('goog.labs.testing.CloseToMatcher');
    28goog.require('goog.labs.testing.EndsWithMatcher');
    29goog.require('goog.labs.testing.EqualToMatcher');
    30goog.require('goog.labs.testing.EqualsMatcher');
    31goog.require('goog.labs.testing.GreaterThanEqualToMatcher');
    32goog.require('goog.labs.testing.GreaterThanMatcher');
    33goog.require('goog.labs.testing.LessThanEqualToMatcher');
    34goog.require('goog.labs.testing.LessThanMatcher');
    35goog.require('goog.labs.testing.InstanceOfMatcher');
    36goog.require('goog.labs.testing.IsNotMatcher');
    37goog.require('goog.labs.testing.IsNullMatcher');
    38goog.require('goog.labs.testing.IsNullOrUndefinedMatcher');
    39goog.require('goog.labs.testing.IsUndefinedMatcher');
    40goog.require('goog.labs.testing.Matcher');
    41goog.require('goog.labs.testing.ObjectEqualsMatcher');
    42goog.require('goog.labs.testing.RegexMatcher');
    43goog.require('goog.labs.testing.StartsWithMatcher');
    44goog.require('goog.labs.testing.assertThat');
    45goog.require('goog.string');
    46goog.require('webdriver.promise');
    47
    48
    49/**
    50 * Accepts strins or array-like structures that contain {@code value}.
    51 * @param {*} value The value to check for.
    52 * @constructor
    53 * @implements {goog.labs.testing.Matcher}
    54 */
    55webdriver.testing.ContainsMatcher = function(value) {
    56 /** @private {*} */
    57 this.value_ = value;
    58};
    59
    60
    61/** @override */
    62webdriver.testing.ContainsMatcher.prototype.matches = function(actualValue) {
    63 if (goog.isString(actualValue)) {
    64 return goog.string.contains(
    65 actualValue, /** @type {string} */(this.value_));
    66 } else {
    67 return goog.array.contains(
    68 /** @type {goog.array.ArrayLike} */(actualValue), this.value_);
    69 }
    70};
    71
    72
    73/** @override */
    74webdriver.testing.ContainsMatcher.prototype.describe = function(actualValue) {
    75 return actualValue + ' does not contain ' + this.value_;
    76};
    77
    78
    79
    80/**
    81 * Utility for performing assertions against a given {@code value}. If the
    82 * value is a {@link webdriver.promise.Promise}, this assertion will wait
    83 * for it to resolve before applying any matchers.
    84 * @param {*} value The value to wrap and apply matchers to.
    85 * @constructor
    86 */
    87webdriver.testing.Assertion = function(value) {
    88
    89 /** @private {*} */
    90 this.value_ = value;
    91
    92 if (!(this instanceof webdriver.testing.NegatedAssertion)) {
    93 /**
    94 * A self reference provided for writing fluent assertions:
    95 * webdriver.testing.assert(x).is.equalTo(y);
    96 * @type {!webdriver.testing.Assertion}
    97 */
    98 this.is = this;
    99
    100 /**
    101 * Negates any matchers applied to this instance's value:
    102 * webdriver.testing.assert(x).not.equalTo(y);
    103 * @type {!webdriver.testing.NegatedAssertion}
    104 */
    105 this.not = new webdriver.testing.NegatedAssertion(value);
    106 }
    107};
    108
    109
    110/**
    111 * Wraps an object literal implementing the Matcher interface. This is used
    112 * to appease the Closure compiler, which will not treat an object literal as
    113 * implementing an interface.
    114 * @param {{matches: function(*): boolean, describe: function(): string}} obj
    115 * The object literal to delegate to.
    116 * @constructor
    117 * @implements {goog.labs.testing.Matcher}
    118 * @private
    119 */
    120webdriver.testing.Assertion.DelegatingMatcher_ = function(obj) {
    121
    122 /** @override */
    123 this.matches = function(value) {
    124 return obj.matches(value);
    125 };
    126
    127 /** @override */
    128 this.describe = function() {
    129 return obj.describe();
    130 };
    131};
    132
    133
    134/**
    135 * Asserts that the given {@code matcher} accepts the value wrapped by this
    136 * instance. If the wrapped value is a promise, this function will defer
    137 * applying the assertion until the value has been resolved. Otherwise, it
    138 * will be applied immediately.
    139 * @param {!goog.labs.testing.Matcher} matcher The matcher to apply
    140 * @param {string=} opt_message A message to include if the matcher does not
    141 * accept the value wrapped by this assertion.
    142 * @return {webdriver.promise.Promise} The deferred assertion result, or
    143 * {@code null} if the assertion was immediately applied.
    144 * @protected
    145 */
    146webdriver.testing.Assertion.prototype.apply = function(matcher, opt_message) {
    147 var result = null;
    148 if (webdriver.promise.isPromise(this.value_)) {
    149 result = webdriver.promise.when(this.value_, function(value) {
    150 goog.labs.testing.assertThat(value, matcher, opt_message);
    151 });
    152 } else {
    153 goog.labs.testing.assertThat(this.value_, matcher, opt_message);
    154 }
    155 return result;
    156};
    157
    158
    159/**
    160 * Asserts that the value managed by this assertion is a number strictly
    161 * greater than {@code value}.
    162 * @param {number} value The minimum value.
    163 * @param {string=} opt_message A message to include if the matcher does not
    164 * accept the value wrapped by this assertion.
    165 * @return {webdriver.promise.Promise} The assertion result.
    166 */
    167webdriver.testing.Assertion.prototype.greaterThan = function(
    168 value, opt_message) {
    169 return this.apply(
    170 new goog.labs.testing.GreaterThanMatcher(value), opt_message);
    171};
    172
    173
    174/**
    175 * Asserts that the value managed by this assertion is a number >= the given
    176 * value.
    177 * @param {number} value The minimum value.
    178 * @param {string=} opt_message A message to include if the matcher does not
    179 * accept the value wrapped by this assertion.
    180 * @return {webdriver.promise.Promise} The assertion result.
    181 */
    182webdriver.testing.Assertion.prototype.greaterThanEqualTo = function(
    183 value, opt_message) {
    184 return this.apply(
    185 new goog.labs.testing.GreaterThanEqualToMatcher(value), opt_message);
    186};
    187
    188
    189/**
    190 * Asserts that the value managed by this assertion is a number strictly less
    191 * than the given value.
    192 * @param {number} value The maximum value.
    193 * @param {string=} opt_message A message to include if the matcher does not
    194 * accept the value wrapped by this assertion.
    195 * @return {webdriver.promise.Promise} The assertion result.
    196 */
    197webdriver.testing.Assertion.prototype.lessThan = function(value, opt_message) {
    198 return this.apply(
    199 new goog.labs.testing.LessThanMatcher(value), opt_message);
    200};
    201
    202
    203/**
    204 * Asserts that the value managed by this assertion is a number <= the given
    205 * value.
    206 * @param {number} value The maximum value.
    207 * @param {string=} opt_message A message to include if the matcher does not
    208 * accept the value wrapped by this assertion.
    209 * @return {webdriver.promise.Promise} The assertion result.
    210 */
    211webdriver.testing.Assertion.prototype.lessThanEqualTo = function(
    212 value, opt_message) {
    213 return this.apply(
    214 new goog.labs.testing.LessThanEqualToMatcher(value), opt_message);
    215};
    216
    217
    218/**
    219 * Asserts that the wrapped value is a number within a given distance of an
    220 * expected value.
    221 * @param {number} value The expected value.
    222 * @param {number} range The maximum amount the actual value is permitted to
    223 * differ from the expected value.
    224 * @param {string=} opt_message A message to include if the matcher does not
    225 * accept the value wrapped by this assertion.
    226 * @return {webdriver.promise.Promise} The assertion result.
    227 */
    228webdriver.testing.Assertion.prototype.closeTo = function(
    229 value, range, opt_message) {
    230 return this.apply(
    231 new goog.labs.testing.CloseToMatcher(value, range), opt_message);
    232};
    233
    234
    235/**
    236 * Asserts that the wrapped value is an instance of the given class.
    237 * @param {!Function} ctor The expected class constructor.
    238 * @param {string=} opt_message A message to include if the matcher does not
    239 * accept the value wrapped by this assertion.
    240 * @return {webdriver.promise.Promise} The assertion result.
    241 */
    242webdriver.testing.Assertion.prototype.instanceOf = function(ctor, opt_message) {
    243 return this.apply(
    244 new goog.labs.testing.InstanceOfMatcher(ctor), opt_message);
    245};
    246
    247
    248/**
    249 * Asserts that the wrapped value is null.
    250 * @param {string=} opt_message A message to include if the matcher does not
    251 * accept the value wrapped by this assertion.
    252 * @return {webdriver.promise.Promise} The assertion result.
    253 */
    254webdriver.testing.Assertion.prototype.isNull = function(opt_message) {
    255 return this.apply(new goog.labs.testing.IsNullMatcher(), opt_message);
    256};
    257
    258
    259/**
    260 * Asserts that the wrapped value is undefined.
    261 * @param {string=} opt_message A message to include if the matcher does not
    262 * accept the value wrapped by this assertion.
    263 * @return {webdriver.promise.Promise} The assertion result.
    264 */
    265webdriver.testing.Assertion.prototype.isUndefined = function(opt_message) {
    266 return this.apply(new goog.labs.testing.IsUndefinedMatcher(), opt_message);
    267};
    268
    269
    270/**
    271 * Asserts that the wrapped value is null or undefined.
    272 * @param {string=} opt_message A message to include if the matcher does not
    273 * accept the value wrapped by this assertion.
    274 * @return {webdriver.promise.Promise} The assertion result.
    275 */
    276webdriver.testing.Assertion.prototype.isNullOrUndefined = function(
    277 opt_message) {
    278 return this.apply(
    279 new goog.labs.testing.IsNullOrUndefinedMatcher(), opt_message);
    280};
    281
    282
    283/**
    284 * Asserts that the wrapped value is a string or array-like structure
    285 * containing the given value.
    286 * @param {*} value The expected value.
    287 * @param {string=} opt_message A message to include if the matcher does not
    288 * accept the value wrapped by this assertion.
    289 * @return {webdriver.promise.Promise} The assertion result.
    290 */
    291webdriver.testing.Assertion.prototype.contains = function(value, opt_message) {
    292 return this.apply(
    293 new webdriver.testing.ContainsMatcher(value), opt_message);
    294};
    295
    296
    297/**
    298 * Asserts that the wrapped value is a string ending with the given suffix.
    299 * @param {string} suffix The expected suffix.
    300 * @param {string=} opt_message A message to include if the matcher does not
    301 * accept the value wrapped by this assertion.
    302 * @return {webdriver.promise.Promise} The assertion result.
    303 */
    304webdriver.testing.Assertion.prototype.endsWith = function(
    305 suffix, opt_message) {
    306 return this.apply(
    307 new goog.labs.testing.EndsWithMatcher(suffix), opt_message);
    308};
    309
    310
    311/**
    312 * Asserts that the wrapped value is a string starting with the given prefix.
    313 * @param {string} prefix The expected prefix.
    314 * @param {string=} opt_message A message to include if the matcher does not
    315 * accept the value wrapped by this assertion.
    316 * @return {webdriver.promise.Promise} The assertion result.
    317 */
    318webdriver.testing.Assertion.prototype.startsWith = function(
    319 prefix, opt_message) {
    320 return this.apply(
    321 new goog.labs.testing.StartsWithMatcher(prefix), opt_message);
    322};
    323
    324
    325/**
    326 * Asserts that the wrapped value is a string that matches the given RegExp.
    327 * @param {!RegExp} regex The regex to test.
    328 * @param {string=} opt_message A message to include if the matcher does not
    329 * accept the value wrapped by this assertion.
    330 * @return {webdriver.promise.Promise} The assertion result.
    331 */
    332webdriver.testing.Assertion.prototype.matches = function(regex, opt_message) {
    333 return this.apply(new goog.labs.testing.RegexMatcher(regex), opt_message);
    334};
    335
    336
    337/**
    338 * Asserts that the value managed by this assertion is strictly equal to the
    339 * given {@code value}.
    340 * @param {*} value The expected value.
    341 * @param {string=} opt_message A message to include if the matcher does not
    342 * accept the value wrapped by this assertion.
    343 * @return {webdriver.promise.Promise} The assertion result.
    344 */
    345webdriver.testing.Assertion.prototype.equalTo = function(value, opt_message) {
    346 return this.apply(webdriver.testing.asserts.equalTo(value), opt_message);
    347};
    348
    349
    350/**
    351 * Asserts that the value managed by this assertion is strictly true.
    352 * @return {webdriver.promise.Promise} The assertion result.
    353 */
    354webdriver.testing.Assertion.prototype.isTrue = function() {
    355 return this.equalTo(true);
    356};
    357
    358
    359/**
    360 * Asserts that the value managed by this assertion is strictly false.
    361 * @return {webdriver.promise.Promise} The assertion result.
    362 */
    363webdriver.testing.Assertion.prototype.isFalse = function() {
    364 return this.equalTo(false);
    365};
    366
    367
    368
    369/**
    370 * An assertion that negates any applied matchers.
    371 * @param {*} value The value to perform assertions on.
    372 * @constructor
    373 * @extends {webdriver.testing.Assertion}
    374 */
    375webdriver.testing.NegatedAssertion = function(value) {
    376 goog.base(this, value);
    377 this.value = value;
    378};
    379goog.inherits(
    380 webdriver.testing.NegatedAssertion, webdriver.testing.Assertion);
    381
    382
    383/** @override */
    384webdriver.testing.NegatedAssertion.prototype.apply = function(
    385 matcher, opt_message) {
    386 matcher = new goog.labs.testing.IsNotMatcher(matcher);
    387 return goog.base(this, 'apply', matcher, opt_message);
    388};
    389
    390
    391
    392/**
    393 * Creates a new assertion.
    394 * @param {*} value The value to perform an assertion on.
    395 * @return {!webdriver.testing.Assertion} The new assertion.
    396 */
    397webdriver.testing.assert = function(value) {
    398 return new webdriver.testing.Assertion(value);
    399};
    400
    401
    402/**
    403 * Registers a new assertion to expose from the
    404 * {@link webdriver.testing.Assertion} prototype.
    405 * @param {string} name The assertion name.
    406 * @param {(function(new: goog.labs.testing.Matcher, *)|
    407 * {matches: function(*): boolean,
    408 * describe: function(): string})} matcherTemplate Either the
    409 * matcher constructor to use, or an object literal defining a matcher.
    410 */
    411webdriver.testing.assert.register = function(name, matcherTemplate) {
    412 webdriver.testing.Assertion.prototype[name] = function(value, opt_message) {
    413 var matcher;
    414 if (goog.isFunction(matcherTemplate)) {
    415 var ctor = /** @type {function(new: goog.labs.testing.Matcher, *)} */ (
    416 matcherTemplate);
    417 matcher = new ctor(value);
    418 } else {
    419 matcher = new webdriver.testing.Assertion.DelegatingMatcher_(value);
    420 }
    421 return this.apply(matcher, opt_message);
    422 };
    423};
    424
    425
    426/**
    427 * Asserts that a matcher accepts a given value. This function has two
    428 * signatures based on the number of arguments:
    429 *
    430 * Two arguments:
    431 * assertThat(actualValue, matcher)
    432 * Three arguments:
    433 * assertThat(failureMessage, actualValue, matcher)
    434 *
    435 * @param {*} failureMessageOrActualValue Either a failure message or the value
    436 * to apply to the given matcher.
    437 * @param {*} actualValueOrMatcher Either the value to apply to the given
    438 * matcher, or the matcher itself.
    439 * @param {goog.labs.testing.Matcher=} opt_matcher The matcher to use;
    440 * ignored unless this function is invoked with three arguments.
    441 * @return {!webdriver.promise.Promise} The assertion result.
    442 * @deprecated Use webdriver.testing.asserts.assert instead.
    443 */
    444webdriver.testing.asserts.assertThat = function(
    445 failureMessageOrActualValue, actualValueOrMatcher, opt_matcher) {
    446 var args = goog.array.slice(arguments, 0);
    447
    448 var message = args.length > 2 ? args.shift() : '';
    449 if (message) message += '\n';
    450
    451 var actualValue = args.shift();
    452 var matcher = args.shift();
    453
    454 return webdriver.promise.when(actualValue, function(value) {
    455 goog.labs.testing.assertThat(value, matcher, message);
    456 });
    457};
    458
    459
    460/**
    461 * Creates an equality matcher.
    462 * @param {*} expected The expected value.
    463 * @return {!goog.labs.testing.Matcher} The new matcher.
    464 */
    465webdriver.testing.asserts.equalTo = function(expected) {
    466 if (goog.isString(expected)) {
    467 return new goog.labs.testing.EqualsMatcher(expected);
    468 } else if (goog.isNumber(expected)) {
    469 return new goog.labs.testing.EqualToMatcher(expected);
    470 } else {
    471 return new goog.labs.testing.ObjectEqualsMatcher(
    472 /** @type {!Object} */ (expected));
    473 }
    474};
    475
    476
    477goog.exportSymbol('assertThat', webdriver.testing.asserts.assertThat);
    478// Mappings for goog.labs.testing matcher functions to the legacy
    479// webdriver.testing.asserts matchers.
    480goog.exportSymbol('contains', containsString);
    481goog.exportSymbol('equalTo', webdriver.testing.asserts.equalTo);
    482goog.exportSymbol('equals', webdriver.testing.asserts.equalTo);
    483goog.exportSymbol('is', webdriver.testing.asserts.equalTo);
    484goog.exportSymbol('not', isNot);
    485goog.exportSymbol('or', anyOf);
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/lib/webdriver/webdriver.js.src.html b/node_modules/selenium-webdriver/docs/source/lib/webdriver/webdriver.js.src.html new file mode 100644 index 0000000..d041966 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/lib/webdriver/webdriver.js.src.html @@ -0,0 +1 @@ +webdriver.js

    lib/webdriver/webdriver.js

    1// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview The heart of the WebDriver JavaScript API.
    17 */
    18
    19goog.provide('webdriver.Alert');
    20goog.provide('webdriver.UnhandledAlertError');
    21goog.provide('webdriver.WebDriver');
    22goog.provide('webdriver.WebElement');
    23
    24goog.require('bot.Error');
    25goog.require('bot.ErrorCode');
    26goog.require('bot.response');
    27goog.require('goog.array');
    28goog.require('goog.object');
    29goog.require('webdriver.ActionSequence');
    30goog.require('webdriver.Command');
    31goog.require('webdriver.CommandName');
    32goog.require('webdriver.Key');
    33goog.require('webdriver.Locator');
    34goog.require('webdriver.Session');
    35goog.require('webdriver.logging');
    36goog.require('webdriver.promise');
    37
    38
    39//////////////////////////////////////////////////////////////////////////////
    40//
    41// webdriver.WebDriver
    42//
    43//////////////////////////////////////////////////////////////////////////////
    44
    45
    46
    47/**
    48 * Creates a new WebDriver client, which provides control over a browser.
    49 *
    50 * Every WebDriver command returns a {@code webdriver.promise.Promise} that
    51 * represents the result of that command. Callbacks may be registered on this
    52 * object to manipulate the command result or catch an expected error. Any
    53 * commands scheduled with a callback are considered sub-commands and will
    54 * execute before the next command in the current frame. For example:
    55 * <pre><code>
    56 * var message = [];
    57 * driver.call(message.push, message, 'a').then(function() {
    58 * driver.call(message.push, message, 'b');
    59 * });
    60 * driver.call(message.push, message, 'c');
    61 * driver.call(function() {
    62 * alert('message is abc? ' + (message.join('') == 'abc'));
    63 * });
    64 * </code></pre>
    65 *
    66 * @param {!(webdriver.Session|webdriver.promise.Promise)} session Either a
    67 * known session or a promise that will be resolved to a session.
    68 * @param {!webdriver.CommandExecutor} executor The executor to use when
    69 * sending commands to the browser.
    70 * @param {webdriver.promise.ControlFlow=} opt_flow The flow to
    71 * schedule commands through. Defaults to the active flow object.
    72 * @constructor
    73 */
    74webdriver.WebDriver = function(session, executor, opt_flow) {
    75
    76 /** @private {!(webdriver.Session|webdriver.promise.Promise)} */
    77 this.session_ = session;
    78
    79 /** @private {!webdriver.CommandExecutor} */
    80 this.executor_ = executor;
    81
    82 /** @private {!webdriver.promise.ControlFlow} */
    83 this.flow_ = opt_flow || webdriver.promise.controlFlow();
    84};
    85
    86
    87/**
    88 * Creates a new WebDriver client for an existing session.
    89 * @param {!webdriver.CommandExecutor} executor Command executor to use when
    90 * querying for session details.
    91 * @param {string} sessionId ID of the session to attach to.
    92 * @return {!webdriver.WebDriver} A new client for the specified session.
    93 */
    94webdriver.WebDriver.attachToSession = function(executor, sessionId) {
    95 return webdriver.WebDriver.acquireSession_(executor,
    96 new webdriver.Command(webdriver.CommandName.DESCRIBE_SESSION).
    97 setParameter('sessionId', sessionId),
    98 'WebDriver.attachToSession()');
    99};
    100
    101
    102/**
    103 * Creates a new WebDriver session.
    104 * @param {!webdriver.CommandExecutor} executor The executor to create the new
    105 * session with.
    106 * @param {!webdriver.Capabilities} desiredCapabilities The desired
    107 * capabilities for the new session.
    108 * @return {!webdriver.WebDriver} The driver for the newly created session.
    109 */
    110webdriver.WebDriver.createSession = function(executor, desiredCapabilities) {
    111 return webdriver.WebDriver.acquireSession_(executor,
    112 new webdriver.Command(webdriver.CommandName.NEW_SESSION).
    113 setParameter('desiredCapabilities', desiredCapabilities),
    114 'WebDriver.createSession()');
    115};
    116
    117
    118/**
    119 * Sends a command to the server that is expected to return the details for a
    120 * {@link webdriver.Session}. This may either be an existing session, or a
    121 * newly created one.
    122 * @param {!webdriver.CommandExecutor} executor Command executor to use when
    123 * querying for session details.
    124 * @param {!webdriver.Command} command The command to send to fetch the session
    125 * details.
    126 * @param {string} description A descriptive debug label for this action.
    127 * @return {!webdriver.WebDriver} A new WebDriver client for the session.
    128 * @private
    129 */
    130webdriver.WebDriver.acquireSession_ = function(executor, command, description) {
    131 var session = webdriver.promise.controlFlow().execute(function() {
    132 return webdriver.WebDriver.executeCommand_(executor, command).
    133 then(function(response) {
    134 bot.response.checkResponse(response);
    135 return new webdriver.Session(response['sessionId'],
    136 response['value']);
    137 });
    138 }, description);
    139 return new webdriver.WebDriver(session, executor);
    140};
    141
    142
    143/**
    144 * Converts an object to its JSON representation in the WebDriver wire protocol.
    145 * When converting values of type object, the following steps will be taken:
    146 * <ol>
    147 * <li>if the object provides a "toWireValue" function, the return value will
    148 * be returned in its fully resolved state (e.g. this function may return
    149 * promise values)</li>
    150 * <li>if the object provides a "toJSON" function, the return value of this
    151 * function will be returned</li>
    152 * <li>otherwise, the value of each key will be recursively converted according
    153 * to the rules above.</li>
    154 * </ol>
    155 *
    156 * @param {*} obj The object to convert.
    157 * @return {!webdriver.promise.Promise} A promise that will resolve to the
    158 * input value's JSON representation.
    159 * @private
    160 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol
    161 */
    162webdriver.WebDriver.toWireValue_ = function(obj) {
    163 switch (goog.typeOf(obj)) {
    164 case 'array':
    165 return webdriver.promise.fullyResolved(
    166 goog.array.map(/** @type {!Array} */ (obj),
    167 webdriver.WebDriver.toWireValue_));
    168 case 'object':
    169 if (goog.isFunction(obj.toWireValue)) {
    170 return webdriver.promise.fullyResolved(obj.toWireValue());
    171 }
    172 if (goog.isFunction(obj.toJSON)) {
    173 return webdriver.promise.fulfilled(obj.toJSON());
    174 }
    175 if (goog.isNumber(obj.nodeType) && goog.isString(obj.nodeName)) {
    176 throw Error([
    177 'Invalid argument type: ', obj.nodeName, '(', obj.nodeType, ')'
    178 ].join(''));
    179 }
    180 return webdriver.promise.fullyResolved(
    181 goog.object.map(/** @type {!Object} */ (obj),
    182 webdriver.WebDriver.toWireValue_));
    183 case 'function':
    184 return webdriver.promise.fulfilled('' + obj);
    185 case 'undefined':
    186 return webdriver.promise.fulfilled(null);
    187 default:
    188 return webdriver.promise.fulfilled(obj);
    189 }
    190};
    191
    192
    193/**
    194 * Converts a value from its JSON representation according to the WebDriver wire
    195 * protocol. Any JSON object containing a
    196 * {@code webdriver.WebElement.ELEMENT_KEY} key will be decoded to a
    197 * {@code webdriver.WebElement} object. All other values will be passed through
    198 * as is.
    199 * @param {!webdriver.WebDriver} driver The driver instance to use as the
    200 * parent of any unwrapped {@code webdriver.WebElement} values.
    201 * @param {*} value The value to convert.
    202 * @return {*} The converted value.
    203 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol
    204 * @private
    205 */
    206webdriver.WebDriver.fromWireValue_ = function(driver, value) {
    207 if (goog.isArray(value)) {
    208 value = goog.array.map(/**@type {goog.array.ArrayLike}*/ (value),
    209 goog.partial(webdriver.WebDriver.fromWireValue_, driver));
    210 } else if (value && goog.isObject(value) && !goog.isFunction(value)) {
    211 if (webdriver.WebElement.ELEMENT_KEY in value) {
    212 value = new webdriver.WebElement(driver,
    213 value[webdriver.WebElement.ELEMENT_KEY]);
    214 } else {
    215 value = goog.object.map(/**@type {!Object}*/ (value),
    216 goog.partial(webdriver.WebDriver.fromWireValue_, driver));
    217 }
    218 }
    219 return value;
    220};
    221
    222
    223/**
    224 * Translates a command to its wire-protocol representation before passing it
    225 * to the given {@code executor} for execution.
    226 * @param {!webdriver.CommandExecutor} executor The executor to use.
    227 * @param {!webdriver.Command} command The command to execute.
    228 * @return {!webdriver.promise.Promise} A promise that will resolve with the
    229 * command response.
    230 * @private
    231 */
    232webdriver.WebDriver.executeCommand_ = function(executor, command) {
    233 return webdriver.promise.fullyResolved(command.getParameters()).
    234 then(webdriver.WebDriver.toWireValue_).
    235 then(function(parameters) {
    236 command.setParameters(parameters);
    237 return webdriver.promise.checkedNodeCall(
    238 goog.bind(executor.execute, executor, command));
    239 });
    240};
    241
    242
    243/**
    244 * @return {!webdriver.promise.ControlFlow} The control flow used by this
    245 * instance.
    246 */
    247webdriver.WebDriver.prototype.controlFlow = function() {
    248 return this.flow_;
    249};
    250
    251
    252/**
    253 * Schedules a {@code webdriver.Command} to be executed by this driver's
    254 * {@code webdriver.CommandExecutor}.
    255 * @param {!webdriver.Command} command The command to schedule.
    256 * @param {string} description A description of the command for debugging.
    257 * @return {!webdriver.promise.Promise.<T>} A promise that will be resolved
    258 * with the command result.
    259 * @template T
    260 */
    261webdriver.WebDriver.prototype.schedule = function(command, description) {
    262 var self = this;
    263
    264 checkHasNotQuit();
    265 command.setParameter('sessionId', this.session_);
    266
    267 var flow = this.flow_;
    268 return flow.execute(function() {
    269 // A call to WebDriver.quit() may have been scheduled in the same event
    270 // loop as this |command|, which would prevent us from detecting that the
    271 // driver has quit above. Therefore, we need to make another quick check.
    272 // We still check above so we can fail as early as possible.
    273 checkHasNotQuit();
    274 return webdriver.WebDriver.executeCommand_(self.executor_, command);
    275 }, description).then(function(response) {
    276 try {
    277 bot.response.checkResponse(response);
    278 } catch (ex) {
    279 var value = response['value'];
    280 if (ex.code === bot.ErrorCode.MODAL_DIALOG_OPENED) {
    281 var text = value && value['alert'] ? value['alert']['text'] : '';
    282 throw new webdriver.UnhandledAlertError(ex.message,
    283 new webdriver.Alert(self, text));
    284 }
    285 throw ex;
    286 }
    287 return webdriver.WebDriver.fromWireValue_(self, response['value']);
    288 });
    289
    290 function checkHasNotQuit() {
    291 if (!self.session_) {
    292 throw new Error('This driver instance does not have a valid session ID ' +
    293 '(did you call WebDriver.quit()?) and may no longer be ' +
    294 'used.');
    295 }
    296 }
    297};
    298
    299
    300// ----------------------------------------------------------------------------
    301// Client command functions:
    302// ----------------------------------------------------------------------------
    303
    304
    305/**
    306 * @return {!webdriver.promise.Promise.<!webdriver.Session>} A promise for this
    307 * client's session.
    308 */
    309webdriver.WebDriver.prototype.getSession = function() {
    310 return webdriver.promise.when(this.session_);
    311};
    312
    313
    314/**
    315 * @return {!webdriver.promise.Promise.<!webdriver.Capabilities>} A promise
    316 * that will resolve with the this instance's capabilities.
    317 */
    318webdriver.WebDriver.prototype.getCapabilities = function() {
    319 return webdriver.promise.when(this.session_, function(session) {
    320 return session.getCapabilities();
    321 });
    322};
    323
    324
    325/**
    326 * Schedules a command to quit the current session. After calling quit, this
    327 * instance will be invalidated and may no longer be used to issue commands
    328 * against the browser.
    329 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    330 * when the command has completed.
    331 */
    332webdriver.WebDriver.prototype.quit = function() {
    333 var result = this.schedule(
    334 new webdriver.Command(webdriver.CommandName.QUIT),
    335 'WebDriver.quit()');
    336 // Delete our session ID when the quit command finishes; this will allow us to
    337 // throw an error when attemnpting to use a driver post-quit.
    338 return result.thenFinally(goog.bind(function() {
    339 delete this.session_;
    340 }, this));
    341};
    342
    343
    344/**
    345 * Creates a new action sequence using this driver. The sequence will not be
    346 * scheduled for execution until {@link webdriver.ActionSequence#perform} is
    347 * called. Example:
    348 * <pre><code>
    349 * driver.actions().
    350 * mouseDown(element1).
    351 * mouseMove(element2).
    352 * mouseUp().
    353 * perform();
    354 * </code></pre>
    355 * @return {!webdriver.ActionSequence} A new action sequence for this instance.
    356 */
    357webdriver.WebDriver.prototype.actions = function() {
    358 return new webdriver.ActionSequence(this);
    359};
    360
    361
    362/**
    363 * Schedules a command to execute JavaScript in the context of the currently
    364 * selected frame or window. The script fragment will be executed as the body
    365 * of an anonymous function. If the script is provided as a function object,
    366 * that function will be converted to a string for injection into the target
    367 * window.
    368 *
    369 * Any arguments provided in addition to the script will be included as script
    370 * arguments and may be referenced using the {@code arguments} object.
    371 * Arguments may be a boolean, number, string, or {@code webdriver.WebElement}.
    372 * Arrays and objects may also be used as script arguments as long as each item
    373 * adheres to the types previously mentioned.
    374 *
    375 * The script may refer to any variables accessible from the current window.
    376 * Furthermore, the script will execute in the window's context, thus
    377 * {@code document} may be used to refer to the current document. Any local
    378 * variables will not be available once the script has finished executing,
    379 * though global variables will persist.
    380 *
    381 * If the script has a return value (i.e. if the script contains a return
    382 * statement), then the following steps will be taken for resolving this
    383 * functions return value:
    384 * <ul>
    385 * <li>For a HTML element, the value will resolve to a
    386 * {@code webdriver.WebElement}</li>
    387 * <li>Null and undefined return values will resolve to null</li>
    388 * <li>Booleans, numbers, and strings will resolve as is</li>
    389 * <li>Functions will resolve to their string representation</li>
    390 * <li>For arrays and objects, each member item will be converted according to
    391 * the rules above</li>
    392 * </ul>
    393 *
    394 * @param {!(string|Function)} script The script to execute.
    395 * @param {...*} var_args The arguments to pass to the script.
    396 * @return {!webdriver.promise.Promise.<T>} A promise that will resolve to the
    397 * scripts return value.
    398 * @template T
    399 */
    400webdriver.WebDriver.prototype.executeScript = function(script, var_args) {
    401 if (goog.isFunction(script)) {
    402 script = 'return (' + script + ').apply(null, arguments);';
    403 }
    404 return this.schedule(
    405 new webdriver.Command(webdriver.CommandName.EXECUTE_SCRIPT).
    406 setParameter('script', script).
    407 setParameter('args', goog.array.slice(arguments, 1)),
    408 'WebDriver.executeScript()');
    409};
    410
    411
    412/**
    413 * Schedules a command to execute asynchronous JavaScript in the context of the
    414 * currently selected frame or window. The script fragment will be executed as
    415 * the body of an anonymous function. If the script is provided as a function
    416 * object, that function will be converted to a string for injection into the
    417 * target window.
    418 *
    419 * Any arguments provided in addition to the script will be included as script
    420 * arguments and may be referenced using the {@code arguments} object.
    421 * Arguments may be a boolean, number, string, or {@code webdriver.WebElement}.
    422 * Arrays and objects may also be used as script arguments as long as each item
    423 * adheres to the types previously mentioned.
    424 *
    425 * Unlike executing synchronous JavaScript with
    426 * {@code webdriver.WebDriver.prototype.executeScript}, scripts executed with
    427 * this function must explicitly signal they are finished by invoking the
    428 * provided callback. This callback will always be injected into the
    429 * executed function as the last argument, and thus may be referenced with
    430 * {@code arguments[arguments.length - 1]}. The following steps will be taken
    431 * for resolving this functions return value against the first argument to the
    432 * script's callback function:
    433 * <ul>
    434 * <li>For a HTML element, the value will resolve to a
    435 * {@code webdriver.WebElement}</li>
    436 * <li>Null and undefined return values will resolve to null</li>
    437 * <li>Booleans, numbers, and strings will resolve as is</li>
    438 * <li>Functions will resolve to their string representation</li>
    439 * <li>For arrays and objects, each member item will be converted according to
    440 * the rules above</li>
    441 * </ul>
    442 *
    443 * Example #1: Performing a sleep that is synchronized with the currently
    444 * selected window:
    445 * <code><pre>
    446 * var start = new Date().getTime();
    447 * driver.executeAsyncScript(
    448 * 'window.setTimeout(arguments[arguments.length - 1], 500);').
    449 * then(function() {
    450 * console.log('Elapsed time: ' + (new Date().getTime() - start) + ' ms');
    451 * });
    452 * </pre></code>
    453 *
    454 * Example #2: Synchronizing a test with an AJAX application:
    455 * <code><pre>
    456 * var button = driver.findElement(By.id('compose-button'));
    457 * button.click();
    458 * driver.executeAsyncScript(
    459 * 'var callback = arguments[arguments.length - 1];' +
    460 * 'mailClient.getComposeWindowWidget().onload(callback);');
    461 * driver.switchTo().frame('composeWidget');
    462 * driver.findElement(By.id('to')).sendKEys('dog@example.com');
    463 * </pre></code>
    464 *
    465 * Example #3: Injecting a XMLHttpRequest and waiting for the result. In this
    466 * example, the inject script is specified with a function literal. When using
    467 * this format, the function is converted to a string for injection, so it
    468 * should not reference any symbols not defined in the scope of the page under
    469 * test.
    470 * <code><pre>
    471 * driver.executeAsyncScript(function() {
    472 * var callback = arguments[arguments.length - 1];
    473 * var xhr = new XMLHttpRequest();
    474 * xhr.open("GET", "/resource/data.json", true);
    475 * xhr.onreadystatechange = function() {
    476 * if (xhr.readyState == 4) {
    477 * callback(xhr.resposneText);
    478 * }
    479 * }
    480 * xhr.send('');
    481 * }).then(function(str) {
    482 * console.log(JSON.parse(str)['food']);
    483 * });
    484 * </pre></code>
    485 *
    486 * @param {!(string|Function)} script The script to execute.
    487 * @param {...*} var_args The arguments to pass to the script.
    488 * @return {!webdriver.promise.Promise.<T>} A promise that will resolve to the
    489 * scripts return value.
    490 * @template T
    491 */
    492webdriver.WebDriver.prototype.executeAsyncScript = function(script, var_args) {
    493 if (goog.isFunction(script)) {
    494 script = 'return (' + script + ').apply(null, arguments);';
    495 }
    496 return this.schedule(
    497 new webdriver.Command(webdriver.CommandName.EXECUTE_ASYNC_SCRIPT).
    498 setParameter('script', script).
    499 setParameter('args', goog.array.slice(arguments, 1)),
    500 'WebDriver.executeScript()');
    501};
    502
    503
    504/**
    505 * Schedules a command to execute a custom function.
    506 * @param {function(...): (T|webdriver.promise.Promise.<T>)} fn The function to
    507 * execute.
    508 * @param {Object=} opt_scope The object in whose scope to execute the function.
    509 * @param {...*} var_args Any arguments to pass to the function.
    510 * @return {!webdriver.promise.Promise.<T>} A promise that will be resolved'
    511 * with the function's result.
    512 * @template T
    513 */
    514webdriver.WebDriver.prototype.call = function(fn, opt_scope, var_args) {
    515 var args = goog.array.slice(arguments, 2);
    516 var flow = this.flow_;
    517 return flow.execute(function() {
    518 return webdriver.promise.fullyResolved(args).then(function(args) {
    519 return fn.apply(opt_scope, args);
    520 });
    521 }, 'WebDriver.call(' + (fn.name || 'function') + ')');
    522};
    523
    524
    525/**
    526 * Schedules a command to wait for a condition to hold, as defined by some
    527 * user supplied function. If any errors occur while evaluating the wait, they
    528 * will be allowed to propagate.
    529 *
    530 * <p>In the event a condition returns a {@link webdriver.promise.Promise}, the
    531 * polling loop will wait for it to be resolved and use the resolved value for
    532 * evaluating whether the condition has been satisfied. The resolution time for
    533 * a promise is factored into whether a wait has timed out.
    534 *
    535 * @param {function():boolean} fn The function to evaluate as a wait condition.
    536 * @param {number} timeout How long to wait for the condition to be true.
    537 * @param {string=} opt_message An optional message to use if the wait times
    538 * out.
    539 * @return {!webdriver.promise.Promise} A promise that will be resolved when the
    540 * wait condition has been satisfied.
    541 */
    542webdriver.WebDriver.prototype.wait = function(fn, timeout, opt_message) {
    543 return this.flow_.wait(fn, timeout, opt_message);
    544};
    545
    546
    547/**
    548 * Schedules a command to make the driver sleep for the given amount of time.
    549 * @param {number} ms The amount of time, in milliseconds, to sleep.
    550 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    551 * when the sleep has finished.
    552 */
    553webdriver.WebDriver.prototype.sleep = function(ms) {
    554 return this.flow_.timeout(ms, 'WebDriver.sleep(' + ms + ')');
    555};
    556
    557
    558/**
    559 * Schedules a command to retrieve they current window handle.
    560 * @return {!webdriver.promise.Promise.<string>} A promise that will be
    561 * resolved with the current window handle.
    562 */
    563webdriver.WebDriver.prototype.getWindowHandle = function() {
    564 return this.schedule(
    565 new webdriver.Command(webdriver.CommandName.GET_CURRENT_WINDOW_HANDLE),
    566 'WebDriver.getWindowHandle()');
    567};
    568
    569
    570/**
    571 * Schedules a command to retrieve the current list of available window handles.
    572 * @return {!webdriver.promise.Promise.<!Array.<string>>} A promise that will
    573 * be resolved with an array of window handles.
    574 */
    575webdriver.WebDriver.prototype.getAllWindowHandles = function() {
    576 return this.schedule(
    577 new webdriver.Command(webdriver.CommandName.GET_WINDOW_HANDLES),
    578 'WebDriver.getAllWindowHandles()');
    579};
    580
    581
    582/**
    583 * Schedules a command to retrieve the current page's source. The page source
    584 * returned is a representation of the underlying DOM: do not expect it to be
    585 * formatted or escaped in the same way as the response sent from the web
    586 * server.
    587 * @return {!webdriver.promise.Promise.<string>} A promise that will be
    588 * resolved with the current page source.
    589 */
    590webdriver.WebDriver.prototype.getPageSource = function() {
    591 return this.schedule(
    592 new webdriver.Command(webdriver.CommandName.GET_PAGE_SOURCE),
    593 'WebDriver.getAllWindowHandles()');
    594};
    595
    596
    597/**
    598 * Schedules a command to close the current window.
    599 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    600 * when this command has completed.
    601 */
    602webdriver.WebDriver.prototype.close = function() {
    603 return this.schedule(new webdriver.Command(webdriver.CommandName.CLOSE),
    604 'WebDriver.close()');
    605};
    606
    607
    608/**
    609 * Schedules a command to navigate to the given URL.
    610 * @param {string} url The fully qualified URL to open.
    611 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    612 * when the document has finished loading.
    613 */
    614webdriver.WebDriver.prototype.get = function(url) {
    615 return this.navigate().to(url);
    616};
    617
    618
    619/**
    620 * Schedules a command to retrieve the URL of the current page.
    621 * @return {!webdriver.promise.Promise.<string>} A promise that will be
    622 * resolved with the current URL.
    623 */
    624webdriver.WebDriver.prototype.getCurrentUrl = function() {
    625 return this.schedule(
    626 new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL),
    627 'WebDriver.getCurrentUrl()');
    628};
    629
    630
    631/**
    632 * Schedules a command to retrieve the current page's title.
    633 * @return {!webdriver.promise.Promise.<string>} A promise that will be
    634 * resolved with the current page's title.
    635 */
    636webdriver.WebDriver.prototype.getTitle = function() {
    637 return this.schedule(new webdriver.Command(webdriver.CommandName.GET_TITLE),
    638 'WebDriver.getTitle()');
    639};
    640
    641
    642/**
    643 * Schedule a command to find an element on the page. If the element cannot be
    644 * found, a {@link bot.ErrorCode.NO_SUCH_ELEMENT} result will be returned
    645 * by the driver. Unlike other commands, this error cannot be suppressed. In
    646 * other words, scheduling a command to find an element doubles as an assert
    647 * that the element is present on the page. To test whether an element is
    648 * present on the page, use {@link #isElementPresent} instead.
    649 *
    650 * <p>The search criteria for an element may be defined using one of the
    651 * factories in the {@link webdriver.By} namespace, or as a short-hand
    652 * {@link webdriver.By.Hash} object. For example, the following two statements
    653 * are equivalent:
    654 * <code><pre>
    655 * var e1 = driver.findElement(By.id('foo'));
    656 * var e2 = driver.findElement({id:'foo'});
    657 * </pre></code>
    658 *
    659 * <p>You may also provide a custom locator function, which takes as input
    660 * this WebDriver instance and returns a {@link webdriver.WebElement}, or a
    661 * promise that will resolve to a WebElement. For example, to find the first
    662 * visible link on a page, you could write:
    663 * <code><pre>
    664 * var link = driver.findElement(firstVisibleLink);
    665 *
    666 * function firstVisibleLink(driver) {
    667 * var links = driver.findElements(By.tagName('a'));
    668 * return webdriver.promise.filter(links, function(link) {
    669 * return links.isDisplayed();
    670 * }).then(function(visibleLinks) {
    671 * return visibleLinks[0];
    672 * });
    673 * }
    674 * </pre></code>
    675 *
    676 * <p>When running in the browser, a WebDriver cannot manipulate DOM elements
    677 * directly; it may do so only through a {@link webdriver.WebElement} reference.
    678 * This function may be used to generate a WebElement from a DOM element. A
    679 * reference to the DOM element will be stored in a known location and this
    680 * driver will attempt to retrieve it through {@link #executeScript}. If the
    681 * element cannot be found (eg, it belongs to a different document than the
    682 * one this instance is currently focused on), a
    683 * {@link bot.ErrorCode.NO_SUCH_ELEMENT} error will be returned.
    684 *
    685 * @param {!(webdriver.Locator|webdriver.By.Hash|Element|Function)} locator The
    686 * locator to use.
    687 * @return {!webdriver.WebElement} A WebElement that can be used to issue
    688 * commands against the located element. If the element is not found, the
    689 * element will be invalidated and all scheduled commands aborted.
    690 */
    691webdriver.WebDriver.prototype.findElement = function(locator) {
    692 var id;
    693 if ('nodeType' in locator && 'ownerDocument' in locator) {
    694 var element = /** @type {!Element} */ (locator);
    695 id = this.findDomElement_(element).then(function(element) {
    696 if (!element) {
    697 throw new bot.Error(bot.ErrorCode.NO_SUCH_ELEMENT,
    698 'Unable to locate element. Is WebDriver focused on its ' +
    699 'ownerDocument\'s frame?');
    700 }
    701 return element;
    702 });
    703 } else {
    704 locator = webdriver.Locator.checkLocator(locator);
    705 if (goog.isFunction(locator)) {
    706 id = this.findElementInternal_(locator, this);
    707 } else {
    708 var command = new webdriver.Command(webdriver.CommandName.FIND_ELEMENT).
    709 setParameter('using', locator.using).
    710 setParameter('value', locator.value);
    711 id = this.schedule(command, 'WebDriver.findElement(' + locator + ')');
    712 }
    713 }
    714 return new webdriver.WebElement(this, id);
    715};
    716
    717
    718/**
    719 * @param {!Function} locatorFn The locator function to use.
    720 * @param {!(webdriver.WebDriver|webdriver.WebElement)} context The search
    721 * context.
    722 * @return {!webdriver.promise.Promise.<!webdriver.WebElement>} A
    723 * promise that will resolve to a list of WebElements.
    724 * @private
    725 */
    726webdriver.WebDriver.prototype.findElementInternal_ = function(
    727 locatorFn, context) {
    728 return this.call(goog.partial(locatorFn, context)).then(function(result) {
    729 if (goog.isArray(result)) {
    730 result = result[0];
    731 }
    732 if (!(result instanceof webdriver.WebElement)) {
    733 throw new TypeError('Custom locator did not return a WebElement');
    734 }
    735 return result;
    736 });
    737};
    738
    739
    740/**
    741 * Locates a DOM element so that commands may be issued against it using the
    742 * {@link webdriver.WebElement} class. This is accomplished by storing a
    743 * reference to the element in an object on the element's ownerDocument.
    744 * {@link #executeScript} will then be used to create a WebElement from this
    745 * reference. This requires this driver to currently be focused on the
    746 * ownerDocument's window+frame.
    747
    748 * @param {!Element} element The element to locate.
    749 * @return {!webdriver.promise.Promise.<webdriver.WebElement>} A promise that
    750 * will be fulfilled with the located element, or null if the element
    751 * could not be found.
    752 * @private
    753 */
    754webdriver.WebDriver.prototype.findDomElement_ = function(element) {
    755 var doc = element.ownerDocument;
    756 var store = doc['$webdriver$'] = doc['$webdriver$'] || {};
    757 var id = Math.floor(Math.random() * goog.now()).toString(36);
    758 store[id] = element;
    759 element[id] = id;
    760
    761 function cleanUp() {
    762 delete store[id];
    763 }
    764
    765 function lookupElement(id) {
    766 var store = document['$webdriver$'];
    767 if (!store) {
    768 return null;
    769 }
    770
    771 var element = store[id];
    772 if (!element || element[id] !== id) {
    773 return null;
    774 }
    775 return element;
    776 }
    777
    778 /** @type {!webdriver.promise.Promise.<webdriver.WebElement>} */
    779 var foundElement = this.executeScript(lookupElement, id);
    780 foundElement.thenFinally(cleanUp);
    781 return foundElement;
    782};
    783
    784
    785/**
    786 * Schedules a command to test if an element is present on the page.
    787 *
    788 * <p>If given a DOM element, this function will check if it belongs to the
    789 * document the driver is currently focused on. Otherwise, the function will
    790 * test if at least one element can be found with the given search criteria.
    791 *
    792 * @param {!(webdriver.Locator|webdriver.By.Hash|Element|
    793 * Function)} locatorOrElement The locator to use, or the actual
    794 * DOM element to be located by the server.
    795 * @return {!webdriver.promise.Promise.<boolean>} A promise that will resolve
    796 * with whether the element is present on the page.
    797 */
    798webdriver.WebDriver.prototype.isElementPresent = function(locatorOrElement) {
    799 if ('nodeType' in locatorOrElement && 'ownerDocument' in locatorOrElement) {
    800 return this.findDomElement_(/** @type {!Element} */ (locatorOrElement)).
    801 then(function(result) { return !!result; });
    802 } else {
    803 return this.findElements.apply(this, arguments).then(function(result) {
    804 return !!result.length;
    805 });
    806 }
    807};
    808
    809
    810/**
    811 * Schedule a command to search for multiple elements on the page.
    812 *
    813 * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The locator
    814 * strategy to use when searching for the element.
    815 * @return {!webdriver.promise.Promise.<!Array.<!webdriver.WebElement>>} A
    816 * promise that will resolve to an array of WebElements.
    817 */
    818webdriver.WebDriver.prototype.findElements = function(locator) {
    819 locator = webdriver.Locator.checkLocator(locator);
    820 if (goog.isFunction(locator)) {
    821 return this.findElementsInternal_(locator, this);
    822 } else {
    823 var command = new webdriver.Command(webdriver.CommandName.FIND_ELEMENTS).
    824 setParameter('using', locator.using).
    825 setParameter('value', locator.value);
    826 return this.schedule(command, 'WebDriver.findElements(' + locator + ')');
    827 }
    828};
    829
    830
    831/**
    832 * @param {!Function} locatorFn The locator function to use.
    833 * @param {!(webdriver.WebDriver|webdriver.WebElement)} context The search
    834 * context.
    835 * @return {!webdriver.promise.Promise.<!Array.<!webdriver.WebElement>>} A
    836 * promise that will resolve to an array of WebElements.
    837 * @private
    838 */
    839webdriver.WebDriver.prototype.findElementsInternal_ = function(
    840 locatorFn, context) {
    841 return this.call(goog.partial(locatorFn, context)).then(function(result) {
    842 if (result instanceof webdriver.WebElement) {
    843 return [result];
    844 }
    845
    846 if (!goog.isArray(result)) {
    847 return [];
    848 }
    849
    850 return goog.array.filter(result, function(item) {
    851 return item instanceof webdriver.WebElement;
    852 });
    853 });
    854};
    855
    856
    857/**
    858 * Schedule a command to take a screenshot. The driver makes a best effort to
    859 * return a screenshot of the following, in order of preference:
    860 * <ol>
    861 * <li>Entire page
    862 * <li>Current window
    863 * <li>Visible portion of the current frame
    864 * <li>The screenshot of the entire display containing the browser
    865 * </ol>
    866 *
    867 * @return {!webdriver.promise.Promise.<string>} A promise that will be
    868 * resolved to the screenshot as a base-64 encoded PNG.
    869 */
    870webdriver.WebDriver.prototype.takeScreenshot = function() {
    871 return this.schedule(new webdriver.Command(webdriver.CommandName.SCREENSHOT),
    872 'WebDriver.takeScreenshot()');
    873};
    874
    875
    876/**
    877 * @return {!webdriver.WebDriver.Options} The options interface for this
    878 * instance.
    879 */
    880webdriver.WebDriver.prototype.manage = function() {
    881 return new webdriver.WebDriver.Options(this);
    882};
    883
    884
    885/**
    886 * @return {!webdriver.WebDriver.Navigation} The navigation interface for this
    887 * instance.
    888 */
    889webdriver.WebDriver.prototype.navigate = function() {
    890 return new webdriver.WebDriver.Navigation(this);
    891};
    892
    893
    894/**
    895 * @return {!webdriver.WebDriver.TargetLocator} The target locator interface for
    896 * this instance.
    897 */
    898webdriver.WebDriver.prototype.switchTo = function() {
    899 return new webdriver.WebDriver.TargetLocator(this);
    900};
    901
    902
    903
    904/**
    905 * Interface for navigating back and forth in the browser history.
    906 * @param {!webdriver.WebDriver} driver The parent driver.
    907 * @constructor
    908 */
    909webdriver.WebDriver.Navigation = function(driver) {
    910
    911 /** @private {!webdriver.WebDriver} */
    912 this.driver_ = driver;
    913};
    914
    915
    916/**
    917 * Schedules a command to navigate to a new URL.
    918 * @param {string} url The URL to navigate to.
    919 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    920 * when the URL has been loaded.
    921 */
    922webdriver.WebDriver.Navigation.prototype.to = function(url) {
    923 return this.driver_.schedule(
    924 new webdriver.Command(webdriver.CommandName.GET).
    925 setParameter('url', url),
    926 'WebDriver.navigate().to(' + url + ')');
    927};
    928
    929
    930/**
    931 * Schedules a command to move backwards in the browser history.
    932 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    933 * when the navigation event has completed.
    934 */
    935webdriver.WebDriver.Navigation.prototype.back = function() {
    936 return this.driver_.schedule(
    937 new webdriver.Command(webdriver.CommandName.GO_BACK),
    938 'WebDriver.navigate().back()');
    939};
    940
    941
    942/**
    943 * Schedules a command to move forwards in the browser history.
    944 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    945 * when the navigation event has completed.
    946 */
    947webdriver.WebDriver.Navigation.prototype.forward = function() {
    948 return this.driver_.schedule(
    949 new webdriver.Command(webdriver.CommandName.GO_FORWARD),
    950 'WebDriver.navigate().forward()');
    951};
    952
    953
    954/**
    955 * Schedules a command to refresh the current page.
    956 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    957 * when the navigation event has completed.
    958 */
    959webdriver.WebDriver.Navigation.prototype.refresh = function() {
    960 return this.driver_.schedule(
    961 new webdriver.Command(webdriver.CommandName.REFRESH),
    962 'WebDriver.navigate().refresh()');
    963};
    964
    965
    966
    967/**
    968 * Provides methods for managing browser and driver state.
    969 * @param {!webdriver.WebDriver} driver The parent driver.
    970 * @constructor
    971 */
    972webdriver.WebDriver.Options = function(driver) {
    973
    974 /** @private {!webdriver.WebDriver} */
    975 this.driver_ = driver;
    976};
    977
    978
    979/**
    980 * A JSON description of a browser cookie.
    981 * @typedef {{
    982 * name: string,
    983 * value: string,
    984 * path: (string|undefined),
    985 * domain: (string|undefined),
    986 * secure: (boolean|undefined),
    987 * expiry: (number|undefined)
    988 * }}
    989 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object
    990 */
    991webdriver.WebDriver.Options.Cookie;
    992
    993
    994/**
    995 * Schedules a command to add a cookie.
    996 * @param {string} name The cookie name.
    997 * @param {string} value The cookie value.
    998 * @param {string=} opt_path The cookie path.
    999 * @param {string=} opt_domain The cookie domain.
    1000 * @param {boolean=} opt_isSecure Whether the cookie is secure.
    1001 * @param {(number|!Date)=} opt_expiry When the cookie expires. If specified as
    1002 * a number, should be in milliseconds since midnight, January 1, 1970 UTC.
    1003 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1004 * when the cookie has been added to the page.
    1005 */
    1006webdriver.WebDriver.Options.prototype.addCookie = function(
    1007 name, value, opt_path, opt_domain, opt_isSecure, opt_expiry) {
    1008 // We do not allow '=' or ';' in the name.
    1009 if (/[;=]/.test(name)) {
    1010 throw Error('Invalid cookie name "' + name + '"');
    1011 }
    1012
    1013 // We do not allow ';' in value.
    1014 if (/;/.test(value)) {
    1015 throw Error('Invalid cookie value "' + value + '"');
    1016 }
    1017
    1018 var cookieString = name + '=' + value +
    1019 (opt_domain ? ';domain=' + opt_domain : '') +
    1020 (opt_path ? ';path=' + opt_path : '') +
    1021 (opt_isSecure ? ';secure' : '');
    1022
    1023 var expiry;
    1024 if (goog.isDef(opt_expiry)) {
    1025 var expiryDate;
    1026 if (goog.isNumber(opt_expiry)) {
    1027 expiryDate = new Date(opt_expiry);
    1028 } else {
    1029 expiryDate = /** @type {!Date} */ (opt_expiry);
    1030 opt_expiry = expiryDate.getTime();
    1031 }
    1032 cookieString += ';expires=' + expiryDate.toUTCString();
    1033 // Convert from milliseconds to seconds.
    1034 expiry = Math.floor(/** @type {number} */ (opt_expiry) / 1000);
    1035 }
    1036
    1037 return this.driver_.schedule(
    1038 new webdriver.Command(webdriver.CommandName.ADD_COOKIE).
    1039 setParameter('cookie', {
    1040 'name': name,
    1041 'value': value,
    1042 'path': opt_path,
    1043 'domain': opt_domain,
    1044 'secure': !!opt_isSecure,
    1045 'expiry': expiry
    1046 }),
    1047 'WebDriver.manage().addCookie(' + cookieString + ')');
    1048};
    1049
    1050
    1051/**
    1052 * Schedules a command to delete all cookies visible to the current page.
    1053 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1054 * when all cookies have been deleted.
    1055 */
    1056webdriver.WebDriver.Options.prototype.deleteAllCookies = function() {
    1057 return this.driver_.schedule(
    1058 new webdriver.Command(webdriver.CommandName.DELETE_ALL_COOKIES),
    1059 'WebDriver.manage().deleteAllCookies()');
    1060};
    1061
    1062
    1063/**
    1064 * Schedules a command to delete the cookie with the given name. This command is
    1065 * a no-op if there is no cookie with the given name visible to the current
    1066 * page.
    1067 * @param {string} name The name of the cookie to delete.
    1068 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1069 * when the cookie has been deleted.
    1070 */
    1071webdriver.WebDriver.Options.prototype.deleteCookie = function(name) {
    1072 return this.driver_.schedule(
    1073 new webdriver.Command(webdriver.CommandName.DELETE_COOKIE).
    1074 setParameter('name', name),
    1075 'WebDriver.manage().deleteCookie(' + name + ')');
    1076};
    1077
    1078
    1079/**
    1080 * Schedules a command to retrieve all cookies visible to the current page.
    1081 * Each cookie will be returned as a JSON object as described by the WebDriver
    1082 * wire protocol.
    1083 * @return {!webdriver.promise.Promise.<
    1084 * !Array.<webdriver.WebDriver.Options.Cookie>>} A promise that will be
    1085 * resolved with the cookies visible to the current page.
    1086 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object
    1087 */
    1088webdriver.WebDriver.Options.prototype.getCookies = function() {
    1089 return this.driver_.schedule(
    1090 new webdriver.Command(webdriver.CommandName.GET_ALL_COOKIES),
    1091 'WebDriver.manage().getCookies()');
    1092};
    1093
    1094
    1095/**
    1096 * Schedules a command to retrieve the cookie with the given name. Returns null
    1097 * if there is no such cookie. The cookie will be returned as a JSON object as
    1098 * described by the WebDriver wire protocol.
    1099 * @param {string} name The name of the cookie to retrieve.
    1100 * @return {!webdriver.promise.Promise.<?webdriver.WebDriver.Options.Cookie>} A
    1101 * promise that will be resolved with the named cookie, or {@code null}
    1102 * if there is no such cookie.
    1103 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object
    1104 */
    1105webdriver.WebDriver.Options.prototype.getCookie = function(name) {
    1106 return this.getCookies().then(function(cookies) {
    1107 return goog.array.find(cookies, function(cookie) {
    1108 return cookie && cookie['name'] == name;
    1109 });
    1110 });
    1111};
    1112
    1113
    1114/**
    1115 * @return {!webdriver.WebDriver.Logs} The interface for managing driver
    1116 * logs.
    1117 */
    1118webdriver.WebDriver.Options.prototype.logs = function() {
    1119 return new webdriver.WebDriver.Logs(this.driver_);
    1120};
    1121
    1122
    1123/**
    1124 * @return {!webdriver.WebDriver.Timeouts} The interface for managing driver
    1125 * timeouts.
    1126 */
    1127webdriver.WebDriver.Options.prototype.timeouts = function() {
    1128 return new webdriver.WebDriver.Timeouts(this.driver_);
    1129};
    1130
    1131
    1132/**
    1133 * @return {!webdriver.WebDriver.Window} The interface for managing the
    1134 * current window.
    1135 */
    1136webdriver.WebDriver.Options.prototype.window = function() {
    1137 return new webdriver.WebDriver.Window(this.driver_);
    1138};
    1139
    1140
    1141
    1142/**
    1143 * An interface for managing timeout behavior for WebDriver instances.
    1144 * @param {!webdriver.WebDriver} driver The parent driver.
    1145 * @constructor
    1146 */
    1147webdriver.WebDriver.Timeouts = function(driver) {
    1148
    1149 /** @private {!webdriver.WebDriver} */
    1150 this.driver_ = driver;
    1151};
    1152
    1153
    1154/**
    1155 * Specifies the amount of time the driver should wait when searching for an
    1156 * element if it is not immediately present.
    1157 * <p/>
    1158 * When searching for a single element, the driver should poll the page
    1159 * until the element has been found, or this timeout expires before failing
    1160 * with a {@code bot.ErrorCode.NO_SUCH_ELEMENT} error. When searching
    1161 * for multiple elements, the driver should poll the page until at least one
    1162 * element has been found or this timeout has expired.
    1163 * <p/>
    1164 * Setting the wait timeout to 0 (its default value), disables implicit
    1165 * waiting.
    1166 * <p/>
    1167 * Increasing the implicit wait timeout should be used judiciously as it
    1168 * will have an adverse effect on test run time, especially when used with
    1169 * slower location strategies like XPath.
    1170 *
    1171 * @param {number} ms The amount of time to wait, in milliseconds.
    1172 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1173 * when the implicit wait timeout has been set.
    1174 */
    1175webdriver.WebDriver.Timeouts.prototype.implicitlyWait = function(ms) {
    1176 return this.driver_.schedule(
    1177 new webdriver.Command(webdriver.CommandName.IMPLICITLY_WAIT).
    1178 setParameter('ms', ms < 0 ? 0 : ms),
    1179 'WebDriver.manage().timeouts().implicitlyWait(' + ms + ')');
    1180};
    1181
    1182
    1183/**
    1184 * Sets the amount of time to wait, in milliseconds, for an asynchronous script
    1185 * to finish execution before returning an error. If the timeout is less than or
    1186 * equal to 0, the script will be allowed to run indefinitely.
    1187 *
    1188 * @param {number} ms The amount of time to wait, in milliseconds.
    1189 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1190 * when the script timeout has been set.
    1191 */
    1192webdriver.WebDriver.Timeouts.prototype.setScriptTimeout = function(ms) {
    1193 return this.driver_.schedule(
    1194 new webdriver.Command(webdriver.CommandName.SET_SCRIPT_TIMEOUT).
    1195 setParameter('ms', ms < 0 ? 0 : ms),
    1196 'WebDriver.manage().timeouts().setScriptTimeout(' + ms + ')');
    1197};
    1198
    1199
    1200/**
    1201 * Sets the amount of time to wait for a page load to complete before returning
    1202 * an error. If the timeout is negative, page loads may be indefinite.
    1203 * @param {number} ms The amount of time to wait, in milliseconds.
    1204 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1205 * when the timeout has been set.
    1206 */
    1207webdriver.WebDriver.Timeouts.prototype.pageLoadTimeout = function(ms) {
    1208 return this.driver_.schedule(
    1209 new webdriver.Command(webdriver.CommandName.SET_TIMEOUT).
    1210 setParameter('type', 'page load').
    1211 setParameter('ms', ms),
    1212 'WebDriver.manage().timeouts().pageLoadTimeout(' + ms + ')');
    1213};
    1214
    1215
    1216
    1217/**
    1218 * An interface for managing the current window.
    1219 * @param {!webdriver.WebDriver} driver The parent driver.
    1220 * @constructor
    1221 */
    1222webdriver.WebDriver.Window = function(driver) {
    1223
    1224 /** @private {!webdriver.WebDriver} */
    1225 this.driver_ = driver;
    1226};
    1227
    1228
    1229/**
    1230 * Retrieves the window's current position, relative to the top left corner of
    1231 * the screen.
    1232 * @return {!webdriver.promise.Promise.<{x: number, y: number}>} A promise that
    1233 * will be resolved with the window's position in the form of a
    1234 * {x:number, y:number} object literal.
    1235 */
    1236webdriver.WebDriver.Window.prototype.getPosition = function() {
    1237 return this.driver_.schedule(
    1238 new webdriver.Command(webdriver.CommandName.GET_WINDOW_POSITION).
    1239 setParameter('windowHandle', 'current'),
    1240 'WebDriver.manage().window().getPosition()');
    1241};
    1242
    1243
    1244/**
    1245 * Repositions the current window.
    1246 * @param {number} x The desired horizontal position, relative to the left side
    1247 * of the screen.
    1248 * @param {number} y The desired vertical position, relative to the top of the
    1249 * of the screen.
    1250 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1251 * when the command has completed.
    1252 */
    1253webdriver.WebDriver.Window.prototype.setPosition = function(x, y) {
    1254 return this.driver_.schedule(
    1255 new webdriver.Command(webdriver.CommandName.SET_WINDOW_POSITION).
    1256 setParameter('windowHandle', 'current').
    1257 setParameter('x', x).
    1258 setParameter('y', y),
    1259 'WebDriver.manage().window().setPosition(' + x + ', ' + y + ')');
    1260};
    1261
    1262
    1263/**
    1264 * Retrieves the window's current size.
    1265 * @return {!webdriver.promise.Promise.<{width: number, height: number}>} A
    1266 * promise that will be resolved with the window's size in the form of a
    1267 * {width:number, height:number} object literal.
    1268 */
    1269webdriver.WebDriver.Window.prototype.getSize = function() {
    1270 return this.driver_.schedule(
    1271 new webdriver.Command(webdriver.CommandName.GET_WINDOW_SIZE).
    1272 setParameter('windowHandle', 'current'),
    1273 'WebDriver.manage().window().getSize()');
    1274};
    1275
    1276
    1277/**
    1278 * Resizes the current window.
    1279 * @param {number} width The desired window width.
    1280 * @param {number} height The desired window height.
    1281 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1282 * when the command has completed.
    1283 */
    1284webdriver.WebDriver.Window.prototype.setSize = function(width, height) {
    1285 return this.driver_.schedule(
    1286 new webdriver.Command(webdriver.CommandName.SET_WINDOW_SIZE).
    1287 setParameter('windowHandle', 'current').
    1288 setParameter('width', width).
    1289 setParameter('height', height),
    1290 'WebDriver.manage().window().setSize(' + width + ', ' + height + ')');
    1291};
    1292
    1293
    1294/**
    1295 * Maximizes the current window.
    1296 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1297 * when the command has completed.
    1298 */
    1299webdriver.WebDriver.Window.prototype.maximize = function() {
    1300 return this.driver_.schedule(
    1301 new webdriver.Command(webdriver.CommandName.MAXIMIZE_WINDOW).
    1302 setParameter('windowHandle', 'current'),
    1303 'WebDriver.manage().window().maximize()');
    1304};
    1305
    1306
    1307/**
    1308 * Interface for managing WebDriver log records.
    1309 * @param {!webdriver.WebDriver} driver The parent driver.
    1310 * @constructor
    1311 */
    1312webdriver.WebDriver.Logs = function(driver) {
    1313
    1314 /** @private {!webdriver.WebDriver} */
    1315 this.driver_ = driver;
    1316};
    1317
    1318
    1319/**
    1320 * Fetches available log entries for the given type.
    1321 *
    1322 * <p/>Note that log buffers are reset after each call, meaning that
    1323 * available log entries correspond to those entries not yet returned for a
    1324 * given log type. In practice, this means that this call will return the
    1325 * available log entries since the last call, or from the start of the
    1326 * session.
    1327 *
    1328 * @param {!webdriver.logging.Type} type The desired log type.
    1329 * @return {!webdriver.promise.Promise.<!Array.<!webdriver.logging.Entry>>} A
    1330 * promise that will resolve to a list of log entries for the specified
    1331 * type.
    1332 */
    1333webdriver.WebDriver.Logs.prototype.get = function(type) {
    1334 return this.driver_.schedule(
    1335 new webdriver.Command(webdriver.CommandName.GET_LOG).
    1336 setParameter('type', type),
    1337 'WebDriver.manage().logs().get(' + type + ')').
    1338 then(function(entries) {
    1339 return goog.array.map(entries, function(entry) {
    1340 if (!(entry instanceof webdriver.logging.Entry)) {
    1341 return new webdriver.logging.Entry(
    1342 entry['level'], entry['message'], entry['timestamp']);
    1343 }
    1344 return entry;
    1345 });
    1346 });
    1347};
    1348
    1349
    1350/**
    1351 * Retrieves the log types available to this driver.
    1352 * @return {!webdriver.promise.Promise.<!Array.<!webdriver.logging.Type>>} A
    1353 * promise that will resolve to a list of available log types.
    1354 */
    1355webdriver.WebDriver.Logs.prototype.getAvailableLogTypes = function() {
    1356 return this.driver_.schedule(
    1357 new webdriver.Command(webdriver.CommandName.GET_AVAILABLE_LOG_TYPES),
    1358 'WebDriver.manage().logs().getAvailableLogTypes()');
    1359};
    1360
    1361
    1362
    1363/**
    1364 * An interface for changing the focus of the driver to another frame or window.
    1365 * @param {!webdriver.WebDriver} driver The parent driver.
    1366 * @constructor
    1367 */
    1368webdriver.WebDriver.TargetLocator = function(driver) {
    1369
    1370 /** @private {!webdriver.WebDriver} */
    1371 this.driver_ = driver;
    1372};
    1373
    1374
    1375/**
    1376 * Schedules a command retrieve the {@code document.activeElement} element on
    1377 * the current document, or {@code document.body} if activeElement is not
    1378 * available.
    1379 * @return {!webdriver.WebElement} The active element.
    1380 */
    1381webdriver.WebDriver.TargetLocator.prototype.activeElement = function() {
    1382 var id = this.driver_.schedule(
    1383 new webdriver.Command(webdriver.CommandName.GET_ACTIVE_ELEMENT),
    1384 'WebDriver.switchTo().activeElement()');
    1385 return new webdriver.WebElement(this.driver_, id);
    1386};
    1387
    1388
    1389/**
    1390 * Schedules a command to switch focus of all future commands to the first frame
    1391 * on the page.
    1392 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1393 * when the driver has changed focus to the default content.
    1394 */
    1395webdriver.WebDriver.TargetLocator.prototype.defaultContent = function() {
    1396 return this.driver_.schedule(
    1397 new webdriver.Command(webdriver.CommandName.SWITCH_TO_FRAME).
    1398 setParameter('id', null),
    1399 'WebDriver.switchTo().defaultContent()');
    1400};
    1401
    1402
    1403/**
    1404 * Schedules a command to switch the focus of all future commands to another
    1405 * frame on the page.
    1406 * <p/>
    1407 * If the frame is specified by a number, the command will switch to the frame
    1408 * by its (zero-based) index into the {@code window.frames} collection.
    1409 * <p/>
    1410 * If the frame is specified by a string, the command will select the frame by
    1411 * its name or ID. To select sub-frames, simply separate the frame names/IDs by
    1412 * dots. As an example, "main.child" will select the frame with the name "main"
    1413 * and then its child "child".
    1414 * <p/>
    1415 * If the specified frame can not be found, the deferred result will errback
    1416 * with a {@code bot.ErrorCode.NO_SUCH_FRAME} error.
    1417 * @param {string|number} nameOrIndex The frame locator.
    1418 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1419 * when the driver has changed focus to the specified frame.
    1420 */
    1421webdriver.WebDriver.TargetLocator.prototype.frame = function(nameOrIndex) {
    1422 return this.driver_.schedule(
    1423 new webdriver.Command(webdriver.CommandName.SWITCH_TO_FRAME).
    1424 setParameter('id', nameOrIndex),
    1425 'WebDriver.switchTo().frame(' + nameOrIndex + ')');
    1426};
    1427
    1428
    1429/**
    1430 * Schedules a command to switch the focus of all future commands to another
    1431 * window. Windows may be specified by their {@code window.name} attribute or
    1432 * by its handle (as returned by {@code webdriver.WebDriver#getWindowHandles}).
    1433 * <p/>
    1434 * If the specificed window can not be found, the deferred result will errback
    1435 * with a {@code bot.ErrorCode.NO_SUCH_WINDOW} error.
    1436 * @param {string} nameOrHandle The name or window handle of the window to
    1437 * switch focus to.
    1438 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1439 * when the driver has changed focus to the specified window.
    1440 */
    1441webdriver.WebDriver.TargetLocator.prototype.window = function(nameOrHandle) {
    1442 return this.driver_.schedule(
    1443 new webdriver.Command(webdriver.CommandName.SWITCH_TO_WINDOW).
    1444 setParameter('name', nameOrHandle),
    1445 'WebDriver.switchTo().window(' + nameOrHandle + ')');
    1446};
    1447
    1448
    1449/**
    1450 * Schedules a command to change focus to the active alert dialog. This command
    1451 * will return a {@link bot.ErrorCode.NO_MODAL_DIALOG_OPEN} error if a modal
    1452 * dialog is not currently open.
    1453 * @return {!webdriver.Alert} The open alert.
    1454 */
    1455webdriver.WebDriver.TargetLocator.prototype.alert = function() {
    1456 var text = this.driver_.schedule(
    1457 new webdriver.Command(webdriver.CommandName.GET_ALERT_TEXT),
    1458 'WebDriver.switchTo().alert()');
    1459 return new webdriver.Alert(this.driver_, text);
    1460};
    1461
    1462
    1463/**
    1464 * Simulate pressing many keys at once in a "chord". Takes a sequence of
    1465 * {@link webdriver.Key}s or strings, appends each of the values to a string,
    1466 * and adds the chord termination key ({@link webdriver.Key.NULL}) and returns
    1467 * the resultant string.
    1468 *
    1469 * Note: when the low-level webdriver key handlers see Keys.NULL, active
    1470 * modifier keys (CTRL/ALT/SHIFT/etc) release via a keyup event.
    1471 *
    1472 * @param {...string} var_args The key sequence to concatenate.
    1473 * @return {string} The null-terminated key sequence.
    1474 * @see http://code.google.com/p/webdriver/issues/detail?id=79
    1475 */
    1476webdriver.Key.chord = function(var_args) {
    1477 var sequence = goog.array.reduce(
    1478 goog.array.slice(arguments, 0),
    1479 function(str, key) {
    1480 return str + key;
    1481 }, '');
    1482 sequence += webdriver.Key.NULL;
    1483 return sequence;
    1484};
    1485
    1486
    1487//////////////////////////////////////////////////////////////////////////////
    1488//
    1489// webdriver.WebElement
    1490//
    1491//////////////////////////////////////////////////////////////////////////////
    1492
    1493
    1494
    1495/**
    1496 * Represents a DOM element. WebElements can be found by searching from the
    1497 * document root using a {@code webdriver.WebDriver} instance, or by searching
    1498 * under another {@code webdriver.WebElement}:
    1499 * <pre><code>
    1500 * driver.get('http://www.google.com');
    1501 * var searchForm = driver.findElement(By.tagName('form'));
    1502 * var searchBox = searchForm.findElement(By.name('q'));
    1503 * searchBox.sendKeys('webdriver');
    1504 * </code></pre>
    1505 *
    1506 * The WebElement is implemented as a promise for compatibility with the promise
    1507 * API. It will always resolve itself when its internal state has been fully
    1508 * resolved and commands may be issued against the element. This can be used to
    1509 * catch errors when an element cannot be located on the page:
    1510 * <pre><code>
    1511 * driver.findElement(By.id('not-there')).then(function(element) {
    1512 * alert('Found an element that was not expected to be there!');
    1513 * }, function(error) {
    1514 * alert('The element was not found, as expected');
    1515 * });
    1516 * </code></pre>
    1517 *
    1518 * @param {!webdriver.WebDriver} driver The parent WebDriver instance for this
    1519 * element.
    1520 * @param {!(string|webdriver.promise.Promise)} id Either the opaque ID for the
    1521 * underlying DOM element assigned by the server, or a promise that will
    1522 * resolve to that ID or another WebElement.
    1523 * @constructor
    1524 * @extends {webdriver.promise.Deferred}
    1525 */
    1526webdriver.WebElement = function(driver, id) {
    1527 webdriver.promise.Deferred.call(this, null, driver.controlFlow());
    1528
    1529 /**
    1530 * The parent WebDriver instance for this element.
    1531 * @private {!webdriver.WebDriver}
    1532 */
    1533 this.driver_ = driver;
    1534
    1535 // This class is responsible for resolving itself; delete the resolve and
    1536 // reject methods so they may not be accessed by consumers of this class.
    1537 var fulfill = goog.partial(this.fulfill, this);
    1538 var reject = this.reject;
    1539 delete this.promise;
    1540 delete this.fulfill;
    1541 delete this.reject;
    1542
    1543 /**
    1544 * A promise that resolves to the JSON representation of this WebElement's
    1545 * ID, as defined by the WebDriver wire protocol.
    1546 * @private {!webdriver.promise.Promise.<webdriver.WebElement.Id>}
    1547 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol
    1548 */
    1549 this.id_ = webdriver.promise.when(id, function(id) {
    1550 if (id instanceof webdriver.WebElement) {
    1551 return id.id_;
    1552 } else if (goog.isDef(id[webdriver.WebElement.ELEMENT_KEY])) {
    1553 return id;
    1554 }
    1555
    1556 var json = {};
    1557 json[webdriver.WebElement.ELEMENT_KEY] = id;
    1558 return json;
    1559 });
    1560
    1561 // This WebElement should not be resolved until its ID has been
    1562 // fully resolved.
    1563 this.id_.then(fulfill, reject);
    1564};
    1565goog.inherits(webdriver.WebElement, webdriver.promise.Deferred);
    1566
    1567
    1568/**
    1569 * Wire protocol definition of a WebElement ID.
    1570 * @typedef {{ELEMENT: string}}
    1571 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol
    1572 */
    1573webdriver.WebElement.Id;
    1574
    1575
    1576/**
    1577 * The property key used in the wire protocol to indicate that a JSON object
    1578 * contains the ID of a WebElement.
    1579 * @type {string}
    1580 * @const
    1581 */
    1582webdriver.WebElement.ELEMENT_KEY = 'ELEMENT';
    1583
    1584
    1585/**
    1586 * Compares to WebElements for equality.
    1587 * @param {!webdriver.WebElement} a A WebElement.
    1588 * @param {!webdriver.WebElement} b A WebElement.
    1589 * @return {!webdriver.promise.Promise.<boolean>} A promise that will be
    1590 * resolved to whether the two WebElements are equal.
    1591 */
    1592webdriver.WebElement.equals = function(a, b) {
    1593 if (a == b) {
    1594 return webdriver.promise.fulfilled(true);
    1595 }
    1596 return webdriver.promise.fullyResolved([a.id_, b.id_]).then(function(ids) {
    1597 // If the two element's have the same ID, they should be considered
    1598 // equal. Otherwise, they may still be equivalent, but we'll need to
    1599 // ask the server to check for us.
    1600 if (ids[0][webdriver.WebElement.ELEMENT_KEY] ==
    1601 ids[1][webdriver.WebElement.ELEMENT_KEY]) {
    1602 return true;
    1603 }
    1604
    1605 var command = new webdriver.Command(
    1606 webdriver.CommandName.ELEMENT_EQUALS);
    1607 command.setParameter('other', b);
    1608 return a.schedule_(command, 'webdriver.WebElement.equals()');
    1609 });
    1610};
    1611
    1612
    1613/**
    1614 * @return {!webdriver.WebDriver} The parent driver for this instance.
    1615 */
    1616webdriver.WebElement.prototype.getDriver = function() {
    1617 return this.driver_;
    1618};
    1619
    1620
    1621/**
    1622 * @return {!webdriver.promise.Promise.<webdriver.WebElement.Id>} A promise
    1623 * that resolves to this element's JSON representation as defined by the
    1624 * WebDriver wire protocol.
    1625 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol
    1626 */
    1627webdriver.WebElement.prototype.toWireValue = function() {
    1628 return this.id_;
    1629};
    1630
    1631
    1632/**
    1633 * Schedules a command that targets this element with the parent WebDriver
    1634 * instance. Will ensure this element's ID is included in the command parameters
    1635 * under the "id" key.
    1636 * @param {!webdriver.Command} command The command to schedule.
    1637 * @param {string} description A description of the command for debugging.
    1638 * @return {!webdriver.promise.Promise.<T>} A promise that will be resolved
    1639 * with the command result.
    1640 * @template T
    1641 * @see webdriver.WebDriver.prototype.schedule
    1642 * @private
    1643 */
    1644webdriver.WebElement.prototype.schedule_ = function(command, description) {
    1645 command.setParameter('id', this.id_);
    1646 return this.driver_.schedule(command, description);
    1647};
    1648
    1649
    1650/**
    1651 * Schedule a command to find a descendant of this element. If the element
    1652 * cannot be found, a {@code bot.ErrorCode.NO_SUCH_ELEMENT} result will
    1653 * be returned by the driver. Unlike other commands, this error cannot be
    1654 * suppressed. In other words, scheduling a command to find an element doubles
    1655 * as an assert that the element is present on the page. To test whether an
    1656 * element is present on the page, use {@code #isElementPresent} instead.
    1657 *
    1658 * <p>The search criteria for an element may be defined using one of the
    1659 * factories in the {@link webdriver.By} namespace, or as a short-hand
    1660 * {@link webdriver.By.Hash} object. For example, the following two statements
    1661 * are equivalent:
    1662 * <code><pre>
    1663 * var e1 = element.findElement(By.id('foo'));
    1664 * var e2 = element.findElement({id:'foo'});
    1665 * </pre></code>
    1666 *
    1667 * <p>You may also provide a custom locator function, which takes as input
    1668 * this WebDriver instance and returns a {@link webdriver.WebElement}, or a
    1669 * promise that will resolve to a WebElement. For example, to find the first
    1670 * visible link on a page, you could write:
    1671 * <code><pre>
    1672 * var link = element.findElement(firstVisibleLink);
    1673 *
    1674 * function firstVisibleLink(element) {
    1675 * var links = element.findElements(By.tagName('a'));
    1676 * return webdriver.promise.filter(links, function(link) {
    1677 * return links.isDisplayed();
    1678 * }).then(function(visibleLinks) {
    1679 * return visibleLinks[0];
    1680 * });
    1681 * }
    1682 * </pre></code>
    1683 *
    1684 * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The
    1685 * locator strategy to use when searching for the element.
    1686 * @return {!webdriver.WebElement} A WebElement that can be used to issue
    1687 * commands against the located element. If the element is not found, the
    1688 * element will be invalidated and all scheduled commands aborted.
    1689 */
    1690webdriver.WebElement.prototype.findElement = function(locator) {
    1691 locator = webdriver.Locator.checkLocator(locator);
    1692 var id;
    1693 if (goog.isFunction(locator)) {
    1694 id = this.driver_.findElementInternal_(locator, this);
    1695 } else {
    1696 var command = new webdriver.Command(
    1697 webdriver.CommandName.FIND_CHILD_ELEMENT).
    1698 setParameter('using', locator.using).
    1699 setParameter('value', locator.value);
    1700 id = this.schedule_(command, 'WebElement.findElement(' + locator + ')');
    1701 }
    1702 return new webdriver.WebElement(this.driver_, id);
    1703};
    1704
    1705
    1706/**
    1707 * Schedules a command to test if there is at least one descendant of this
    1708 * element that matches the given search criteria.
    1709 *
    1710 * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The
    1711 * locator strategy to use when searching for the element.
    1712 * @return {!webdriver.promise.Promise.<boolean>} A promise that will be
    1713 * resolved with whether an element could be located on the page.
    1714 */
    1715webdriver.WebElement.prototype.isElementPresent = function(locator) {
    1716 return this.findElements(locator).then(function(result) {
    1717 return !!result.length;
    1718 });
    1719};
    1720
    1721
    1722/**
    1723 * Schedules a command to find all of the descendants of this element that
    1724 * match the given search criteria.
    1725 *
    1726 * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The
    1727 * locator strategy to use when searching for the elements.
    1728 * @return {!webdriver.promise.Promise.<!Array.<!webdriver.WebElement>>} A
    1729 * promise that will resolve to an array of WebElements.
    1730 */
    1731webdriver.WebElement.prototype.findElements = function(locator) {
    1732 locator = webdriver.Locator.checkLocator(locator);
    1733 if (goog.isFunction(locator)) {
    1734 return this.driver_.findElementsInternal_(locator, this);
    1735 } else {
    1736 var command = new webdriver.Command(
    1737 webdriver.CommandName.FIND_CHILD_ELEMENTS).
    1738 setParameter('using', locator.using).
    1739 setParameter('value', locator.value);
    1740 return this.schedule_(command, 'WebElement.findElements(' + locator + ')');
    1741 }
    1742};
    1743
    1744
    1745/**
    1746 * Schedules a command to click on this element.
    1747 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1748 * when the click command has completed.
    1749 */
    1750webdriver.WebElement.prototype.click = function() {
    1751 return this.schedule_(
    1752 new webdriver.Command(webdriver.CommandName.CLICK_ELEMENT),
    1753 'WebElement.click()');
    1754};
    1755
    1756
    1757/**
    1758 * Schedules a command to type a sequence on the DOM element represented by this
    1759 * instance.
    1760 * <p/>
    1761 * Modifier keys (SHIFT, CONTROL, ALT, META) are stateful; once a modifier is
    1762 * processed in the keysequence, that key state is toggled until one of the
    1763 * following occurs:
    1764 * <ul>
    1765 * <li>The modifier key is encountered again in the sequence. At this point the
    1766 * state of the key is toggled (along with the appropriate keyup/down events).
    1767 * </li>
    1768 * <li>The {@code webdriver.Key.NULL} key is encountered in the sequence. When
    1769 * this key is encountered, all modifier keys current in the down state are
    1770 * released (with accompanying keyup events). The NULL key can be used to
    1771 * simulate common keyboard shortcuts:
    1772 * <code><pre>
    1773 * element.sendKeys("text was",
    1774 * webdriver.Key.CONTROL, "a", webdriver.Key.NULL,
    1775 * "now text is");
    1776 * // Alternatively:
    1777 * element.sendKeys("text was",
    1778 * webdriver.Key.chord(webdriver.Key.CONTROL, "a"),
    1779 * "now text is");
    1780 * </pre></code></li>
    1781 * <li>The end of the keysequence is encountered. When there are no more keys
    1782 * to type, all depressed modifier keys are released (with accompanying keyup
    1783 * events).
    1784 * </li>
    1785 * </ul>
    1786 * <strong>Note:</strong> On browsers where native keyboard events are not yet
    1787 * supported (e.g. Firefox on OS X), key events will be synthesized. Special
    1788 * punctionation keys will be synthesized according to a standard QWERTY en-us
    1789 * keyboard layout.
    1790 *
    1791 * @param {...string} var_args The sequence of keys to
    1792 * type. All arguments will be joined into a single sequence (var_args is
    1793 * permitted for convenience).
    1794 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1795 * when all keys have been typed.
    1796 */
    1797webdriver.WebElement.prototype.sendKeys = function(var_args) {
    1798 // Coerce every argument to a string. This protects us from users that
    1799 // ignore the jsdoc and give us a number (which ends up causing problems on
    1800 // the server, which requires strings).
    1801 var keys = webdriver.promise.fullyResolved(goog.array.slice(arguments, 0)).
    1802 then(function(args) {
    1803 return goog.array.map(goog.array.slice(args, 0), function(key) {
    1804 return key + '';
    1805 });
    1806 });
    1807 return this.schedule_(
    1808 new webdriver.Command(webdriver.CommandName.SEND_KEYS_TO_ELEMENT).
    1809 setParameter('value', keys),
    1810 'WebElement.sendKeys(' + keys + ')');
    1811};
    1812
    1813
    1814/**
    1815 * Schedules a command to query for the tag/node name of this element.
    1816 * @return {!webdriver.promise.Promise.<string>} A promise that will be
    1817 * resolved with the element's tag name.
    1818 */
    1819webdriver.WebElement.prototype.getTagName = function() {
    1820 return this.schedule_(
    1821 new webdriver.Command(webdriver.CommandName.GET_ELEMENT_TAG_NAME),
    1822 'WebElement.getTagName()');
    1823};
    1824
    1825
    1826/**
    1827 * Schedules a command to query for the computed style of the element
    1828 * represented by this instance. If the element inherits the named style from
    1829 * its parent, the parent will be queried for its value. Where possible, color
    1830 * values will be converted to their hex representation (e.g. #00ff00 instead of
    1831 * rgb(0, 255, 0)).
    1832 * <p/>
    1833 * <em>Warning:</em> the value returned will be as the browser interprets it, so
    1834 * it may be tricky to form a proper assertion.
    1835 *
    1836 * @param {string} cssStyleProperty The name of the CSS style property to look
    1837 * up.
    1838 * @return {!webdriver.promise.Promise.<string>} A promise that will be
    1839 * resolved with the requested CSS value.
    1840 */
    1841webdriver.WebElement.prototype.getCssValue = function(cssStyleProperty) {
    1842 var name = webdriver.CommandName.GET_ELEMENT_VALUE_OF_CSS_PROPERTY;
    1843 return this.schedule_(
    1844 new webdriver.Command(name).
    1845 setParameter('propertyName', cssStyleProperty),
    1846 'WebElement.getCssValue(' + cssStyleProperty + ')');
    1847};
    1848
    1849
    1850/**
    1851 * Schedules a command to query for the value of the given attribute of the
    1852 * element. Will return the current value, even if it has been modified after
    1853 * the page has been loaded. More exactly, this method will return the value of
    1854 * the given attribute, unless that attribute is not present, in which case the
    1855 * value of the property with the same name is returned. If neither value is
    1856 * set, null is returned (for example, the "value" property of a textarea
    1857 * element). The "style" attribute is converted as best can be to a
    1858 * text representation with a trailing semi-colon. The following are deemed to
    1859 * be "boolean" attributes and will return either "true" or null:
    1860 *
    1861 * <p>async, autofocus, autoplay, checked, compact, complete, controls, declare,
    1862 * defaultchecked, defaultselected, defer, disabled, draggable, ended,
    1863 * formnovalidate, hidden, indeterminate, iscontenteditable, ismap, itemscope,
    1864 * loop, multiple, muted, nohref, noresize, noshade, novalidate, nowrap, open,
    1865 * paused, pubdate, readonly, required, reversed, scoped, seamless, seeking,
    1866 * selected, spellcheck, truespeed, willvalidate
    1867 *
    1868 * <p>Finally, the following commonly mis-capitalized attribute/property names
    1869 * are evaluated as expected:
    1870 * <ul>
    1871 * <li>"class"
    1872 * <li>"readonly"
    1873 * </ul>
    1874 * @param {string} attributeName The name of the attribute to query.
    1875 * @return {!webdriver.promise.Promise.<?string>} A promise that will be
    1876 * resolved with the attribute's value. The returned value will always be
    1877 * either a string or null.
    1878 */
    1879webdriver.WebElement.prototype.getAttribute = function(attributeName) {
    1880 return this.schedule_(
    1881 new webdriver.Command(webdriver.CommandName.GET_ELEMENT_ATTRIBUTE).
    1882 setParameter('name', attributeName),
    1883 'WebElement.getAttribute(' + attributeName + ')');
    1884};
    1885
    1886
    1887/**
    1888 * Get the visible (i.e. not hidden by CSS) innerText of this element, including
    1889 * sub-elements, without any leading or trailing whitespace.
    1890 * @return {!webdriver.promise.Promise.<string>} A promise that will be
    1891 * resolved with the element's visible text.
    1892 */
    1893webdriver.WebElement.prototype.getText = function() {
    1894 return this.schedule_(
    1895 new webdriver.Command(webdriver.CommandName.GET_ELEMENT_TEXT),
    1896 'WebElement.getText()');
    1897};
    1898
    1899
    1900/**
    1901 * Schedules a command to compute the size of this element's bounding box, in
    1902 * pixels.
    1903 * @return {!webdriver.promise.Promise.<{width: number, height: number}>} A
    1904 * promise that will be resolved with the element's size as a
    1905 * {@code {width:number, height:number}} object.
    1906 */
    1907webdriver.WebElement.prototype.getSize = function() {
    1908 return this.schedule_(
    1909 new webdriver.Command(webdriver.CommandName.GET_ELEMENT_SIZE),
    1910 'WebElement.getSize()');
    1911};
    1912
    1913
    1914/**
    1915 * Schedules a command to compute the location of this element in page space.
    1916 * @return {!webdriver.promise.Promise.<{x: number, y: number}>} A promise that
    1917 * will be resolved to the element's location as a
    1918 * {@code {x:number, y:number}} object.
    1919 */
    1920webdriver.WebElement.prototype.getLocation = function() {
    1921 return this.schedule_(
    1922 new webdriver.Command(webdriver.CommandName.GET_ELEMENT_LOCATION),
    1923 'WebElement.getLocation()');
    1924};
    1925
    1926
    1927/**
    1928 * Schedules a command to query whether the DOM element represented by this
    1929 * instance is enabled, as dicted by the {@code disabled} attribute.
    1930 * @return {!webdriver.promise.Promise.<boolean>} A promise that will be
    1931 * resolved with whether this element is currently enabled.
    1932 */
    1933webdriver.WebElement.prototype.isEnabled = function() {
    1934 return this.schedule_(
    1935 new webdriver.Command(webdriver.CommandName.IS_ELEMENT_ENABLED),
    1936 'WebElement.isEnabled()');
    1937};
    1938
    1939
    1940/**
    1941 * Schedules a command to query whether this element is selected.
    1942 * @return {!webdriver.promise.Promise.<boolean>} A promise that will be
    1943 * resolved with whether this element is currently selected.
    1944 */
    1945webdriver.WebElement.prototype.isSelected = function() {
    1946 return this.schedule_(
    1947 new webdriver.Command(webdriver.CommandName.IS_ELEMENT_SELECTED),
    1948 'WebElement.isSelected()');
    1949};
    1950
    1951
    1952/**
    1953 * Schedules a command to submit the form containing this element (or this
    1954 * element if it is a FORM element). This command is a no-op if the element is
    1955 * not contained in a form.
    1956 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1957 * when the form has been submitted.
    1958 */
    1959webdriver.WebElement.prototype.submit = function() {
    1960 return this.schedule_(
    1961 new webdriver.Command(webdriver.CommandName.SUBMIT_ELEMENT),
    1962 'WebElement.submit()');
    1963};
    1964
    1965
    1966/**
    1967 * Schedules a command to clear the {@code value} of this element. This command
    1968 * has no effect if the underlying DOM element is neither a text INPUT element
    1969 * nor a TEXTAREA element.
    1970 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    1971 * when the element has been cleared.
    1972 */
    1973webdriver.WebElement.prototype.clear = function() {
    1974 return this.schedule_(
    1975 new webdriver.Command(webdriver.CommandName.CLEAR_ELEMENT),
    1976 'WebElement.clear()');
    1977};
    1978
    1979
    1980/**
    1981 * Schedules a command to test whether this element is currently displayed.
    1982 * @return {!webdriver.promise.Promise.<boolean>} A promise that will be
    1983 * resolved with whether this element is currently visible on the page.
    1984 */
    1985webdriver.WebElement.prototype.isDisplayed = function() {
    1986 return this.schedule_(
    1987 new webdriver.Command(webdriver.CommandName.IS_ELEMENT_DISPLAYED),
    1988 'WebElement.isDisplayed()');
    1989};
    1990
    1991
    1992/**
    1993 * Schedules a command to retrieve the outer HTML of this element.
    1994 * @return {!webdriver.promise.Promise.<string>} A promise that will be
    1995 * resolved with the element's outer HTML.
    1996 */
    1997webdriver.WebElement.prototype.getOuterHtml = function() {
    1998 return this.driver_.executeScript(function() {
    1999 var element = arguments[0];
    2000 if ('outerHTML' in element) {
    2001 return element.outerHTML;
    2002 } else {
    2003 var div = element.ownerDocument.createElement('div');
    2004 div.appendChild(element.cloneNode(true));
    2005 return div.innerHTML;
    2006 }
    2007 }, this);
    2008};
    2009
    2010
    2011/**
    2012 * Schedules a command to retrieve the inner HTML of this element.
    2013 * @return {!webdriver.promise.Promise.<string>} A promise that will be
    2014 * resolved with the element's inner HTML.
    2015 */
    2016webdriver.WebElement.prototype.getInnerHtml = function() {
    2017 return this.driver_.executeScript('return arguments[0].innerHTML', this);
    2018};
    2019
    2020
    2021
    2022/**
    2023 * Represents a modal dialog such as {@code alert}, {@code confirm}, or
    2024 * {@code prompt}. Provides functions to retrieve the message displayed with
    2025 * the alert, accept or dismiss the alert, and set the response text (in the
    2026 * case of {@code prompt}).
    2027 * @param {!webdriver.WebDriver} driver The driver controlling the browser this
    2028 * alert is attached to.
    2029 * @param {!(string|webdriver.promise.Promise.<string>)} text Either the
    2030 * message text displayed with this alert, or a promise that will be
    2031 * resolved to said text.
    2032 * @constructor
    2033 * @extends {webdriver.promise.Deferred}
    2034 */
    2035webdriver.Alert = function(driver, text) {
    2036 goog.base(this, null, driver.controlFlow());
    2037
    2038 /** @private {!webdriver.WebDriver} */
    2039 this.driver_ = driver;
    2040
    2041 // This class is responsible for resolving itself; delete the resolve and
    2042 // reject methods so they may not be accessed by consumers of this class.
    2043 var fulfill = goog.partial(this.fulfill, this);
    2044 var reject = this.reject;
    2045 delete this.promise;
    2046 delete this.fulfill;
    2047 delete this.reject;
    2048
    2049 /** @private {!webdriver.promise.Promise.<string>} */
    2050 this.text_ = webdriver.promise.when(text);
    2051
    2052 // Make sure this instance is resolved when its displayed text is.
    2053 this.text_.then(fulfill, reject);
    2054};
    2055goog.inherits(webdriver.Alert, webdriver.promise.Deferred);
    2056
    2057
    2058/**
    2059 * Retrieves the message text displayed with this alert. For instance, if the
    2060 * alert were opened with alert("hello"), then this would return "hello".
    2061 * @return {!webdriver.promise.Promise.<string>} A promise that will be
    2062 * resolved to the text displayed with this alert.
    2063 */
    2064webdriver.Alert.prototype.getText = function() {
    2065 return this.text_;
    2066};
    2067
    2068
    2069/**
    2070 * Accepts this alert.
    2071 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    2072 * when this command has completed.
    2073 */
    2074webdriver.Alert.prototype.accept = function() {
    2075 return this.driver_.schedule(
    2076 new webdriver.Command(webdriver.CommandName.ACCEPT_ALERT),
    2077 'WebDriver.switchTo().alert().accept()');
    2078};
    2079
    2080
    2081/**
    2082 * Dismisses this alert.
    2083 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    2084 * when this command has completed.
    2085 */
    2086webdriver.Alert.prototype.dismiss = function() {
    2087 return this.driver_.schedule(
    2088 new webdriver.Command(webdriver.CommandName.DISMISS_ALERT),
    2089 'WebDriver.switchTo().alert().dismiss()');
    2090};
    2091
    2092
    2093/**
    2094 * Sets the response text on this alert. This command will return an error if
    2095 * the underlying alert does not support response text (e.g. window.alert and
    2096 * window.confirm).
    2097 * @param {string} text The text to set.
    2098 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
    2099 * when this command has completed.
    2100 */
    2101webdriver.Alert.prototype.sendKeys = function(text) {
    2102 return this.driver_.schedule(
    2103 new webdriver.Command(webdriver.CommandName.SET_ALERT_TEXT).
    2104 setParameter('text', text),
    2105 'WebDriver.switchTo().alert().sendKeys(' + text + ')');
    2106};
    2107
    2108
    2109
    2110/**
    2111 * An error returned to indicate that there is an unhandled modal dialog on the
    2112 * current page.
    2113 * @param {string} message The error message.
    2114 * @param {!webdriver.Alert} alert The alert handle.
    2115 * @constructor
    2116 * @extends {bot.Error}
    2117 */
    2118webdriver.UnhandledAlertError = function(message, alert) {
    2119 goog.base(this, bot.ErrorCode.MODAL_DIALOG_OPENED, message);
    2120
    2121 /** @private {!webdriver.Alert} */
    2122 this.alert_ = alert;
    2123};
    2124goog.inherits(webdriver.UnhandledAlertError, bot.Error);
    2125
    2126
    2127/**
    2128 * @return {!webdriver.Alert} The open alert.
    2129 */
    2130webdriver.UnhandledAlertError.prototype.getAlert = function() {
    2131 return this.alert_;
    2132};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/net/index.js.src.html b/node_modules/selenium-webdriver/docs/source/net/index.js.src.html new file mode 100644 index 0000000..33b4995 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/net/index.js.src.html @@ -0,0 +1 @@ +index.js

    net/index.js

    1// Copyright 2013 Selenium committers
    2// Copyright 2013 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16'use strict';
    17
    18var os = require('os');
    19
    20
    21function getLoInterface() {
    22 var name;
    23 if (process.platform === 'darwin') {
    24 name = 'lo0';
    25 } else if (process.platform === 'linux') {
    26 name = 'lo';
    27 }
    28 return name ? os.networkInterfaces()[name] : null;
    29}
    30
    31
    32/**
    33 * Queries the system network interfaces for an IP address.
    34 * @param {boolean} loopback Whether to find a loopback address.
    35 * @param {string=} opt_family The IP family (IPv4 or IPv6). Defaults to IPv4.
    36 * @return {string} The located IP address or undefined.
    37 */
    38function getAddress(loopback, opt_family) {
    39 var family = opt_family || 'IPv4';
    40 var addresses = [];
    41
    42 var interfaces;
    43 if (loopback) {
    44 var lo = getLoInterface();
    45 interfaces = lo ? [lo] : null;
    46 }
    47 interfaces = interfaces || os.networkInterfaces();
    48 for (var key in interfaces) {
    49 interfaces[key].forEach(function(ipAddress) {
    50 if (ipAddress.family === family &&
    51 ipAddress.internal === loopback) {
    52 addresses.push(ipAddress.address);
    53 }
    54 });
    55 }
    56 return addresses[0];
    57}
    58
    59
    60// PUBLIC API
    61
    62
    63/**
    64 * Retrieves the external IP address for this host.
    65 * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4".
    66 * @return {string} The IP address or undefined if not available.
    67 */
    68exports.getAddress = function(opt_family) {
    69 return getAddress(false, opt_family);
    70};
    71
    72
    73/**
    74 * Retrieves a loopback address for this machine.
    75 * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4".
    76 * @return {string} The IP address or undefined if not available.
    77 */
    78exports.getLoopbackAddress = function(opt_family) {
    79 return getAddress(true, opt_family);
    80};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/net/portprober.js.src.html b/node_modules/selenium-webdriver/docs/source/net/portprober.js.src.html new file mode 100644 index 0000000..115b0c9 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/net/portprober.js.src.html @@ -0,0 +1 @@ +portprober.js

    net/portprober.js

    1// Copyright 2013 Selenium committers
    2// Copyright 2013 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16'use strict';
    17
    18var exec = require('child_process').exec,
    19 fs = require('fs'),
    20 net = require('net');
    21
    22var promise = require('../index').promise;
    23
    24
    25/**
    26 * The IANA suggested ephemeral port range.
    27 * @type {{min: number, max: number}}
    28 * @const
    29 * @see http://en.wikipedia.org/wiki/Ephemeral_ports
    30 */
    31var DEFAULT_IANA_RANGE = {min: 49152, max: 65535};
    32
    33
    34/**
    35 * The epheremal port range for the current system. Lazily computed on first
    36 * access.
    37 * @type {webdriver.promise.Promise.<{min: number, max: number}>}
    38 */
    39var systemRange = null;
    40
    41
    42/**
    43 * Computes the ephemeral port range for the current system. This is based on
    44 * http://stackoverflow.com/a/924337.
    45 * @return {webdriver.promise.Promise.<{min: number, max: number}>} A promise
    46 * that will resolve to the ephemeral port range of the current system.
    47 */
    48function findSystemPortRange() {
    49 if (systemRange) {
    50 return systemRange;
    51 }
    52 var range = process.platform === 'win32' ?
    53 findWindowsPortRange() : findUnixPortRange();
    54 return systemRange = range.thenCatch(function() {
    55 return DEFAULT_IANA_RANGE;
    56 });
    57}
    58
    59
    60/**
    61 * Executes a command and returns its output if it succeeds.
    62 * @param {string} cmd The command to execute.
    63 * @return {!webdriver.promise.Promise<string>} A promise that will resolve
    64 * with the command's stdout data.
    65 */
    66function execute(cmd) {
    67 var result = promise.defer();
    68 exec(cmd, function(err, stdout) {
    69 if (err) {
    70 result.reject(err);
    71 } else {
    72 result.fulfill(stdout);
    73 }
    74 });
    75 return result.promise;
    76}
    77
    78
    79/**
    80 * Computes the ephemeral port range for a Unix-like system.
    81 * @return {!webdriver.promise.Promise<{min: number, max: number}>} A promise
    82 * that will resolve with the ephemeral port range on the current system.
    83 */
    84function findUnixPortRange() {
    85 var cmd;
    86 if (process.platform === 'sunos') {
    87 cmd =
    88 '/usr/sbin/ndd /dev/tcp tcp_smallest_anon_port tcp_largest_anon_port';
    89 } else if (fs.existsSync('/proc/sys/net/ipv4/ip_local_port_range')) {
    90 // Linux
    91 cmd = 'cat /proc/sys/net/ipv4/ip_local_port_range';
    92 } else {
    93 cmd = 'sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last' +
    94 ' | sed -e "s/.*:\\s*//"';
    95 }
    96
    97 return execute(cmd).then(function(stdout) {
    98 if (!stdout || !stdout.length) return DEFAULT_IANA_RANGE;
    99 var range = stdout.trim().split(/\s+/).map(Number);
    100 if (range.some(isNaN)) return DEFAULT_IANA_RANGE;
    101 return {min: range[0], max: range[1]};
    102 });
    103}
    104
    105
    106/**
    107 * Computes the ephemeral port range for a Windows system.
    108 * @return {!webdriver.promise.Promise<{min: number, max: number}>} A promise
    109 * that will resolve with the ephemeral port range on the current system.
    110 */
    111function findWindowsPortRange() {
    112 var deferredRange = promise.defer();
    113 // First, check if we're running on XP. If this initial command fails,
    114 // we just fallback on the default IANA range.
    115 return execute('cmd.exe /c ver').then(function(stdout) {
    116 if (/Windows XP/.test(stdout)) {
    117 // TODO: Try to read these values from the registry.
    118 return {min: 1025, max: 5000};
    119 } else {
    120 return execute('netsh int ipv4 show dynamicport tcp').
    121 then(function(stdout) {
    122 /* > netsh int ipv4 show dynamicport tcp
    123 Protocol tcp Dynamic Port Range
    124 ---------------------------------
    125 Start Port : 49152
    126 Number of Ports : 16384
    127 */
    128 var range = stdout.split(/\n/).filter(function(line) {
    129 return /.*:\s*\d+/.test(line);
    130 }).map(function(line) {
    131 return Number(line.split(/:\s*/)[1]);
    132 });
    133
    134 return {
    135 min: range[0],
    136 max: range[0] + range[1]
    137 };
    138 });
    139 }
    140 });
    141}
    142
    143
    144/**
    145 * Tests if a port is free.
    146 * @param {number} port The port to test.
    147 * @param {string=} opt_host The bound host to test the {@code port} against.
    148 * Defaults to {@code INADDR_ANY}.
    149 * @return {!webdriver.promise.Promise.<boolean>} A promise that will resolve
    150 * with whether the port is free.
    151 */
    152function isFree(port, opt_host) {
    153 var result = promise.defer(function() {
    154 server.cancel();
    155 });
    156
    157 var server = net.createServer().on('error', function(e) {
    158 if (e.code === 'EADDRINUSE') {
    159 result.fulfill(false);
    160 } else {
    161 result.reject(e);
    162 }
    163 });
    164
    165 server.listen(port, opt_host, function() {
    166 server.close(function() {
    167 result.fulfill(true);
    168 });
    169 });
    170
    171 return result.promise;
    172}
    173
    174
    175/**
    176 * @param {string=} opt_host The bound host to test the {@code port} against.
    177 * Defaults to {@code INADDR_ANY}.
    178 * @return {!webdriver.promise.Promise.<number>} A promise that will resolve
    179 * to a free port. If a port cannot be found, the promise will be
    180 * rejected.
    181 */
    182function findFreePort(opt_host) {
    183 return findSystemPortRange().then(function(range) {
    184 var attempts = 0;
    185 var deferredPort = promise.defer();
    186 findPort();
    187 return deferredPort.promise;
    188
    189 function findPort() {
    190 attempts += 1;
    191 if (attempts > 10) {
    192 deferredPort.reject(Error('Unable to find a free port'));
    193 }
    194
    195 var port = Math.floor(
    196 Math.random() * (range.max - range.min) + range.min);
    197 isFree(port, opt_host).then(function(isFree) {
    198 if (isFree) {
    199 deferredPort.fulfill(port);
    200 } else {
    201 findPort();
    202 }
    203 });
    204 }
    205 });
    206}
    207
    208
    209// PUBLIC API
    210
    211
    212exports.findFreePort = findFreePort;
    213exports.isFree = isFree;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/phantomjs.js.src.html b/node_modules/selenium-webdriver/docs/source/phantomjs.js.src.html new file mode 100644 index 0000000..8988c7d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/phantomjs.js.src.html @@ -0,0 +1 @@ +phantomjs.js

    phantomjs.js

    1// Copyright 2013 Selenium committers
    2// Copyright 2013 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16'use strict';
    17
    18var fs = require('fs'),
    19 util = require('util');
    20
    21var webdriver = require('./index'),
    22 LogLevel = webdriver.logging.LevelName,
    23 executors = require('./executors'),
    24 io = require('./io'),
    25 portprober = require('./net/portprober'),
    26 remote = require('./remote');
    27
    28
    29/**
    30 * Name of the PhantomJS executable.
    31 * @type {string}
    32 * @const
    33 */
    34var PHANTOMJS_EXE =
    35 process.platform === 'win32' ? 'phantomjs.exe' : 'phantomjs';
    36
    37
    38/**
    39 * Capability that designates the location of the PhantomJS executable to use.
    40 * @type {string}
    41 * @const
    42 */
    43var BINARY_PATH_CAPABILITY = 'phantomjs.binary.path';
    44
    45
    46/**
    47 * Capability that designates the CLI arguments to pass to PhantomJS.
    48 * @type {string}
    49 * @const
    50 */
    51var CLI_ARGS_CAPABILITY = 'phantomjs.cli.args';
    52
    53
    54/**
    55 * Default log file to use if one is not specified through CLI args.
    56 * @type {string}
    57 * @const
    58 */
    59var DEFAULT_LOG_FILE = 'phantomjsdriver.log';
    60
    61
    62/**
    63 * Finds the PhantomJS executable.
    64 * @param {string=} opt_exe Path to the executable to use.
    65 * @return {string} The located executable.
    66 * @throws {Error} If the executable cannot be found on the PATH, or if the
    67 * provided executable path does not exist.
    68 */
    69function findExecutable(opt_exe) {
    70 var exe = opt_exe || io.findInPath(PHANTOMJS_EXE, true);
    71 if (!exe) {
    72 throw Error(
    73 'The PhantomJS executable could not be found on the current PATH. ' +
    74 'Please download the latest version from ' +
    75 'http://phantomjs.org/download.html and ensure it can be found on ' +
    76 'your PATH. For more information, see ' +
    77 'https://github.com/ariya/phantomjs/wiki');
    78 }
    79 if (!fs.existsSync(exe)) {
    80 throw Error('File does not exist: ' + exe);
    81 }
    82 return exe;
    83}
    84
    85
    86/**
    87 * Maps WebDriver logging level name to those recognised by PhantomJS.
    88 * @type {!Object.<webdriver.logging.LevelName, string>}
    89 * @const
    90 */
    91var WEBDRIVER_TO_PHANTOMJS_LEVEL = (function() {
    92 var map = {};
    93 map[LogLevel.ALL] = map[LogLevel.DEBUG] = 'DEBUG';
    94 map[LogLevel.INFO] = 'INFO';
    95 map[LogLevel.WARNING] = 'WARN';
    96 map[LogLevel.SEVERE] = map[LogLevel.OFF] = 'ERROR';
    97 return map;
    98})();
    99
    100
    101/**
    102 * Creates a new PhantomJS WebDriver client.
    103 * @param {webdriver.Capabilities=} opt_capabilities The desired capabilities.
    104 * @return {!webdriver.WebDriver} A new WebDriver instance.
    105 */
    106function createDriver(opt_capabilities) {
    107 var capabilities = opt_capabilities || webdriver.Capabilities.phantomjs();
    108 var exe = findExecutable(capabilities.get(BINARY_PATH_CAPABILITY));
    109 var args = ['--webdriver-logfile=' + DEFAULT_LOG_FILE];
    110
    111 var logPrefs = capabilities.get(webdriver.Capability.LOGGING_PREFS);
    112 if (logPrefs && logPrefs[webdriver.logging.Type.DRIVER]) {
    113 var level = WEBDRIVER_TO_PHANTOMJS_LEVEL[
    114 logPrefs[webdriver.logging.Type.DRIVER]];
    115 if (level) {
    116 args.push('--webdriver-loglevel=' + level);
    117 }
    118 }
    119
    120 var proxy = capabilities.get(webdriver.Capability.PROXY);
    121 if (proxy) {
    122 switch (proxy.proxyType) {
    123 case 'manual':
    124 if (proxy.httpProxy) {
    125 args.push(
    126 '--proxy-type=http',
    127 '--proxy=http://' + proxy.httpProxy);
    128 }
    129 break;
    130 case 'pac':
    131 throw Error('PhantomJS does not support Proxy PAC files');
    132 case 'system':
    133 args.push('--proxy-type=system');
    134 break;
    135 case 'direct':
    136 args.push('--proxy-type=none');
    137 break;
    138 }
    139 }
    140 args = args.concat(capabilities.get(CLI_ARGS_CAPABILITY) || []);
    141
    142 var port = portprober.findFreePort();
    143 var service = new remote.DriverService(exe, {
    144 port: port,
    145 args: webdriver.promise.when(port, function(port) {
    146 args.push('--webdriver=' + port);
    147 return args;
    148 })
    149 });
    150
    151 var executor = executors.createExecutor(service.start());
    152 var driver = webdriver.WebDriver.createSession(executor, capabilities);
    153 var boundQuit = driver.quit.bind(driver);
    154 driver.quit = function() {
    155 return boundQuit().thenFinally(service.kill.bind(service));
    156 };
    157 return driver;
    158}
    159
    160
    161// PUBLIC API
    162
    163
    164exports.createDriver = createDriver;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/proxy.js.src.html b/node_modules/selenium-webdriver/docs/source/proxy.js.src.html new file mode 100644 index 0000000..70d3c1d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/proxy.js.src.html @@ -0,0 +1 @@ +proxy.js

    proxy.js

    1// Copyright 2013 Selenium committers
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Defines functions for configuring a webdriver proxy:
    17 * <pre><code>
    18 * var webdriver = require('selenium-webdriver'),
    19 * proxy = require('selenium-webdriver/proxy');
    20 *
    21 * var driver = new webdriver.Builder()
    22 * .withCapabilities(webdriver.Capabilities.chrome())
    23 * .setProxy(proxy.manual({http: 'host:1234'}))
    24 * .build();
    25 * </code></pre>
    26 */
    27
    28'use strict';
    29
    30var util = require('util');
    31
    32
    33/**
    34 * Proxy configuration object, as defined by the WebDriver wire protocol.
    35 * @typedef {(
    36 * {proxyType: string}|
    37 * {proxyType: string,
    38 * proxyAutoconfigUrl: string}|
    39 * {proxyType: string,
    40 * ftpProxy: string,
    41 * httpProxy: string,
    42 * sslProxy: string,
    43 * noProxy: string})}
    44 */
    45var ProxyConfig;
    46
    47
    48
    49// PUBLIC API
    50
    51
    52/**
    53 * Configures WebDriver to bypass all browser proxies.
    54 * @return {!ProxyConfig} A new proxy configuration object.
    55 */
    56exports.direct = function() {
    57 return {proxyType: 'direct'};
    58};
    59
    60
    61/**
    62 * Manually configures the browser proxy. The following options are
    63 * supported:
    64 * <ul>
    65 * <li>{@code ftp}: Proxy host to use for FTP requests
    66 * <li>{@code http}: Proxy host to use for HTTP requests
    67 * <li>{@code https}: Proxy host to use for HTTPS requests
    68 * <li>{@code bypass}: A list of hosts requests should directly connect to,
    69 * bypassing any other proxies for that request. May be specified as a
    70 * comma separated string, or a list of strings.
    71 * </ul>
    72 *
    73 * Behavior is undefined for FTP, HTTP, and HTTPS requests if the
    74 * corresponding key is omitted from the configuration options.
    75 *
    76 * @param {{ftp: (string|undefined),
    77 * http: (string|undefined),
    78 * https: (string|undefined),
    79 * bypass: (string|!Array.<string>|undefined)}} options Proxy
    80 * configuration options.
    81 * @return {!ProxyConfig} A new proxy configuration object.
    82 */
    83exports.manual = function(options) {
    84 return {
    85 proxyType: 'manual',
    86 ftpProxy: options.ftp,
    87 httpProxy: options.http,
    88 sslProxy: options.https,
    89 noProxy: util.isArray(options.bypass) ?
    90 options.bypass.join(',') : options.bypass
    91 };
    92};
    93
    94
    95/**
    96 * Configures WebDriver to configure the browser proxy using the PAC file at
    97 * the given URL.
    98 * @param {string} url URL for the PAC proxy to use.
    99 * @return {!ProxyConfig} A new proxy configuration object.
    100 */
    101exports.pac = function(url) {
    102 return {
    103 proxyType: 'pac',
    104 proxyAutoconfigUrl: url
    105 };
    106};
    107
    108
    109/**
    110 * Configures WebDriver to use the current system's proxy.
    111 * @return {!ProxyConfig} A new proxy configuration object.
    112 */
    113exports.system = function() {
    114 return {proxyType: 'system'};
    115};
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/remote/index.js.src.html b/node_modules/selenium-webdriver/docs/source/remote/index.js.src.html new file mode 100644 index 0000000..7ba3bf2 --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/remote/index.js.src.html @@ -0,0 +1 @@ +index.js

    remote/index.js

    1// Copyright 2013 Software Freedom Conservancy
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15'use strict';
    16
    17var spawn = require('child_process').spawn,
    18 os = require('os'),
    19 path = require('path'),
    20 url = require('url'),
    21 util = require('util');
    22
    23var promise = require('../').promise,
    24 httpUtil = require('../http/util'),
    25 net = require('../net'),
    26 portprober = require('../net/portprober');
    27
    28
    29
    30/**
    31 * Configuration options for a DriverService instance.
    32 * <ul>
    33 * <li>
    34 * <li>{@code loopback} - Whether the service should only be accessed on this
    35 * host's loopback address.
    36 * <li>{@code port} - The port to start the server on (must be > 0). If the
    37 * port is provided as a promise, the service will wait for the promise to
    38 * resolve before starting.
    39 * <li>{@code args} - The arguments to pass to the service. If a promise is
    40 * provided, the service will wait for it to resolve before starting.
    41 * <li>{@code path} - The base path on the server for the WebDriver wire
    42 * protocol (e.g. '/wd/hub'). Defaults to '/'.
    43 * <li>{@code env} - The environment variables that should be visible to the
    44 * server process. Defaults to inheriting the current process's
    45 * environment.
    46 * <li>{@code stdio} - IO configuration for the spawned server process. For
    47 * more information, refer to the documentation of
    48 * {@code child_process.spawn}.
    49 * </ul>
    50 *
    51 * @typedef {{
    52 * port: (number|!webdriver.promise.Promise.<number>),
    53 * args: !(Array.<string>|webdriver.promise.Promise.<!Array.<string>>),
    54 * path: (string|undefined),
    55 * env: (!Object.<string, string>|undefined),
    56 * stdio: (string|!Array.<string|number|!Stream|null|undefined>|undefined)
    57 * }}
    58 */
    59var ServiceOptions;
    60
    61
    62/**
    63 * Manages the life and death of a native executable WebDriver server.
    64 *
    65 * <p>It is expected that the driver server implements the
    66 * <a href="http://code.google.com/p/selenium/wiki/JsonWireProtocol">WebDriver
    67 * Wire Protocol</a>. Furthermore, the managed server should support multiple
    68 * concurrent sessions, so that this class may be reused for multiple clients.
    69 *
    70 * @param {string} executable Path to the executable to run.
    71 * @param {!ServiceOptions} options Configuration options for the service.
    72 * @constructor
    73 */
    74function DriverService(executable, options) {
    75
    76 /** @private {string} */
    77 this.executable_ = executable;
    78
    79 /** @private {boolean} */
    80 this.loopbackOnly_ = !!options.loopback;
    81
    82 /** @private {(number|!webdriver.promise.Promise.<number>)} */
    83 this.port_ = options.port;
    84
    85 /**
    86 * @private {!(Array.<string>|webdriver.promise.Promise.<!Array.<string>>)}
    87 */
    88 this.args_ = options.args;
    89
    90 /** @private {string} */
    91 this.path_ = options.path || '/';
    92
    93 /** @private {!Object.<string, string>} */
    94 this.env_ = options.env || process.env;
    95
    96 /** @private {(string|!Array.<string|number|!Stream|null|undefined>)} */
    97 this.stdio_ = options.stdio || 'ignore';
    98}
    99
    100
    101/**
    102 * The default amount of time, in milliseconds, to wait for the server to
    103 * start.
    104 * @type {number}
    105 */
    106DriverService.DEFAULT_START_TIMEOUT_MS = 30 * 1000;
    107
    108
    109/** @private {child_process.ChildProcess} */
    110DriverService.prototype.process_ = null;
    111
    112
    113/**
    114 * Promise that resolves to the server's address or null if the server has not
    115 * been started.
    116 * @private {webdriver.promise.Promise.<string>}
    117 */
    118DriverService.prototype.address_ = null;
    119
    120
    121/**
    122 * Promise that tracks the status of shutting down the server, or null if the
    123 * server is not currently shutting down.
    124 * @private {webdriver.promise.Promise}
    125 */
    126DriverService.prototype.shutdownHook_ = null;
    127
    128
    129/**
    130 * @return {!webdriver.promise.Promise.<string>} A promise that resolves to
    131 * the server's address.
    132 * @throws {Error} If the server has not been started.
    133 */
    134DriverService.prototype.address = function() {
    135 if (this.address_) {
    136 return this.address_;
    137 }
    138 throw Error('Server has not been started.');
    139};
    140
    141
    142/**
    143 * @return {boolean} Whether the underlying service process is running.
    144 */
    145DriverService.prototype.isRunning = function() {
    146 return !!this.address_;
    147};
    148
    149
    150/**
    151 * Starts the server if it is not already running.
    152 * @param {number=} opt_timeoutMs How long to wait, in milliseconds, for the
    153 * server to start accepting requests. Defaults to 30 seconds.
    154 * @return {!webdriver.promise.Promise.<string>} A promise that will resolve
    155 * to the server's base URL when it has started accepting requests. If the
    156 * timeout expires before the server has started, the promise will be
    157 * rejected.
    158 */
    159DriverService.prototype.start = function(opt_timeoutMs) {
    160 if (this.address_) {
    161 return this.address_;
    162 }
    163
    164 var timeout = opt_timeoutMs || DriverService.DEFAULT_START_TIMEOUT_MS;
    165
    166 var self = this;
    167 this.address_ = promise.defer();
    168 this.address_.fulfill(promise.when(this.port_, function(port) {
    169 if (port <= 0) {
    170 throw Error('Port must be > 0: ' + port);
    171 }
    172 return promise.when(self.args_, function(args) {
    173 self.process_ = spawn(self.executable_, args, {
    174 env: self.env_,
    175 stdio: self.stdio_
    176 }).once('exit', onServerExit);
    177
    178 // This process should not wait on the spawned child, however, we do
    179 // want to ensure the child is killed when this process exits.
    180 self.process_.unref();
    181 process.once('exit', killServer);
    182
    183 var serverUrl = url.format({
    184 protocol: 'http',
    185 hostname: !self.loopbackOnly_ && net.getAddress() ||
    186 net.getLoopbackAddress(),
    187 port: port,
    188 pathname: self.path_
    189 });
    190
    191 return httpUtil.waitForServer(serverUrl, timeout).then(function() {
    192 return serverUrl;
    193 });
    194 });
    195 }));
    196
    197 return this.address_;
    198
    199 function onServerExit(code, signal) {
    200 self.address_.reject(code == null ?
    201 Error('Server was killed with ' + signal) :
    202 Error('Server exited with ' + code));
    203
    204 if (self.shutdownHook_) {
    205 self.shutdownHook_.fulfill();
    206 }
    207
    208 self.shutdownHook_ = null;
    209 self.address_ = null;
    210 self.process_ = null;
    211 process.removeListener('exit', killServer);
    212 }
    213
    214 function killServer() {
    215 process.removeListener('exit', killServer);
    216 self.process_ && self.process_.kill('SIGTERM');
    217 }
    218};
    219
    220
    221/**
    222 * Stops the service if it is not currently running. This function will kill
    223 * the server immediately. To synchronize with the active control flow, use
    224 * {@link #stop()}.
    225 * @return {!webdriver.promise.Promise} A promise that will be resolved when
    226 * the server has been stopped.
    227 */
    228DriverService.prototype.kill = function() {
    229 if (!this.address_) {
    230 return promise.fulfilled(); // Not currently running.
    231 }
    232
    233 if (!this.shutdownHook_) {
    234 // No process: still starting; wait on address.
    235 // Otherwise, kill the process now. Exit handler will resolve the
    236 // shutdown hook.
    237 if (this.process_) {
    238 this.shutdownHook_ = promise.defer();
    239 this.process_.kill('SIGTERM');
    240 } else {
    241 var self = this;
    242 this.shutdownHook_ = this.address_.thenFinally(function() {
    243 self.process_ && self.process_.kill('SIGTERM');
    244 });
    245 }
    246 }
    247
    248 return this.shutdownHook_;
    249};
    250
    251
    252/**
    253 * Schedules a task in the current control flow to stop the server if it is
    254 * currently running.
    255 * @return {!webdriver.promise.Promise} A promise that will be resolved when
    256 * the server has been stopped.
    257 */
    258DriverService.prototype.stop = function() {
    259 return promise.controlFlow().execute(this.kill.bind(this));
    260};
    261
    262
    263
    264/**
    265 * Manages the life and death of the Selenium standalone server. The server
    266 * may be obtained from http://selenium-release.storage.googleapis.com/index.html.
    267 * @param {string} jar Path to the Selenium server jar.
    268 * @param {!SeleniumServer.Options} options Configuration options for the
    269 * server.
    270 * @throws {Error} If an invalid port is specified.
    271 * @constructor
    272 * @extends {DriverService}
    273 */
    274function SeleniumServer(jar, options) {
    275 if (options.port < 0)
    276 throw Error('Port must be >= 0: ' + options.port);
    277
    278 var port = options.port || portprober.findFreePort();
    279 var args = promise.when(options.jvmArgs || [], function(jvmArgs) {
    280 return promise.when(options.args || [], function(args) {
    281 return promise.when(port, function(port) {
    282 return jvmArgs.concat(['-jar', jar, '-port', port]).concat(args);
    283 });
    284 });
    285 });
    286
    287 DriverService.call(this, 'java', {
    288 port: port,
    289 args: args,
    290 path: '/wd/hub',
    291 env: options.env,
    292 stdio: options.stdio
    293 });
    294}
    295util.inherits(SeleniumServer, DriverService);
    296
    297
    298/**
    299 * Options for the Selenium server:
    300 * <ul>
    301 * <li>{@code port} - The port to start the server on (must be > 0). If the
    302 * port is provided as a promise, the service will wait for the promise to
    303 * resolve before starting.
    304 * <li>{@code args} - The arguments to pass to the service. If a promise is
    305 * provided, the service will wait for it to resolve before starting.
    306 * <li>{@code jvmArgs} - The arguments to pass to the JVM. If a promise is
    307 * provided, the service will wait for it to resolve before starting.
    308 * <li>{@code env} - The environment variables that should be visible to the
    309 * server process. Defaults to inheriting the current process's
    310 * environment.
    311 * <li>{@code stdio} - IO configuration for the spawned server process. For
    312 * more information, refer to the documentation of
    313 * {@code child_process.spawn}.
    314 * </ul>
    315 *
    316 * @typedef {{
    317 * port: (number|!webdriver.promise.Promise.<number>),
    318 * args: !(Array.<string>|webdriver.promise.Promise.<!Array.<string>>),
    319 * jvmArgs: (!Array.<string>|
    320 * !webdriver.promise.Promise.<!Array.<string>>|
    321 * undefined),
    322 * env: (!Object.<string, string>|undefined),
    323 * stdio: (string|!Array.<string|number|!Stream|null|undefined>|undefined)
    324 * }}
    325 */
    326SeleniumServer.Options;
    327
    328
    329// PUBLIC API
    330
    331exports.DriverService = DriverService;
    332exports.SeleniumServer = SeleniumServer;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/testing/assert.js.src.html b/node_modules/selenium-webdriver/docs/source/testing/assert.js.src.html new file mode 100644 index 0000000..125141d --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/testing/assert.js.src.html @@ -0,0 +1 @@ +assert.js

    testing/assert.js

    1// Copyright 2013 Software Freedom Conservancy
    2//
    3// Licensed under the Apache License, Version 2.0 (the "License");
    4// you may not use this file except in compliance with the License.
    5// You may obtain a copy of the License at
    6//
    7// http://www.apache.org/licenses/LICENSE-2.0
    8//
    9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15/**
    16 * @fileoverview Defines a library that simplifies writing assertions against
    17 * promised values.
    18 *
    19 * <blockquote>
    20 * <hr>
    21 * <b>NOTE:</b> This module is considered experimental and is subject to
    22 * change, or removal, at any time!
    23 * <hr>
    24 * </blockquote>
    25 *
    26 * Sample usage:
    27 * <pre><code>
    28 * var driver = new webdriver.Builder().build();
    29 * driver.get('http://www.google.com');
    30 *
    31 * assert(driver.getTitle()).equalTo('Google');
    32 * </code></pre>
    33 */
    34
    35var base = require('../_base'),
    36 assert = base.require('webdriver.testing.assert');
    37
    38
    39// PUBLIC API
    40
    41
    42/** @type {webdriver.testing.assert.} */
    43module.exports = assert;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/source/testing/index.js.src.html b/node_modules/selenium-webdriver/docs/source/testing/index.js.src.html new file mode 100644 index 0000000..b53398e --- /dev/null +++ b/node_modules/selenium-webdriver/docs/source/testing/index.js.src.html @@ -0,0 +1 @@ +index.js

    testing/index.js

    1// Copyright 2013 Selenium committers
    2// Copyright 2013 Software Freedom Conservancy
    3//
    4// Licensed under the Apache License, Version 2.0 (the "License");
    5// you may not use this file except in compliance with the License.
    6// You may obtain a copy of the License at
    7//
    8// http://www.apache.org/licenses/LICENSE-2.0
    9//
    10// Unless required by applicable law or agreed to in writing, software
    11// distributed under the License is distributed on an "AS IS" BASIS,
    12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13// See the License for the specific language governing permissions and
    14// limitations under the License.
    15
    16/**
    17 * @fileoverview Provides wrappers around the following global functions from
    18 * <a href="http://visionmedia.github.io/mocha/">Mocha's BDD interface</a>:
    19 * <ul>
    20 * <li>after
    21 * <li>afterEach
    22 * <li>before
    23 * <li>beforeEach
    24 * <li>it
    25 * <li>it.only
    26 * <li>it.skip
    27 * <li>xit
    28 * </ul>
    29 *
    30 * <p>The provided wrappers leverage the {@link webdriver.promise.ControlFlow}
    31 * to simplify writing asynchronous tests:
    32 * <pre><code>
    33 * var webdriver = require('selenium-webdriver'),
    34 * portprober = require('selenium-webdriver/net/portprober'),
    35 * remote = require('selenium-webdriver/remote'),
    36 * test = require('selenium-webdriver/testing');
    37 *
    38 * test.describe('Google Search', function() {
    39 * var driver, server;
    40 *
    41 * test.before(function() {
    42 * server = new remote.SeleniumServer(
    43 * 'path/to/selenium-server-standalone.jar',
    44 * {port: portprober.findFreePort()});
    45 * server.start();
    46 *
    47 * driver = new webdriver.Builder().
    48 * withCapabilities({'browserName': 'firefox'}).
    49 * usingServer(server.address()).
    50 * build();
    51 * });
    52 *
    53 * test.after(function() {
    54 * driver.quit();
    55 * server.stop();
    56 * });
    57 *
    58 * test.it('should append query to title', function() {
    59 * driver.get('http://www.google.com');
    60 * driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
    61 * driver.findElement(webdriver.By.name('btnG')).click();
    62 * driver.wait(function() {
    63 * return driver.getTitle().then(function(title) {
    64 * return 'webdriver - Google Search' === title;
    65 * });
    66 * }, 1000, 'Waiting for title to update');
    67 * });
    68 * });
    69 * </code></pre>
    70 *
    71 * <p>You may conditionally suppress a test function using the exported
    72 * "ignore" function. If the provided predicate returns true, the attached
    73 * test case will be skipped:
    74 * <pre><code>
    75 * test.ignore(maybe()).it('is flaky', function() {
    76 * if (Math.random() < 0.5) throw Error();
    77 * });
    78 *
    79 * function maybe() { return Math.random() < 0.5; }
    80 * </code></pre>
    81 */
    82
    83var promise = require('..').promise;
    84var flow = promise.controlFlow();
    85
    86
    87/**
    88 * Wraps a function so that all passed arguments are ignored.
    89 * @param {!Function} fn The function to wrap.
    90 * @return {!Function} The wrapped function.
    91 */
    92function seal(fn) {
    93 return function() {
    94 fn();
    95 };
    96}
    97
    98
    99/**
    100 * Wraps a function on Mocha's BDD interface so it runs inside a
    101 * webdriver.promise.ControlFlow and waits for the flow to complete before
    102 * continuing.
    103 * @param {!Function} globalFn The function to wrap.
    104 * @return {!Function} The new function.
    105 */
    106function wrapped(globalFn) {
    107 return function() {
    108 switch (arguments.length) {
    109 case 1:
    110 globalFn(asyncTestFn(arguments[0]));
    111 break;
    112
    113 case 2:
    114 globalFn(arguments[0], asyncTestFn(arguments[1]));
    115 break;
    116
    117 default:
    118 throw Error('Invalid # arguments: ' + arguments.length);
    119 }
    120 };
    121
    122 function asyncTestFn(fn) {
    123 var ret = function(done) {
    124 this.timeout(0);
    125 var timeout = this.timeout;
    126 this.timeout = undefined; // Do not let tests change the timeout.
    127 try {
    128 var testFn = fn.bind(this);
    129 flow.execute(function() {
    130 var done = promise.defer();
    131 promise.asap(testFn(done.reject), done.fulfill, done.reject);
    132 return done.promise;
    133 }).then(seal(done), done);
    134 } finally {
    135 this.timeout = timeout;
    136 }
    137 };
    138
    139 ret.toString = function() {
    140 return fn.toString();
    141 };
    142
    143 return ret;
    144 }
    145}
    146
    147
    148/**
    149 * Ignores the test chained to this function if the provided predicate returns
    150 * true.
    151 * @param {function(): boolean} predicateFn A predicate to call to determine
    152 * if the test should be suppressed. This function MUST be synchronous.
    153 * @return {!Object} An object with wrapped versions of {@link #it()} and
    154 * {@link #describe()} that ignore tests as indicated by the predicate.
    155 */
    156function ignore(predicateFn) {
    157 var describe = wrap(exports.xdescribe, exports.describe);
    158 describe.only = wrap(exports.xdescribe, exports.describe.only);
    159
    160 var it = wrap(exports.xit, exports.it);
    161 it.only = wrap(exports.xit, exports.it.only);
    162
    163 return {
    164 describe: describe,
    165 it: it
    166 };
    167
    168 function wrap(onSkip, onRun) {
    169 return function(title, fn) {
    170 if (predicateFn()) {
    171 onSkip(title, fn);
    172 } else {
    173 onRun(title, fn);
    174 }
    175 };
    176 }
    177}
    178
    179
    180// PUBLIC API
    181
    182/**
    183 * Registers a new test suite.
    184 * @param {string} name The suite name.
    185 * @param {function()=} fn The suite function, or {@code undefined} to define
    186 * a pending test suite.
    187 */
    188exports.describe = global.describe;
    189
    190/**
    191 * Defines a suppressed test suite.
    192 * @param {string} name The suite name.
    193 * @param {function()=} fn The suite function, or {@code undefined} to define
    194 * a pending test suite.
    195 */
    196exports.xdescribe = global.xdescribe;
    197exports.describe.skip = global.describe.skip;
    198
    199/**
    200 * Register a function to call after the current suite finishes.
    201 * @param {function()} fn .
    202 */
    203exports.after = wrapped(global.after);
    204
    205/**
    206 * Register a function to call after each test in a suite.
    207 * @param {function()} fn .
    208 */
    209exports.afterEach = wrapped(global.afterEach);
    210
    211/**
    212 * Register a function to call before the current suite starts.
    213 * @param {function()} fn .
    214 */
    215exports.before = wrapped(global.before);
    216
    217/**
    218 * Register a function to call before each test in a suite.
    219 * @param {function()} fn .
    220 */
    221exports.beforeEach = wrapped(global.beforeEach);
    222
    223/**
    224 * Add a test to the current suite.
    225 * @param {string} name The test name.
    226 * @param {function()=} fn The test function, or {@code undefined} to define
    227 * a pending test case.
    228 */
    229exports.it = wrapped(global.it);
    230
    231/**
    232 * An alias for {@link #it()} that flags the test as the only one that should
    233 * be run within the current suite.
    234 * @param {string} name The test name.
    235 * @param {function()=} fn The test function, or {@code undefined} to define
    236 * a pending test case.
    237 */
    238exports.iit = exports.it.only = wrapped(global.it.only);
    239
    240/**
    241 * Adds a test to the current suite while suppressing it so it is not run.
    242 * @param {string} name The test name.
    243 * @param {function()=} fn The test function, or {@code undefined} to define
    244 * a pending test case.
    245 */
    246exports.xit = exports.it.skip = wrapped(global.xit);
    247
    248exports.ignore = ignore;
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/docs/types.js b/node_modules/selenium-webdriver/docs/types.js new file mode 100644 index 0000000..7d2bb8b --- /dev/null +++ b/node_modules/selenium-webdriver/docs/types.js @@ -0,0 +1 @@ +var TYPES = {"files":[{"name":"_base.js","href":"source/_base.js.src.html"},{"name":"builder.js","href":"source/builder.js.src.html"},{"name":"chrome.js","href":"source/chrome.js.src.html"},{"name":"error.js","href":"source/error.js.src.html"},{"name":"executors.js","href":"source/executors.js.src.html"},{"name":"http/index.js","href":"source/http/index.js.src.html"},{"name":"http/util.js","href":"source/http/util.js.src.html"},{"name":"index.js","href":"source/index.js.src.html"},{"name":"io/index.js","href":"source/io/index.js.src.html"},{"name":"lib/atoms/error.js","href":"source/lib/atoms/error.js.src.html"},{"name":"lib/atoms/json.js","href":"source/lib/atoms/json.js.src.html"},{"name":"lib/atoms/response.js","href":"source/lib/atoms/response.js.src.html"},{"name":"lib/atoms/userAgent.js","href":"source/lib/atoms/userAgent.js.src.html"},{"name":"lib/goog/array/array.js","href":"source/lib/goog/array/array.js.src.html"},{"name":"lib/goog/asserts/asserts.js","href":"source/lib/goog/asserts/asserts.js.src.html"},{"name":"lib/goog/base.js","href":"source/lib/goog/base.js.src.html"},{"name":"lib/goog/debug/error.js","href":"source/lib/goog/debug/error.js.src.html"},{"name":"lib/goog/deps.js","href":"source/lib/goog/deps.js.src.html"},{"name":"lib/goog/dom/nodetype.js","href":"source/lib/goog/dom/nodetype.js.src.html"},{"name":"lib/goog/functions/functions.js","href":"source/lib/goog/functions/functions.js.src.html"},{"name":"lib/goog/iter/iter.js","href":"source/lib/goog/iter/iter.js.src.html"},{"name":"lib/goog/json/json.js","href":"source/lib/goog/json/json.js.src.html"},{"name":"lib/goog/labs/testing/assertthat.js","href":"source/lib/goog/labs/testing/assertthat.js.src.html"},{"name":"lib/goog/labs/testing/logicmatcher.js","href":"source/lib/goog/labs/testing/logicmatcher.js.src.html"},{"name":"lib/goog/labs/testing/matcher.js","href":"source/lib/goog/labs/testing/matcher.js.src.html"},{"name":"lib/goog/labs/testing/numbermatcher.js","href":"source/lib/goog/labs/testing/numbermatcher.js.src.html"},{"name":"lib/goog/labs/testing/objectmatcher.js","href":"source/lib/goog/labs/testing/objectmatcher.js.src.html"},{"name":"lib/goog/labs/testing/stringmatcher.js","href":"source/lib/goog/labs/testing/stringmatcher.js.src.html"},{"name":"lib/goog/labs/useragent/browser.js","href":"source/lib/goog/labs/useragent/browser.js.src.html"},{"name":"lib/goog/labs/useragent/engine.js","href":"source/lib/goog/labs/useragent/engine.js.src.html"},{"name":"lib/goog/labs/useragent/util.js","href":"source/lib/goog/labs/useragent/util.js.src.html"},{"name":"lib/goog/math/math.js","href":"source/lib/goog/math/math.js.src.html"},{"name":"lib/goog/net/wrapperxmlhttpfactory.js","href":"source/lib/goog/net/wrapperxmlhttpfactory.js.src.html"},{"name":"lib/goog/net/xhrlike.js","href":"source/lib/goog/net/xhrlike.js.src.html"},{"name":"lib/goog/net/xmlhttp.js","href":"source/lib/goog/net/xmlhttp.js.src.html"},{"name":"lib/goog/net/xmlhttpfactory.js","href":"source/lib/goog/net/xmlhttpfactory.js.src.html"},{"name":"lib/goog/object/object.js","href":"source/lib/goog/object/object.js.src.html"},{"name":"lib/goog/string/string.js","href":"source/lib/goog/string/string.js.src.html"},{"name":"lib/goog/structs/map.js","href":"source/lib/goog/structs/map.js.src.html"},{"name":"lib/goog/structs/structs.js","href":"source/lib/goog/structs/structs.js.src.html"},{"name":"lib/goog/uri/uri.js","href":"source/lib/goog/uri/uri.js.src.html"},{"name":"lib/goog/uri/utils.js","href":"source/lib/goog/uri/utils.js.src.html"},{"name":"lib/goog/useragent/product.js","href":"source/lib/goog/useragent/product.js.src.html"},{"name":"lib/goog/useragent/product_isversion.js","href":"source/lib/goog/useragent/product_isversion.js.src.html"},{"name":"lib/goog/useragent/useragent.js","href":"source/lib/goog/useragent/useragent.js.src.html"},{"name":"lib/webdriver/abstractbuilder.js","href":"source/lib/webdriver/abstractbuilder.js.src.html"},{"name":"lib/webdriver/actionsequence.js","href":"source/lib/webdriver/actionsequence.js.src.html"},{"name":"lib/webdriver/builder.js","href":"source/lib/webdriver/builder.js.src.html"},{"name":"lib/webdriver/button.js","href":"source/lib/webdriver/button.js.src.html"},{"name":"lib/webdriver/capabilities.js","href":"source/lib/webdriver/capabilities.js.src.html"},{"name":"lib/webdriver/command.js","href":"source/lib/webdriver/command.js.src.html"},{"name":"lib/webdriver/events.js","href":"source/lib/webdriver/events.js.src.html"},{"name":"lib/webdriver/firefoxdomexecutor.js","href":"source/lib/webdriver/firefoxdomexecutor.js.src.html"},{"name":"lib/webdriver/http/corsclient.js","href":"source/lib/webdriver/http/corsclient.js.src.html"},{"name":"lib/webdriver/http/http.js","href":"source/lib/webdriver/http/http.js.src.html"},{"name":"lib/webdriver/http/xhrclient.js","href":"source/lib/webdriver/http/xhrclient.js.src.html"},{"name":"lib/webdriver/key.js","href":"source/lib/webdriver/key.js.src.html"},{"name":"lib/webdriver/locators.js","href":"source/lib/webdriver/locators.js.src.html"},{"name":"lib/webdriver/logging.js","href":"source/lib/webdriver/logging.js.src.html"},{"name":"lib/webdriver/process.js","href":"source/lib/webdriver/process.js.src.html"},{"name":"lib/webdriver/promise.js","href":"source/lib/webdriver/promise.js.src.html"},{"name":"lib/webdriver/session.js","href":"source/lib/webdriver/session.js.src.html"},{"name":"lib/webdriver/stacktrace.js","href":"source/lib/webdriver/stacktrace.js.src.html"},{"name":"lib/webdriver/testing/asserts.js","href":"source/lib/webdriver/testing/asserts.js.src.html"},{"name":"lib/webdriver/webdriver.js","href":"source/lib/webdriver/webdriver.js.src.html"},{"name":"net/index.js","href":"source/net/index.js.src.html"},{"name":"net/portprober.js","href":"source/net/portprober.js.src.html"},{"name":"phantomjs.js","href":"source/phantomjs.js.src.html"},{"name":"proxy.js","href":"source/proxy.js.src.html"},{"name":"remote/index.js","href":"source/remote/index.js.src.html"},{"name":"testing/assert.js","href":"source/testing/assert.js.src.html"},{"name":"testing/index.js","href":"source/testing/index.js.src.html"}],"types":[{"isInterface":false,"name":"bot","isTypedef":false,"href":"namespace_bot.html"},{"isInterface":false,"name":"bot.Error","isTypedef":false,"href":"class_bot_Error.html"},{"isInterface":false,"name":"bot.Error.State","isTypedef":false,"href":"enum_bot_Error_State.html"},{"isInterface":false,"name":"bot.ErrorCode","isTypedef":false,"href":"enum_bot_ErrorCode.html"},{"isInterface":false,"name":"bot.json","isTypedef":false,"href":"namespace_bot_json.html"},{"isInterface":false,"name":"bot.response","isTypedef":false,"href":"namespace_bot_response.html"},{"name":"bot.response.ResponseObject","isTypedef":true,"href":"namespace_bot_response.html#bot.response.ResponseObject"},{"isInterface":false,"name":"bot.userAgent","isTypedef":false,"href":"namespace_bot_userAgent.html"},{"isInterface":false,"name":"goog","isTypedef":false,"href":"namespace_goog.html"},{"isInterface":false,"name":"goog.Uri","isTypedef":false,"href":"class_goog_Uri.html"},{"isInterface":false,"name":"goog.Uri.QueryData","isTypedef":false,"href":"class_goog_Uri_QueryData.html"},{"isInterface":false,"name":"goog.array","isTypedef":false,"href":"namespace_goog_array.html"},{"name":"goog.array.ArrayLike","isTypedef":true,"href":"namespace_goog_array.html#goog.array.ArrayLike"},{"isInterface":false,"name":"goog.asserts","isTypedef":false,"href":"namespace_goog_asserts.html"},{"isInterface":false,"name":"goog.asserts.AssertionError","isTypedef":false,"href":"class_goog_asserts_AssertionError.html"},{"isInterface":false,"name":"goog.debug","isTypedef":false,"href":"namespace_goog_debug.html"},{"isInterface":false,"name":"goog.debug.Error","isTypedef":false,"href":"class_goog_debug_Error.html"},{"isInterface":false,"name":"goog.dom","isTypedef":false,"href":"namespace_goog_dom.html"},{"isInterface":false,"name":"goog.dom.NodeType","isTypedef":false,"href":"enum_goog_dom_NodeType.html"},{"isInterface":false,"name":"goog.functions","isTypedef":false,"href":"namespace_goog_functions.html"},{"isInterface":false,"name":"goog.iter","isTypedef":false,"href":"namespace_goog_iter.html"},{"name":"goog.iter.Iterable","isTypedef":true,"href":"namespace_goog_iter.html#goog.iter.Iterable"},{"isInterface":false,"name":"goog.iter.GroupByIterator_","isTypedef":false,"href":"class_goog_iter_GroupByIterator_.html"},{"isInterface":false,"name":"goog.iter.Iterator","isTypedef":false,"href":"class_goog_iter_Iterator.html"},{"isInterface":false,"name":"goog.json","isTypedef":false,"href":"namespace_goog_json.html"},{"name":"goog.json.Replacer","isTypedef":true,"href":"namespace_goog_json.html#goog.json.Replacer"},{"name":"goog.json.Reviver","isTypedef":true,"href":"namespace_goog_json.html#goog.json.Reviver"},{"isInterface":false,"name":"goog.json.Serializer","isTypedef":false,"href":"class_goog_json_Serializer.html"},{"isInterface":false,"name":"goog.labs","isTypedef":false,"href":"namespace_goog_labs.html"},{"isInterface":false,"name":"goog.labs.testing","isTypedef":false,"href":"namespace_goog_labs_testing.html"},{"isInterface":false,"name":"goog.labs.testing.AllOfMatcher","isTypedef":false,"href":"class_goog_labs_testing_AllOfMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.AnyOfMatcher","isTypedef":false,"href":"class_goog_labs_testing_AnyOfMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.CloseToMatcher","isTypedef":false,"href":"class_goog_labs_testing_CloseToMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.ContainsStringMatcher","isTypedef":false,"href":"class_goog_labs_testing_ContainsStringMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.EndsWithMatcher","isTypedef":false,"href":"class_goog_labs_testing_EndsWithMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.EqualToIgnoringWhitespaceMatcher","isTypedef":false,"href":"class_goog_labs_testing_EqualToIgnoringWhitespaceMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.EqualToMatcher","isTypedef":false,"href":"class_goog_labs_testing_EqualToMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.EqualsMatcher","isTypedef":false,"href":"class_goog_labs_testing_EqualsMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.GreaterThanEqualToMatcher","isTypedef":false,"href":"class_goog_labs_testing_GreaterThanEqualToMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.GreaterThanMatcher","isTypedef":false,"href":"class_goog_labs_testing_GreaterThanMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.HasPropertyMatcher","isTypedef":false,"href":"class_goog_labs_testing_HasPropertyMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.InstanceOfMatcher","isTypedef":false,"href":"class_goog_labs_testing_InstanceOfMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.IsNotMatcher","isTypedef":false,"href":"class_goog_labs_testing_IsNotMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.IsNullMatcher","isTypedef":false,"href":"class_goog_labs_testing_IsNullMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.IsNullOrUndefinedMatcher","isTypedef":false,"href":"class_goog_labs_testing_IsNullOrUndefinedMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.IsUndefinedMatcher","isTypedef":false,"href":"class_goog_labs_testing_IsUndefinedMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.LessThanEqualToMatcher","isTypedef":false,"href":"class_goog_labs_testing_LessThanEqualToMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.LessThanMatcher","isTypedef":false,"href":"class_goog_labs_testing_LessThanMatcher.html"},{"isInterface":true,"name":"goog.labs.testing.Matcher","isTypedef":false,"href":"interface_goog_labs_testing_Matcher.html"},{"isInterface":false,"name":"goog.labs.testing.MatcherError","isTypedef":false,"href":"class_goog_labs_testing_MatcherError.html"},{"isInterface":false,"name":"goog.labs.testing.ObjectEqualsMatcher","isTypedef":false,"href":"class_goog_labs_testing_ObjectEqualsMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.RegexMatcher","isTypedef":false,"href":"class_goog_labs_testing_RegexMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.StartsWithMatcher","isTypedef":false,"href":"class_goog_labs_testing_StartsWithMatcher.html"},{"isInterface":false,"name":"goog.labs.testing.StringContainsInOrderMatcher","isTypedef":false,"href":"class_goog_labs_testing_StringContainsInOrderMatcher.html"},{"isInterface":false,"name":"goog.labs.userAgent","isTypedef":false,"href":"namespace_goog_labs_userAgent.html"},{"isInterface":false,"name":"goog.labs.userAgent.browser","isTypedef":false,"href":"namespace_goog_labs_userAgent_browser.html"},{"isInterface":false,"name":"goog.labs.userAgent.engine","isTypedef":false,"href":"namespace_goog_labs_userAgent_engine.html"},{"isInterface":false,"name":"goog.labs.userAgent.util","isTypedef":false,"href":"namespace_goog_labs_userAgent_util.html"},{"isInterface":false,"name":"goog.math","isTypedef":false,"href":"namespace_goog_math.html"},{"isInterface":false,"name":"goog.net","isTypedef":false,"href":"namespace_goog_net.html"},{"isInterface":false,"name":"goog.net.DefaultXmlHttpFactory","isTypedef":false,"href":"class_goog_net_DefaultXmlHttpFactory.html"},{"isInterface":false,"name":"goog.net.WrapperXmlHttpFactory","isTypedef":false,"href":"class_goog_net_WrapperXmlHttpFactory.html"},{"isInterface":true,"name":"goog.net.XhrLike","isTypedef":false,"href":"interface_goog_net_XhrLike.html"},{"name":"goog.net.XhrLike.OrNative","isTypedef":true,"href":"interface_goog_net_XhrLike.html#goog.net.XhrLike.OrNative"},{"isInterface":false,"name":"goog.net.XmlHttp","isTypedef":false,"href":"namespace_goog_net_XmlHttp.html"},{"isInterface":false,"name":"goog.net.XmlHttp.OptionType","isTypedef":false,"href":"enum_goog_net_XmlHttp_OptionType.html"},{"isInterface":false,"name":"goog.net.XmlHttp.ReadyState","isTypedef":false,"href":"enum_goog_net_XmlHttp_ReadyState.html"},{"isInterface":false,"name":"goog.net.XmlHttpDefines","isTypedef":false,"href":"namespace_goog_net_XmlHttpDefines.html"},{"isInterface":false,"name":"goog.net.XmlHttpFactory","isTypedef":false,"href":"class_goog_net_XmlHttpFactory.html"},{"isInterface":false,"name":"goog.object","isTypedef":false,"href":"namespace_goog_object.html"},{"isInterface":false,"name":"goog.string","isTypedef":false,"href":"namespace_goog_string.html"},{"isInterface":false,"name":"goog.string.Unicode","isTypedef":false,"href":"enum_goog_string_Unicode.html"},{"isInterface":false,"name":"goog.structs","isTypedef":false,"href":"namespace_goog_structs.html"},{"isInterface":false,"name":"goog.structs.Map","isTypedef":false,"href":"class_goog_structs_Map.html"},{"isInterface":false,"name":"goog.uri","isTypedef":false,"href":"namespace_goog_uri.html"},{"isInterface":false,"name":"goog.uri.utils","isTypedef":false,"href":"namespace_goog_uri_utils.html"},{"name":"goog.uri.utils.QueryArray","isTypedef":true,"href":"namespace_goog_uri_utils.html#goog.uri.utils.QueryArray"},{"name":"goog.uri.utils.QueryValue","isTypedef":true,"href":"namespace_goog_uri_utils.html#goog.uri.utils.QueryValue"},{"isInterface":false,"name":"goog.uri.utils.CharCode_","isTypedef":false,"href":"enum_goog_uri_utils_CharCode_.html"},{"isInterface":false,"name":"goog.uri.utils.ComponentIndex","isTypedef":false,"href":"enum_goog_uri_utils_ComponentIndex.html"},{"isInterface":false,"name":"goog.uri.utils.StandardQueryParam","isTypedef":false,"href":"enum_goog_uri_utils_StandardQueryParam.html"},{"isInterface":false,"name":"goog.userAgent","isTypedef":false,"href":"namespace_goog_userAgent.html"},{"isInterface":false,"name":"goog.userAgent.product","isTypedef":false,"href":"namespace_goog_userAgent_product.html"},{"isInterface":false,"name":"webdriver","isTypedef":false,"href":"namespace_webdriver.html"},{"isInterface":false,"name":"webdriver.AbstractBuilder","isTypedef":false,"href":"class_webdriver_AbstractBuilder.html"},{"isInterface":false,"name":"webdriver.ActionSequence","isTypedef":false,"href":"class_webdriver_ActionSequence.html"},{"isInterface":false,"name":"webdriver.Alert","isTypedef":false,"href":"class_webdriver_Alert.html"},{"isInterface":false,"name":"webdriver.Browser","isTypedef":false,"href":"enum_webdriver_Browser.html"},{"isInterface":false,"name":"webdriver.Builder","isTypedef":false,"href":"class_webdriver_Builder.html"},{"isInterface":false,"name":"webdriver.Button","isTypedef":false,"href":"enum_webdriver_Button.html"},{"isInterface":false,"name":"webdriver.By","isTypedef":false,"href":"namespace_webdriver_By.html"},{"name":"webdriver.By.Hash","isTypedef":true,"href":"namespace_webdriver_By.html#webdriver.By.Hash"},{"isInterface":false,"name":"webdriver.Capabilities","isTypedef":false,"href":"class_webdriver_Capabilities.html"},{"isInterface":false,"name":"webdriver.Capability","isTypedef":false,"href":"enum_webdriver_Capability.html"},{"isInterface":false,"name":"webdriver.Command","isTypedef":false,"href":"class_webdriver_Command.html"},{"isInterface":true,"name":"webdriver.CommandExecutor","isTypedef":false,"href":"interface_webdriver_CommandExecutor.html"},{"isInterface":false,"name":"webdriver.CommandName","isTypedef":false,"href":"enum_webdriver_CommandName.html"},{"isInterface":false,"name":"webdriver.EventEmitter","isTypedef":false,"href":"class_webdriver_EventEmitter.html"},{"isInterface":false,"name":"webdriver.FirefoxDomExecutor","isTypedef":false,"href":"class_webdriver_FirefoxDomExecutor.html"},{"isInterface":false,"name":"webdriver.FirefoxDomExecutor.Attribute_","isTypedef":false,"href":"enum_webdriver_FirefoxDomExecutor_Attribute_.html"},{"isInterface":false,"name":"webdriver.FirefoxDomExecutor.EventType_","isTypedef":false,"href":"enum_webdriver_FirefoxDomExecutor_EventType_.html"},{"isInterface":false,"name":"webdriver.Key","isTypedef":false,"href":"enum_webdriver_Key.html"},{"isInterface":false,"name":"webdriver.Locator","isTypedef":false,"href":"class_webdriver_Locator.html"},{"isInterface":false,"name":"webdriver.Session","isTypedef":false,"href":"class_webdriver_Session.html"},{"isInterface":false,"name":"webdriver.UnhandledAlertError","isTypedef":false,"href":"class_webdriver_UnhandledAlertError.html"},{"isInterface":false,"name":"webdriver.WebDriver","isTypedef":false,"href":"class_webdriver_WebDriver.html"},{"isInterface":false,"name":"webdriver.WebDriver.Logs","isTypedef":false,"href":"class_webdriver_WebDriver_Logs.html"},{"isInterface":false,"name":"webdriver.WebDriver.Navigation","isTypedef":false,"href":"class_webdriver_WebDriver_Navigation.html"},{"isInterface":false,"name":"webdriver.WebDriver.Options","isTypedef":false,"href":"class_webdriver_WebDriver_Options.html"},{"name":"webdriver.WebDriver.Options.Cookie","isTypedef":true,"href":"class_webdriver_WebDriver_Options.html#webdriver.WebDriver.Options.Cookie"},{"isInterface":false,"name":"webdriver.WebDriver.TargetLocator","isTypedef":false,"href":"class_webdriver_WebDriver_TargetLocator.html"},{"isInterface":false,"name":"webdriver.WebDriver.Timeouts","isTypedef":false,"href":"class_webdriver_WebDriver_Timeouts.html"},{"isInterface":false,"name":"webdriver.WebDriver.Window","isTypedef":false,"href":"class_webdriver_WebDriver_Window.html"},{"isInterface":false,"name":"webdriver.WebElement","isTypedef":false,"href":"class_webdriver_WebElement.html"},{"name":"webdriver.WebElement.Id","isTypedef":true,"href":"class_webdriver_WebElement.html#webdriver.WebElement.Id"},{"isInterface":false,"name":"webdriver.http","isTypedef":false,"href":"namespace_webdriver_http.html"},{"isInterface":true,"name":"webdriver.http.Client","isTypedef":false,"href":"interface_webdriver_http_Client.html"},{"isInterface":false,"name":"webdriver.http.CorsClient","isTypedef":false,"href":"class_webdriver_http_CorsClient.html"},{"isInterface":false,"name":"webdriver.http.Executor","isTypedef":false,"href":"class_webdriver_http_Executor.html"},{"isInterface":false,"name":"webdriver.http.Request","isTypedef":false,"href":"class_webdriver_http_Request.html"},{"isInterface":false,"name":"webdriver.http.Response","isTypedef":false,"href":"class_webdriver_http_Response.html"},{"isInterface":false,"name":"webdriver.http.XhrClient","isTypedef":false,"href":"class_webdriver_http_XhrClient.html"},{"isInterface":false,"name":"webdriver.logging","isTypedef":false,"href":"namespace_webdriver_logging.html"},{"name":"webdriver.logging.Preferences","isTypedef":true,"href":"namespace_webdriver_logging.html#webdriver.logging.Preferences"},{"isInterface":false,"name":"webdriver.logging.Entry","isTypedef":false,"href":"class_webdriver_logging_Entry.html"},{"isInterface":false,"name":"webdriver.logging.Level","isTypedef":false,"href":"enum_webdriver_logging_Level.html"},{"isInterface":false,"name":"webdriver.logging.LevelName","isTypedef":false,"href":"enum_webdriver_logging_LevelName.html"},{"isInterface":false,"name":"webdriver.logging.Type","isTypedef":false,"href":"enum_webdriver_logging_Type.html"},{"isInterface":false,"name":"webdriver.process","isTypedef":false,"href":"namespace_webdriver_process.html"},{"isInterface":false,"name":"webdriver.promise","isTypedef":false,"href":"namespace_webdriver_promise.html"},{"isInterface":false,"name":"webdriver.promise.CanceledTaskError_","isTypedef":false,"href":"class_webdriver_promise_CanceledTaskError_.html"},{"isInterface":false,"name":"webdriver.promise.ControlFlow","isTypedef":false,"href":"class_webdriver_promise_ControlFlow.html"},{"name":"webdriver.promise.ControlFlow.Timer","isTypedef":true,"href":"class_webdriver_promise_ControlFlow.html#webdriver.promise.ControlFlow.Timer"},{"isInterface":false,"name":"webdriver.promise.ControlFlow.EventType","isTypedef":false,"href":"enum_webdriver_promise_ControlFlow_EventType.html"},{"isInterface":false,"name":"webdriver.promise.Deferred","isTypedef":false,"href":"class_webdriver_promise_Deferred.html"},{"name":"webdriver.promise.Deferred.Listener_","isTypedef":true,"href":"class_webdriver_promise_Deferred.html#webdriver.promise.Deferred.Listener_"},{"isInterface":false,"name":"webdriver.promise.Deferred.State_","isTypedef":false,"href":"enum_webdriver_promise_Deferred_State_.html"},{"isInterface":false,"name":"webdriver.promise.Frame_","isTypedef":false,"href":"class_webdriver_promise_Frame_.html"},{"isInterface":false,"name":"webdriver.promise.Node_","isTypedef":false,"href":"class_webdriver_promise_Node_.html"},{"isInterface":false,"name":"webdriver.promise.Promise","isTypedef":false,"href":"class_webdriver_promise_Promise.html"},{"isInterface":false,"name":"webdriver.promise.Task_","isTypedef":false,"href":"class_webdriver_promise_Task_.html"},{"isInterface":false,"name":"webdriver.stacktrace","isTypedef":false,"href":"namespace_webdriver_stacktrace.html"},{"isInterface":false,"name":"webdriver.stacktrace.Frame","isTypedef":false,"href":"class_webdriver_stacktrace_Frame.html"},{"isInterface":false,"name":"webdriver.stacktrace.Snapshot","isTypedef":false,"href":"class_webdriver_stacktrace_Snapshot.html"},{"isInterface":false,"name":"webdriver.testing","isTypedef":false,"href":"namespace_webdriver_testing.html"},{"isInterface":false,"name":"webdriver.testing.Assertion","isTypedef":false,"href":"class_webdriver_testing_Assertion.html"},{"isInterface":false,"name":"webdriver.testing.Assertion.DelegatingMatcher_","isTypedef":false,"href":"class_webdriver_testing_Assertion_DelegatingMatcher_.html"},{"isInterface":false,"name":"webdriver.testing.ContainsMatcher","isTypedef":false,"href":"class_webdriver_testing_ContainsMatcher.html"},{"isInterface":false,"name":"webdriver.testing.NegatedAssertion","isTypedef":false,"href":"class_webdriver_testing_NegatedAssertion.html"},{"isInterface":false,"name":"webdriver.testing.assert","isTypedef":false,"href":"module_selenium-webdriver_testing_assert_namespace_dossier$$module__$usr$local$google$home$jleyba$dev$selenium$build$javascript$node$selenium_webdriver$testing$assert_exports.html"},{"isInterface":false,"name":"webdriver.testing.asserts","isTypedef":false,"href":"namespace_webdriver_testing_asserts.html"}],"modules":[{"name":"selenium-webdriver","types":[{"isInterface":false,"name":"Command","isTypedef":false,"href":"class_webdriver_Command.html"},{"isInterface":false,"name":"Key","isTypedef":false,"href":"enum_webdriver_Key.html"},{"isInterface":false,"name":"EventEmitter","isTypedef":false,"href":"class_webdriver_EventEmitter.html"},{"isInterface":false,"name":"Browser","isTypedef":false,"href":"enum_webdriver_Browser.html"},{"isInterface":false,"name":"ActionSequence","isTypedef":false,"href":"class_webdriver_ActionSequence.html"},{"isInterface":false,"name":"Button","isTypedef":false,"href":"enum_webdriver_Button.html"},{"isInterface":false,"name":"WebElement","isTypedef":false,"href":"class_webdriver_WebElement.html"},{"name":"webdriver.WebElement.Id","isTypedef":true,"href":"class_webdriver_WebElement.html#webdriver.WebElement.Id"},{"isInterface":false,"name":"CommandName","isTypedef":false,"href":"enum_webdriver_CommandName.html"},{"isInterface":false,"name":"Capability","isTypedef":false,"href":"enum_webdriver_Capability.html"},{"isInterface":false,"name":"Session","isTypedef":false,"href":"class_webdriver_Session.html"},{"isInterface":false,"name":"Builder","isTypedef":false,"href":"module_selenium-webdriver_class_Builder.html"},{"isInterface":false,"name":"Capabilities","isTypedef":false,"href":"class_webdriver_Capabilities.html"},{"isInterface":false,"name":"WebDriver","isTypedef":false,"href":"class_webdriver_WebDriver.html"}],"href":"module_selenium-webdriver.html"},{"name":"selenium-webdriver/_base","types":[],"href":"module_selenium-webdriver__base.html"},{"name":"selenium-webdriver/builder","types":[{"isInterface":false,"name":"Builder","isTypedef":false,"href":"module_selenium-webdriver_builder_class_Builder.html"}],"href":"module_selenium-webdriver_builder.html"},{"name":"selenium-webdriver/chrome","types":[{"isInterface":false,"name":"ServiceBuilder","isTypedef":false,"href":"module_selenium-webdriver_chrome_class_ServiceBuilder.html"},{"isInterface":false,"name":"Options","isTypedef":false,"href":"module_selenium-webdriver_chrome_class_Options.html"}],"href":"module_selenium-webdriver_chrome.html"},{"name":"selenium-webdriver/error","types":[{"isInterface":false,"name":"ErrorCode","isTypedef":false,"href":"enum_bot_ErrorCode.html"},{"isInterface":false,"name":"Error","isTypedef":false,"href":"class_bot_Error.html"}],"href":"module_selenium-webdriver_error.html"},{"name":"selenium-webdriver/executors","types":[],"href":"module_selenium-webdriver_executors.html"},{"name":"selenium-webdriver/http","types":[{"isInterface":false,"name":"HttpClient","isTypedef":false,"href":"module_selenium-webdriver_http_class_HttpClient.html"},{"isInterface":false,"name":"Response","isTypedef":false,"href":"class_webdriver_http_Response.html"},{"isInterface":false,"name":"Request","isTypedef":false,"href":"class_webdriver_http_Request.html"},{"isInterface":false,"name":"Executor","isTypedef":false,"href":"class_webdriver_http_Executor.html"}],"href":"module_selenium-webdriver_http.html"},{"name":"selenium-webdriver/http/util","types":[],"href":"module_selenium-webdriver_http_util.html"},{"name":"selenium-webdriver/io","types":[],"href":"module_selenium-webdriver_io.html"},{"name":"selenium-webdriver/net","types":[],"href":"module_selenium-webdriver_net.html"},{"name":"selenium-webdriver/net/portprober","types":[],"href":"module_selenium-webdriver_net_portprober.html"},{"name":"selenium-webdriver/phantomjs","types":[],"href":"module_selenium-webdriver_phantomjs.html"},{"name":"selenium-webdriver/proxy","types":[{"isInterface":false,"name":"ProxyConfig","isTypedef":true,"href":"module_selenium-webdriver_proxy_namespace_ProxyConfig.html"}],"href":"module_selenium-webdriver_proxy.html"},{"name":"selenium-webdriver/remote","types":[{"isInterface":false,"name":"DriverService","isTypedef":false,"href":"module_selenium-webdriver_remote_class_DriverService.html"},{"isInterface":false,"name":"SeleniumServer","isTypedef":false,"href":"module_selenium-webdriver_remote_class_SeleniumServer.html"},{"name":"SeleniumServer.Options","isTypedef":true,"href":""},{"isInterface":false,"name":"ServiceOptions","isTypedef":true,"href":"module_selenium-webdriver_remote_namespace_ServiceOptions.html"}],"href":"module_selenium-webdriver_remote.html"},{"name":"selenium-webdriver/testing","types":[],"href":"module_selenium-webdriver_testing.html"},{"name":"selenium-webdriver/testing/assert","types":[],"href":"module_selenium-webdriver_testing_assert.html"}]}; \ No newline at end of file diff --git a/node_modules/selenium-webdriver/error.js b/node_modules/selenium-webdriver/error.js new file mode 100644 index 0000000..368bbc2 --- /dev/null +++ b/node_modules/selenium-webdriver/error.js @@ -0,0 +1,25 @@ +// Copyright 2014 Selenium committers +// Copyright 2014 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var base = require('./_base'); + + +/** @type {function(new: bot.Error)} */ +exports.Error = base.require('bot.Error'); + +/** @type {bot.ErrorCode.} */ +exports.ErrorCode = base.require('bot.ErrorCode'); diff --git a/node_modules/selenium-webdriver/example/google_search.js b/node_modules/selenium-webdriver/example/google_search.js new file mode 100644 index 0000000..d09e41d --- /dev/null +++ b/node_modules/selenium-webdriver/example/google_search.js @@ -0,0 +1,40 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview An example WebDriver script. This requires the chromedriver + * to be present on the system PATH. + * Usage: node selenium-webdriver/example/google_search.js + */ + +var fs = require('fs'); + +var webdriver = require('..'), + remote = require('../remote'); + +var driver = new webdriver.Builder(). + withCapabilities(webdriver.Capabilities.chrome()). + build(); + +driver.get('http://www.google.com'); +driver.findElement(webdriver.By.name('q')).sendKeys('webdriver'); +driver.findElement(webdriver.By.name('btnG')).click(); +driver.wait(function() { + return driver.getTitle().then(function(title) { + return 'webdriver - Google Search' === title; + }); +}, 1000); + +driver.quit(); diff --git a/node_modules/selenium-webdriver/example/google_search_test.js b/node_modules/selenium-webdriver/example/google_search_test.js new file mode 100644 index 0000000..8ed6a7d --- /dev/null +++ b/node_modules/selenium-webdriver/example/google_search_test.js @@ -0,0 +1,50 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview An example test that may be run using Mocha. To run, you must + * have the chromedriver installed on the system PATH. + */ + +var assert = require('assert'), + fs = require('fs'); + +var webdriver = require('..'), + test = require('../testing'), + remote = require('../remote'); + + +test.describe('Google Search', function() { + var driver; + + test.before(function() { + driver = new webdriver.Builder(). + withCapabilities(webdriver.Capabilities.chrome()). + build(); + }); + + test.it('should append query to title', function() { + driver.get('http://www.google.com'); + driver.findElement(webdriver.By.name('q')).sendKeys('webdriver'); + driver.findElement(webdriver.By.name('btnG')).click(); + driver.wait(function() { + return driver.getTitle().then(function(title) { + return 'webdriver - Google Search' === title; + }); + }, 1000); + }); + + test.after(function() { driver.quit(); }); +}); diff --git a/node_modules/selenium-webdriver/executors.js b/node_modules/selenium-webdriver/executors.js new file mode 100644 index 0000000..79cf8c1 --- /dev/null +++ b/node_modules/selenium-webdriver/executors.js @@ -0,0 +1,59 @@ +// Copyright 2013 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Various utilities for working with + * {@link webdriver.CommandExecutor} implementations. + */ + +var HttpClient = require('./http').HttpClient, + HttpExecutor = require('./http').Executor, + promise = require('./_base').require('webdriver.promise'); + + + +/** + * Wraps a promised {@link webdriver.CommandExecutor}, ensuring no commands + * are executed until the wrapped executor has been fully built. + * @param {!webdriver.promise.Promise.} delegate The + * promised delegate. + * @constructor + * @implements {webdriver.CommandExecutor} + */ +var DeferredExecutor = function(delegate) { + + /** @override */ + this.execute = function(command, callback) { + delegate.then(function(executor) { + executor.execute(command, callback); + }, callback); + }; +}; + + +// PUBLIC API + + +/** + * Creates a command executor that uses WebDriver's JSON wire protocol. + * @param {(string|!webdriver.promise.Promise.)} url The server's URL, + * or a promise that will resolve to that URL. + * @returns {!webdriver.CommandExecutor} The new command executor. + */ +exports.createExecutor = function(url) { + return new DeferredExecutor(promise.when(url, function(url) { + var client = new HttpClient(url); + return new HttpExecutor(client); + })); +}; diff --git a/node_modules/selenium-webdriver/http/index.js b/node_modules/selenium-webdriver/http/index.js new file mode 100644 index 0000000..2571cd3 --- /dev/null +++ b/node_modules/selenium-webdriver/http/index.js @@ -0,0 +1,159 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Defines a the {@code webdriver.http.Client} for use with + * NodeJS. + */ + +var http = require('http'), + url = require('url'); + +var base = require('../_base'), + HttpResponse = base.require('webdriver.http.Response'); + + +/** + * A {@link webdriver.http.Client} implementation using Node's built-in http + * module. + * @param {string} serverUrl URL for the WebDriver server to send commands to. + * @constructor + * @implements {webdriver.http.Client} + */ +var HttpClient = function(serverUrl) { + var parsedUrl = url.parse(serverUrl); + if (!parsedUrl.hostname) { + throw new Error('Invalid server URL: ' + serverUrl); + } + + /** + * Base options for each request. + * @private {!Object} + */ + this.options_ = { + host: parsedUrl.hostname, + path: parsedUrl.pathname, + port: parsedUrl.port + }; +}; + + +/** @override */ +HttpClient.prototype.send = function(httpRequest, callback) { + var data; + httpRequest.headers['Content-Length'] = 0; + if (httpRequest.method == 'POST' || httpRequest.method == 'PUT') { + data = JSON.stringify(httpRequest.data); + httpRequest.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); + httpRequest.headers['Content-Type'] = 'application/json;charset=UTF-8'; + } + + var path = this.options_.path; + if (path[path.length - 1] === '/' && httpRequest.path[0] === '/') { + path += httpRequest.path.substring(1); + } else { + path += httpRequest.path; + } + + sendRequest({ + method: httpRequest.method, + host: this.options_.host, + port: this.options_.port, + path: path, + headers: httpRequest.headers + }, callback, data); +}; + + +/** + * Sends a single HTTP request. + * @param {!Object} options The request options. + * @param {function(Error, !webdriver.http.Response=)} callback The function to + * invoke with the server's response. + * @param {string=} opt_data The data to send with the request. + */ +var sendRequest = function(options, callback, opt_data) { + var request = http.request(options, function(response) { + if (response.statusCode == 302 || response.statusCode == 303) { + try { + var location = url.parse(response.headers['location']); + } catch (ex) { + callback(Error( + 'Failed to parse "Location" header for server redirect: ' + + ex.message + '\nResponse was: \n' + + new HttpResponse(response.statusCode, response.headers, ''))); + return; + } + + if (!location.hostname) { + location.hostname = options.host; + location.port = options.port; + } + + request.abort(); + sendRequest({ + method: 'GET', + host: location.hostname, + path: location.pathname + (location.search || ''), + port: location.port, + headers: { + 'Accept': 'application/json; charset=utf-8' + } + }, callback); + return; + } + + var body = []; + response.on('data', body.push.bind(body)); + response.on('end', function() { + var resp = new HttpResponse(response.statusCode, + response.headers, body.join('').replace(/\0/g, '')); + callback(null, resp); + }); + }); + + request.on('error', function(e) { + if (e.code === 'ECONNRESET') { + setTimeout(function() { + sendRequest(options, callback, opt_data); + }, 15); + } else { + var message = e.message; + if (e.code) { + message = e.code + ' ' + message; + } + callback(new Error(message)); + } + }); + + if (opt_data) { + request.write(opt_data); + } + + request.end(); +}; + + +// PUBLIC API + +/** @type {webdriver.http.Executor.} */ +exports.Executor = base.require('webdriver.http.Executor'); + +/** @type {webdriver.http.Request.} */ +exports.Request = base.require('webdriver.http.Request'); + +/** @type {webdriver.http.Response.} */ +exports.Response = base.require('webdriver.http.Response'); + +exports.HttpClient = HttpClient; diff --git a/node_modules/selenium-webdriver/http/util.js b/node_modules/selenium-webdriver/http/util.js new file mode 100644 index 0000000..fcb2219 --- /dev/null +++ b/node_modules/selenium-webdriver/http/util.js @@ -0,0 +1,133 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Various HTTP utilities. + */ + +var base = require('../_base'), + HttpClient = require('./index').HttpClient, + checkResponse = base.require('bot.response').checkResponse, + Executor = base.require('webdriver.http.Executor'), + HttpRequest = base.require('webdriver.http.Request'), + Command = base.require('webdriver.Command'), + CommandName = base.require('webdriver.CommandName'), + promise = base.require('webdriver.promise'); + + + +/** + * Queries a WebDriver server for its current status. + * @param {string} url Base URL of the server to query. + * @param {function(Error, *=)} callback The function to call with the + * response. + */ +function getStatus(url, callback) { + var client = new HttpClient(url); + var executor = new Executor(client); + var command = new Command(CommandName.GET_SERVER_STATUS); + executor.execute(command, function(err, responseObj) { + if (err) return callback(err); + try { + checkResponse(responseObj); + } catch (ex) { + return callback(ex); + } + callback(null, responseObj['value']); + }); +} + + +// PUBLIC API + + +/** + * Queries a WebDriver server for its current status. + * @param {string} url Base URL of the server to query. + * @return {!webdriver.promise.Promise.} A promise that resolves with + * a hash of the server status. + */ +exports.getStatus = function(url) { + return promise.checkedNodeCall(getStatus.bind(null, url)); +}; + + +/** + * Waits for a WebDriver server to be healthy and accepting requests. + * @param {string} url Base URL of the server to query. + * @param {number} timeout How long to wait for the server. + * @return {!webdriver.promise.Promise} A promise that will resolve when the + * server is ready. + */ +exports.waitForServer = function(url, timeout) { + var ready = promise.defer(), + start = Date.now(), + checkServerStatus = getStatus.bind(null, url, onResponse); + checkServerStatus(); + return ready.promise; + + function onResponse(err) { + if (!ready.isPending()) return; + if (!err) return ready.fulfill(); + + if (Date.now() - start > timeout) { + ready.reject( + Error('Timed out waiting for the WebDriver server at ' + url)); + } else { + setTimeout(function() { + if (ready.isPending()) { + checkServerStatus(); + } + }, 50); + } + } +}; + + +/** + * Polls a URL with GET requests until it returns a 2xx response or the + * timeout expires. + * @param {string} url The URL to poll. + * @param {number} timeout How long to wait, in milliseconds. + * @return {!webdriver.promise.Promise} A promise that will resolve when the + * URL responds with 2xx. + */ +exports.waitForUrl = function(url, timeout) { + var client = new HttpClient(url), + request = new HttpRequest('GET', ''), + testUrl = client.send.bind(client, request, onResponse), + ready = promise.defer(), + start = Date.now(); + testUrl(); + return ready.promise; + + function onResponse(err, response) { + if (!ready.isPending()) return; + if (!err && response.status > 199 && response.status < 300) { + return ready.fulfill(); + } + + if (Date.now() - start > timeout) { + ready.reject(Error( + 'Timed out waiting for the URL to return 2xx: ' + url)); + } else { + setTimeout(function() { + if (ready.isPending()) { + testUrl(); + } + }, 50); + } + } +}; diff --git a/node_modules/selenium-webdriver/index.js b/node_modules/selenium-webdriver/index.js new file mode 100644 index 0000000..7391fdb --- /dev/null +++ b/node_modules/selenium-webdriver/index.js @@ -0,0 +1,128 @@ +// Copyright 2012 Selenium committers +// Copyright 2012 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview The main user facing module. Exports WebDriver's primary + * public API and provides convenience assessors to certain sub-modules. + */ + +var base = require('./_base'); +var builder = require('./builder'); +var error = require('./error'); + + +// NOTE: the remainder of this file is nasty and verbose, but the annotations +// are necessary to guide the Closure Compiler's type analysis. Without them, +// we would not be able to extract any meaningful API documentation. + + +/** @type {function(new: webdriver.ActionSequence)} */ +exports.ActionSequence = base.require('webdriver.ActionSequence'); + + +/** @type {function(new: builder.Builder)} */ +exports.Builder = builder.Builder; + + +/** @type {webdriver.By.} */ +exports.By = base.require('webdriver.By'); + + +/** @type {function(new: webdriver.Capabilities)} */ +exports.Capabilities = base.require('webdriver.Capabilities'); + + +/** @type {function(new: webdriver.Command)} */ +exports.Command = base.require('webdriver.Command'); + + +/** @type {function(new: webdriver.EventEmitter)} */ +exports.EventEmitter = base.require('webdriver.EventEmitter'); + + +/** @type {function(new: webdriver.Session)} */ +exports.Session = base.require('webdriver.Session'); + + +/** @type {function(new: webdriver.WebDriver)} */ +exports.WebDriver = base.require('webdriver.WebDriver'); + + +/** @type {function(new: webdriver.WebElement)} */ +exports.WebElement = base.require('webdriver.WebElement'); + + +// Export the remainder of our API through getters to keep things cleaner +// when this module is used in a REPL environment. + + +/** @type {webdriver.Browser.} */ +(exports.__defineGetter__('Browser', function() { + return base.require('webdriver.Browser'); +})); + + +/** @type {webdriver.Button.} */ +(exports.__defineGetter__('Button', function() { + return base.require('webdriver.Button'); +})); + + +/** @type {webdriver.Capability.} */ +(exports.__defineGetter__('Capability', function() { + return base.require('webdriver.Capability'); +})); + + +/** @type {webdriver.CommandName.} */ +(exports.__defineGetter__('CommandName', function() { + return base.require('webdriver.CommandName'); +})); + + +/** @type {webdriver.Key.} */ +(exports.__defineGetter__('Key', function() { + return base.require('webdriver.Key'); +})); + + +/** @type {error.} */ +(exports.__defineGetter__('error', function() { + return error; +})); + + +/** @type {error.} */ +(exports.__defineGetter__('error', function() { + return error; +})); + + +/** @type {webdriver.logging.} */ +(exports.__defineGetter__('logging', function() { + return base.exportPublicApi('webdriver.logging'); +})); + + +/** @type {webdriver.promise.} */ +(exports.__defineGetter__('promise', function() { + return base.exportPublicApi('webdriver.promise'); +})); + + +/** @type {webdriver.stacktrace.} */ +(exports.__defineGetter__('stacktrace', function() { + return base.exportPublicApi('webdriver.stacktrace'); +})); diff --git a/node_modules/selenium-webdriver/io/index.js b/node_modules/selenium-webdriver/io/index.js new file mode 100644 index 0000000..5d5a3de --- /dev/null +++ b/node_modules/selenium-webdriver/io/index.js @@ -0,0 +1,52 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var fs = require('fs'), + path = require('path'); + + +var PATH_SEPARATOR = process.platform === 'win32' ? ';' : ':'; + + +// PUBLIC API + + +/** + * Searches the {@code PATH} environment variable for the given file. + * @param {string} file The file to locate on the PATH. + * @param {boolean=} opt_checkCwd Whether to always start with the search with + * the current working directory, regardless of whether it is explicitly + * listed on the PATH. + * @return {?string} Path to the located file, or {@code null} if it could + * not be found. + */ +exports.findInPath = function(file, opt_checkCwd) { + if (opt_checkCwd) { + var tmp = path.join(process.cwd(), file); + if (fs.existsSync(tmp)) { + return tmp; + } + } + + var dirs = process.env['PATH'].split(PATH_SEPARATOR); + var found = null; + dirs.forEach(function(dir) { + var tmp = path.join(dir, file); + if (!found && fs.existsSync(tmp)) { + found = tmp; + } + }); + return found; +}; diff --git a/node_modules/selenium-webdriver/lib/README b/node_modules/selenium-webdriver/lib/README new file mode 100644 index 0000000..bdf25b0 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/README @@ -0,0 +1,2 @@ +This directory contains modules internal to selenium-webdriver that are not +intended for general consumption. They may change at any time. diff --git a/node_modules/selenium-webdriver/lib/atoms/error.js b/node_modules/selenium-webdriver/lib/atoms/error.js new file mode 100644 index 0000000..5b23ff9 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/atoms/error.js @@ -0,0 +1,205 @@ +// Copyright 2010 WebDriver committers +// Copyright 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Utilities for working with errors as defined by WebDriver's + * wire protocol: http://code.google.com/p/selenium/wiki/JsonWireProtocol. + */ + +goog.provide('bot.Error'); +goog.provide('bot.ErrorCode'); + + +/** + * Error codes from the WebDriver wire protocol: + * http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes + * + * @enum {number} + */ +bot.ErrorCode = { + SUCCESS: 0, // Included for completeness + + NO_SUCH_ELEMENT: 7, + NO_SUCH_FRAME: 8, + UNKNOWN_COMMAND: 9, + UNSUPPORTED_OPERATION: 9, // Alias. + STALE_ELEMENT_REFERENCE: 10, + ELEMENT_NOT_VISIBLE: 11, + INVALID_ELEMENT_STATE: 12, + UNKNOWN_ERROR: 13, + ELEMENT_NOT_SELECTABLE: 15, + JAVASCRIPT_ERROR: 17, + XPATH_LOOKUP_ERROR: 19, + TIMEOUT: 21, + NO_SUCH_WINDOW: 23, + INVALID_COOKIE_DOMAIN: 24, + UNABLE_TO_SET_COOKIE: 25, + MODAL_DIALOG_OPENED: 26, + NO_MODAL_DIALOG_OPEN: 27, + SCRIPT_TIMEOUT: 28, + INVALID_ELEMENT_COORDINATES: 29, + IME_NOT_AVAILABLE: 30, + IME_ENGINE_ACTIVATION_FAILED: 31, + INVALID_SELECTOR_ERROR: 32, + SESSION_NOT_CREATED: 33, + MOVE_TARGET_OUT_OF_BOUNDS: 34, + SQL_DATABASE_ERROR: 35, + INVALID_XPATH_SELECTOR: 51, + INVALID_XPATH_SELECTOR_RETURN_TYPE: 52, + // The following error codes are derived straight from HTTP return codes. + METHOD_NOT_ALLOWED: 405 +}; + + + +/** + * Error extension that includes error status codes from the WebDriver wire + * protocol: + * http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes + * + * @param {!bot.ErrorCode} code The error's status code. + * @param {string=} opt_message Optional error message. + * @constructor + * @extends {Error} + */ +bot.Error = function(code, opt_message) { + + /** + * This error's status code. + * @type {!bot.ErrorCode} + */ + this.code = code; + + /** @type {string} */ + this.state = + bot.Error.CODE_TO_STATE_[code] || bot.Error.State.UNKNOWN_ERROR; + + /** @override */ + this.message = opt_message || ''; + + var name = this.state.replace(/((?:^|\s+)[a-z])/g, function(str) { + // IE<9 does not support String#trim(). Also, IE does not include 0xa0 + // (the non-breaking-space) in the \s character class, so we have to + // explicitly include it. + return str.toUpperCase().replace(/^[\s\xa0]+/g, ''); + }); + + var l = name.length - 'Error'.length; + if (l < 0 || name.indexOf('Error', l) != l) { + name += 'Error'; + } + + /** @override */ + this.name = name; + + // Generate a stacktrace for our custom error; ensure the error has our + // custom name and message so the stack prints correctly in all browsers. + var template = new Error(this.message); + template.name = this.name; + + /** @override */ + this.stack = template.stack || ''; +}; +goog.inherits(bot.Error, Error); + + +/** + * Status strings enumerated in the W3C WebDriver working draft. + * @enum {string} + * @see http://www.w3.org/TR/webdriver/#status-codes + */ +bot.Error.State = { + ELEMENT_NOT_SELECTABLE: 'element not selectable', + ELEMENT_NOT_VISIBLE: 'element not visible', + IME_ENGINE_ACTIVATION_FAILED: 'ime engine activation failed', + IME_NOT_AVAILABLE: 'ime not available', + INVALID_COOKIE_DOMAIN: 'invalid cookie domain', + INVALID_ELEMENT_COORDINATES: 'invalid element coordinates', + INVALID_ELEMENT_STATE: 'invalid element state', + INVALID_SELECTOR: 'invalid selector', + JAVASCRIPT_ERROR: 'javascript error', + MOVE_TARGET_OUT_OF_BOUNDS: 'move target out of bounds', + NO_SUCH_ALERT: 'no such alert', + NO_SUCH_DOM: 'no such dom', + NO_SUCH_ELEMENT: 'no such element', + NO_SUCH_FRAME: 'no such frame', + NO_SUCH_WINDOW: 'no such window', + SCRIPT_TIMEOUT: 'script timeout', + SESSION_NOT_CREATED: 'session not created', + STALE_ELEMENT_REFERENCE: 'stale element reference', + SUCCESS: 'success', + TIMEOUT: 'timeout', + UNABLE_TO_SET_COOKIE: 'unable to set cookie', + UNEXPECTED_ALERT_OPEN: 'unexpected alert open', + UNKNOWN_COMMAND: 'unknown command', + UNKNOWN_ERROR: 'unknown error', + UNSUPPORTED_OPERATION: 'unsupported operation' +}; + + +/** + * A map of error codes to state string. + * @private {!Object.} + */ +bot.Error.CODE_TO_STATE_ = {}; +goog.scope(function() { + var map = bot.Error.CODE_TO_STATE_; + var code = bot.ErrorCode; + var state = bot.Error.State; + + map[code.ELEMENT_NOT_SELECTABLE] = state.ELEMENT_NOT_SELECTABLE; + map[code.ELEMENT_NOT_VISIBLE] = state.ELEMENT_NOT_VISIBLE; + map[code.IME_ENGINE_ACTIVATION_FAILED] = state.IME_ENGINE_ACTIVATION_FAILED; + map[code.IME_NOT_AVAILABLE] = state.IME_NOT_AVAILABLE; + map[code.INVALID_COOKIE_DOMAIN] = state.INVALID_COOKIE_DOMAIN; + map[code.INVALID_ELEMENT_COORDINATES] = state.INVALID_ELEMENT_COORDINATES; + map[code.INVALID_ELEMENT_STATE] = state.INVALID_ELEMENT_STATE; + map[code.INVALID_SELECTOR_ERROR] = state.INVALID_SELECTOR; + map[code.INVALID_XPATH_SELECTOR] = state.INVALID_SELECTOR; + map[code.INVALID_XPATH_SELECTOR_RETURN_TYPE] = state.INVALID_SELECTOR; + map[code.JAVASCRIPT_ERROR] = state.JAVASCRIPT_ERROR; + map[code.METHOD_NOT_ALLOWED] = state.UNSUPPORTED_OPERATION; + map[code.MOVE_TARGET_OUT_OF_BOUNDS] = state.MOVE_TARGET_OUT_OF_BOUNDS; + map[code.NO_MODAL_DIALOG_OPEN] = state.NO_SUCH_ALERT; + map[code.NO_SUCH_ELEMENT] = state.NO_SUCH_ELEMENT; + map[code.NO_SUCH_FRAME] = state.NO_SUCH_FRAME; + map[code.NO_SUCH_WINDOW] = state.NO_SUCH_WINDOW; + map[code.SCRIPT_TIMEOUT] = state.SCRIPT_TIMEOUT; + map[code.SESSION_NOT_CREATED] = state.SESSION_NOT_CREATED; + map[code.STALE_ELEMENT_REFERENCE] = state.STALE_ELEMENT_REFERENCE; + map[code.SUCCESS] = state.SUCCESS; + map[code.TIMEOUT] = state.TIMEOUT; + map[code.UNABLE_TO_SET_COOKIE] = state.UNABLE_TO_SET_COOKIE; + map[code.MODAL_DIALOG_OPENED] = state.UNEXPECTED_ALERT_OPEN; + map[code.UNKNOWN_ERROR] = state.UNKNOWN_ERROR; + map[code.UNSUPPORTED_OPERATION] = state.UNKNOWN_COMMAND; +}); // goog.scope + + +/** + * Flag used for duck-typing when this code is embedded in a Firefox extension. + * This is required since an Error thrown in one component and then reported + * to another will fail instanceof checks in the second component. + * @type {boolean} + */ +bot.Error.prototype.isAutomationError = true; + + +if (goog.DEBUG) { + /** @return {string} The string representation of this error. */ + bot.Error.prototype.toString = function() { + return this.name + ': ' + this.message; + }; +} diff --git a/node_modules/selenium-webdriver/lib/atoms/json.js b/node_modules/selenium-webdriver/lib/atoms/json.js new file mode 100644 index 0000000..b3e863c --- /dev/null +++ b/node_modules/selenium-webdriver/lib/atoms/json.js @@ -0,0 +1,78 @@ +// Copyright 2012 WebDriver committers +// Copyright 2012 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Provides JSON utilities that uses native JSON parsing where + * possible (a feature not currently offered by Closure). + */ + +goog.provide('bot.json'); + +goog.require('bot.userAgent'); +goog.require('goog.json'); +goog.require('goog.userAgent'); + + +/** + * @define {boolean} NATIVE_JSON indicates whether the code should rely on the + * native {@code JSON} functions, if available. + * + *

    The JSON functions can be defined by external libraries like Prototype + * and setting this flag to false forces the use of Closure's goog.json + * implementation. + * + *

    If your JavaScript can be loaded by a third_party site and you are wary + * about relying on the native functions, specify + * "--define bot.json.NATIVE_JSON=false" to the Closure compiler. + */ +bot.json.NATIVE_JSON = true; + + +/** + * Whether the current browser supports the native JSON interface. + * @const + * @see http://caniuse.com/#search=JSON + * @private {boolean} + */ +bot.json.SUPPORTS_NATIVE_JSON_ = + // List WebKit and Opera first since every supported version of these + // browsers supports native JSON (and we can compile away large chunks of + // code for individual fragments by setting the appropriate compiler flags). + goog.userAgent.WEBKIT || goog.userAgent.OPERA || + (goog.userAgent.GECKO && bot.userAgent.isEngineVersion(3.5)) || + (goog.userAgent.IE && bot.userAgent.isEngineVersion(8)); + + +/** + * Converts a JSON object to its string representation. + * @param {*} jsonObj The input object. + * @param {?(function(string, *): *)=} opt_replacer A replacer function called + * for each (key, value) pair that determines how the value should be + * serialized. By default, this just returns the value and allows default + * serialization to kick in. + * @return {string} A JSON string representation of the input object. + */ +bot.json.stringify = bot.json.NATIVE_JSON && bot.json.SUPPORTS_NATIVE_JSON_ ? + JSON.stringify : goog.json.serialize; + + +/** + * Parses a JSON string and returns the result. + * @param {string} jsonStr The string to parse. + * @return {*} The JSON object. + * @throws {Error} If the input string is an invalid JSON string. + */ +bot.json.parse = bot.json.NATIVE_JSON && bot.json.SUPPORTS_NATIVE_JSON_ ? + JSON.parse : goog.json.parse; diff --git a/node_modules/selenium-webdriver/lib/atoms/response.js b/node_modules/selenium-webdriver/lib/atoms/response.js new file mode 100644 index 0000000..d929a66 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/atoms/response.js @@ -0,0 +1,107 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Utilities for working with WebDriver response objects. + * @see: http://code.google.com/p/selenium/wiki/JsonWireProtocol#Responses + */ + +goog.provide('bot.response'); +goog.provide('bot.response.ResponseObject'); + +goog.require('bot.Error'); +goog.require('bot.ErrorCode'); + + +/** + * Type definition for a response object, as defined by the JSON wire protocol. + * @typedef {{status: bot.ErrorCode, value: (*|{message: string})}} + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Responses + */ +bot.response.ResponseObject; + + +/** + * @param {*} value The value to test. + * @return {boolean} Whether the given value is a response object. + */ +bot.response.isResponseObject = function(value) { + return goog.isObject(value) && goog.isNumber(value['status']); +}; + + +/** + * Creates a new success response object with the provided value. + * @param {*} value The response value. + * @return {!bot.response.ResponseObject} The new response object. + */ +bot.response.createResponse = function(value) { + if (bot.response.isResponseObject(value)) { + return /** @type {!bot.response.ResponseObject} */ (value); + } + return { + 'status': bot.ErrorCode.SUCCESS, + 'value': value + }; +}; + + +/** + * Converts an error value into its JSON representation as defined by the + * WebDriver wire protocol. + * @param {(bot.Error|Error|*)} error The error value to convert. + * @return {!bot.response.ResponseObject} The new response object. + */ +bot.response.createErrorResponse = function(error) { + if (bot.response.isResponseObject(error)) { + return /** @type {!bot.response.ResponseObject} */ (error); + } + + var statusCode = error && goog.isNumber(error.code) ? error.code : + bot.ErrorCode.UNKNOWN_ERROR; + return { + 'status': /** @type {bot.ErrorCode} */ (statusCode), + 'value': { + 'message': (error && error.message || error) + '' + } + }; +}; + + +/** + * Checks that a response object does not specify an error as defined by the + * WebDriver wire protocol. If the response object defines an error, it will + * be thrown. Otherwise, the response will be returned as is. + * @param {!bot.response.ResponseObject} responseObj The response object to + * check. + * @return {!bot.response.ResponseObject} The checked response object. + * @throws {bot.Error} If the response describes an error. + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Failed_Commands + */ +bot.response.checkResponse = function(responseObj) { + var status = responseObj['status']; + if (status == bot.ErrorCode.SUCCESS) { + return responseObj; + } + + // If status is not defined, assume an unknown error. + status = status || bot.ErrorCode.UNKNOWN_ERROR; + + var value = responseObj['value']; + if (!value || !goog.isObject(value)) { + throw new bot.Error(status, value + ''); + } + + throw new bot.Error(status, value['message'] + ''); +}; diff --git a/node_modules/selenium-webdriver/lib/atoms/userAgent.js b/node_modules/selenium-webdriver/lib/atoms/userAgent.js new file mode 100644 index 0000000..60964d0 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/atoms/userAgent.js @@ -0,0 +1,255 @@ +// Copyright 2011 WebDriver committers +// Copyright 2011 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Similar to goog.userAgent.isVersion, but with support for + * getting the version information when running in a firefox extension. + */ +goog.provide('bot.userAgent'); + +goog.require('goog.string'); +goog.require('goog.userAgent'); +goog.require('goog.userAgent.product'); +goog.require('goog.userAgent.product.isVersion'); + + +/** + * Whether the rendering engine version of the current browser is equal to or + * greater than the given version. This implementation differs from + * goog.userAgent.isVersion in the following ways: + *

      + *
    1. in a Firefox extension, tests the engine version through the XUL version + * comparator service, because no window.navigator object is available + *
    2. in IE, compares the given version to the current documentMode + *
    + * + * @param {string|number} version The version number to check. + * @return {boolean} Whether the browser engine version is the same or higher + * than the given version. + */ +bot.userAgent.isEngineVersion = function(version) { + if (bot.userAgent.FIREFOX_EXTENSION) { + return bot.userAgent.FIREFOX_EXTENSION_IS_ENGINE_VERSION_(version); + } else if (goog.userAgent.IE) { + return goog.string.compareVersions( + /** @type {number} */ (goog.userAgent.DOCUMENT_MODE), version) >= 0; + } else { + return goog.userAgent.isVersionOrHigher(version); + } +}; + + +/** + * Whether the product version of the current browser is equal to or greater + * than the given version. This implementation differs from + * goog.userAgent.product.isVersion in the following ways: + *
      + *
    1. in a Firefox extension, tests the product version through the XUL version + * comparator service, because no window.navigator object is available + *
    2. on Android, always compares to the version to the OS version + *
    + * + * @param {string|number} version The version number to check. + * @return {boolean} Whether the browser product version is the same or higher + * than the given version. + */ +bot.userAgent.isProductVersion = function(version) { + if (bot.userAgent.FIREFOX_EXTENSION) { + return bot.userAgent.FIREFOX_EXTENSION_IS_PRODUCT_VERSION_(version); + } else if (goog.userAgent.product.ANDROID) { + return goog.string.compareVersions( + bot.userAgent.ANDROID_VERSION_, version) >= 0; + } else { + return goog.userAgent.product.isVersion(version); + } +}; + + +/** + * When we are in a Firefox extension, this is a function that accepts a version + * and returns whether the version of Gecko we are on is the same or higher + * than the given version. When we are not in a Firefox extension, this is null. + * @private {(undefined|function((string|number)): boolean)} + */ +bot.userAgent.FIREFOX_EXTENSION_IS_ENGINE_VERSION_; + + +/** + * When we are in a Firefox extension, this is a function that accepts a version + * and returns whether the version of Firefox we are on is the same or higher + * than the given version. When we are not in a Firefox extension, this is null. + * @private {(undefined|function((string|number)): boolean)} + */ +bot.userAgent.FIREFOX_EXTENSION_IS_PRODUCT_VERSION_; + + +/** + * Whether we are in a Firefox extension. + * + * @const + * @type {boolean} + */ +bot.userAgent.FIREFOX_EXTENSION = (function() { + // False if this browser is not a Gecko browser. + if (!goog.userAgent.GECKO) { + return false; + } + + // False if this code isn't running in an extension. + var Components = goog.global.Components; + if (!Components) { + return false; + } + try { + if (!Components['classes']) { + return false; + } + } catch (e) { + return false; + } + + // Populate the version checker functions. + var cc = Components['classes']; + var ci = Components['interfaces']; + var versionComparator = cc['@mozilla.org/xpcom/version-comparator;1'][ + 'getService'](ci['nsIVersionComparator']); + var appInfo = cc['@mozilla.org/xre/app-info;1']['getService']( + ci['nsIXULAppInfo']); + var geckoVersion = appInfo['platformVersion']; + var firefoxVersion = appInfo['version']; + + bot.userAgent.FIREFOX_EXTENSION_IS_ENGINE_VERSION_ = function(version) { + return versionComparator.compare(geckoVersion, '' + version) >= 0; + }; + bot.userAgent.FIREFOX_EXTENSION_IS_PRODUCT_VERSION_ = function(version) { + return versionComparator.compare(firefoxVersion, '' + version) >= 0; + }; + + return true; +})(); + + +/** + * Whether we are on IOS. + * + * @const + * @type {boolean} + */ +bot.userAgent.IOS = goog.userAgent.product.IPAD || + goog.userAgent.product.IPHONE; + + +/** + * Whether we are on a mobile browser. + * + * @const + * @type {boolean} + */ +bot.userAgent.MOBILE = bot.userAgent.IOS || goog.userAgent.product.ANDROID; + + +/** + * Android Operating System Version. + * @private {string} + * @const + */ +bot.userAgent.ANDROID_VERSION_ = (function() { + if (goog.userAgent.product.ANDROID) { + var userAgentString = goog.userAgent.getUserAgentString(); + var match = /Android\s+([0-9\.]+)/.exec(userAgentString); + return match ? match[1] : '0'; + } else { + return '0'; + } +})(); + + +/** + * Whether the current document is IE in a documentMode older than 8. + * @type {boolean} + * @const + */ +bot.userAgent.IE_DOC_PRE8 = goog.userAgent.IE && + !goog.userAgent.isDocumentModeOrHigher(8); + + +/** + * Whether the current document is IE in IE9 (or newer) standards mode. + * @type {boolean} + * @const + */ +bot.userAgent.IE_DOC_9 = goog.userAgent.isDocumentModeOrHigher(9); + + +/** + * Whether the current document is IE in a documentMode older than 9. + * @type {boolean} + * @const + */ +bot.userAgent.IE_DOC_PRE9 = goog.userAgent.IE && + !goog.userAgent.isDocumentModeOrHigher(9); + + +/** + * Whether the current document is IE in IE10 (or newer) standards mode. + * @type {boolean} + * @const + */ +bot.userAgent.IE_DOC_10 = goog.userAgent.isDocumentModeOrHigher(10); + + +/** + * Whether the current document is IE in a documentMode older than 10. + * @type {boolean} + * @const + */ +bot.userAgent.IE_DOC_PRE10 = goog.userAgent.IE && + !goog.userAgent.isDocumentModeOrHigher(10); + + +/** + * Whether the current browser is Android pre-gingerbread. + * @type {boolean} + * @const + */ +bot.userAgent.ANDROID_PRE_GINGERBREAD = goog.userAgent.product.ANDROID && + !bot.userAgent.isProductVersion(2.3); + + +/** + * Whether the current browser is Android pre-icecreamsandwich + * @type {boolean} + * @const + */ +bot.userAgent.ANDROID_PRE_ICECREAMSANDWICH = goog.userAgent.product.ANDROID && + !bot.userAgent.isProductVersion(4); + + +/** + * Whether the current browser is Safari 6. + * @type {boolean} + * @const + */ +bot.userAgent.SAFARI_6 = goog.userAgent.product.SAFARI && + bot.userAgent.isProductVersion(6); + + +/** + * Whether the current browser is Windows Phone. + * @type {boolean} + * @const + */ +bot.userAgent.WINDOWS_PHONE = goog.userAgent.IE && + goog.userAgent.getUserAgentString().indexOf('IEMobile') != -1; diff --git a/node_modules/selenium-webdriver/lib/goog/LICENSE b/node_modules/selenium-webdriver/lib/goog/LICENSE new file mode 100644 index 0000000..d9a10c0 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/goog/LICENSE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/node_modules/selenium-webdriver/lib/goog/array/array.js b/node_modules/selenium-webdriver/lib/goog/array/array.js new file mode 100644 index 0000000..2d8c23f --- /dev/null +++ b/node_modules/selenium-webdriver/lib/goog/array/array.js @@ -0,0 +1,1570 @@ +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Utilities for manipulating arrays. + * + */ + + +goog.provide('goog.array'); +goog.provide('goog.array.ArrayLike'); + +goog.require('goog.asserts'); + + +/** + * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should + * rely on Array.prototype functions, if available. + * + * The Array.prototype functions can be defined by external libraries like + * Prototype and setting this flag to false forces closure to use its own + * goog.array implementation. + * + * If your javascript can be loaded by a third party site and you are wary about + * relying on the prototype functions, specify + * "--define goog.NATIVE_ARRAY_PROTOTYPES=false" to the JSCompiler. + * + * Setting goog.TRUSTED_SITE to false will automatically set + * NATIVE_ARRAY_PROTOTYPES to false. + */ +goog.define('goog.NATIVE_ARRAY_PROTOTYPES', goog.TRUSTED_SITE); + + +/** + * @define {boolean} If true, JSCompiler will use the native implementation of + * array functions where appropriate (e.g., {@code Array#filter}) and remove the + * unused pure JS implementation. + */ +goog.define('goog.array.ASSUME_NATIVE_FUNCTIONS', false); + + +/** + * @typedef {Array|NodeList|Arguments|{length: number}} + */ +goog.array.ArrayLike; + + +/** + * Returns the last element in an array without removing it. + * Same as goog.array.last. + * @param {Array.|goog.array.ArrayLike} array The array. + * @return {T} Last item in array. + * @template T + */ +goog.array.peek = function(array) { + return array[array.length - 1]; +}; + + +/** + * Returns the last element in an array without removing it. + * Same as goog.array.peek. + * @param {Array.|goog.array.ArrayLike} array The array. + * @return {T} Last item in array. + * @template T + */ +goog.array.last = goog.array.peek; + + +/** + * Reference to the original {@code Array.prototype}. + * @private + */ +goog.array.ARRAY_PROTOTYPE_ = Array.prototype; + + +// NOTE(arv): Since most of the array functions are generic it allows you to +// pass an array-like object. Strings have a length and are considered array- +// like. However, the 'in' operator does not work on strings so we cannot just +// use the array path even if the browser supports indexing into strings. We +// therefore end up splitting the string. + + +/** + * Returns the index of the first element of an array with a specified value, or + * -1 if the element is not present in the array. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof} + * + * @param {Array.|goog.array.ArrayLike} arr The array to be searched. + * @param {T} obj The object for which we are searching. + * @param {number=} opt_fromIndex The index at which to start the search. If + * omitted the search starts at index 0. + * @return {number} The index of the first matching array element. + * @template T + */ +goog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || + goog.array.ARRAY_PROTOTYPE_.indexOf) ? + function(arr, obj, opt_fromIndex) { + goog.asserts.assert(arr.length != null); + + return goog.array.ARRAY_PROTOTYPE_.indexOf.call(arr, obj, opt_fromIndex); + } : + function(arr, obj, opt_fromIndex) { + var fromIndex = opt_fromIndex == null ? + 0 : (opt_fromIndex < 0 ? + Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex); + + if (goog.isString(arr)) { + // Array.prototype.indexOf uses === so only strings should be found. + if (!goog.isString(obj) || obj.length != 1) { + return -1; + } + return arr.indexOf(obj, fromIndex); + } + + for (var i = fromIndex; i < arr.length; i++) { + if (i in arr && arr[i] === obj) + return i; + } + return -1; + }; + + +/** + * Returns the index of the last element of an array with a specified value, or + * -1 if the element is not present in the array. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof} + * + * @param {!Array.|!goog.array.ArrayLike} arr The array to be searched. + * @param {T} obj The object for which we are searching. + * @param {?number=} opt_fromIndex The index at which to start the search. If + * omitted the search starts at the end of the array. + * @return {number} The index of the last matching array element. + * @template T + */ +goog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || + goog.array.ARRAY_PROTOTYPE_.lastIndexOf) ? + function(arr, obj, opt_fromIndex) { + goog.asserts.assert(arr.length != null); + + // Firefox treats undefined and null as 0 in the fromIndex argument which + // leads it to always return -1 + var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex; + return goog.array.ARRAY_PROTOTYPE_.lastIndexOf.call(arr, obj, fromIndex); + } : + function(arr, obj, opt_fromIndex) { + var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex; + + if (fromIndex < 0) { + fromIndex = Math.max(0, arr.length + fromIndex); + } + + if (goog.isString(arr)) { + // Array.prototype.lastIndexOf uses === so only strings should be found. + if (!goog.isString(obj) || obj.length != 1) { + return -1; + } + return arr.lastIndexOf(obj, fromIndex); + } + + for (var i = fromIndex; i >= 0; i--) { + if (i in arr && arr[i] === obj) + return i; + } + return -1; + }; + + +/** + * Calls a function for each element in an array. Skips holes in the array. + * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach} + * + * @param {Array.|goog.array.ArrayLike} arr Array or array like object over + * which to iterate. + * @param {?function(this: S, T, number, ?): ?} f The function to call for every + * element. This function takes 3 arguments (the element, the index and the + * array). The return value is ignored. + * @param {S=} opt_obj The object to be used as the value of 'this' within f. + * @template T,S + */ +goog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || + goog.array.ARRAY_PROTOTYPE_.forEach) ? + function(arr, f, opt_obj) { + goog.asserts.assert(arr.length != null); + + goog.array.ARRAY_PROTOTYPE_.forEach.call(arr, f, opt_obj); + } : + function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = 0; i < l; i++) { + if (i in arr2) { + f.call(opt_obj, arr2[i], i, arr); + } + } + }; + + +/** + * Calls a function for each element in an array, starting from the last + * element rather than the first. + * + * @param {Array.|goog.array.ArrayLike} arr Array or array + * like object over which to iterate. + * @param {?function(this: S, T, number, ?): ?} f The function to call for every + * element. This function + * takes 3 arguments (the element, the index and the array). The return + * value is ignored. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within f. + * @template T,S + */ +goog.array.forEachRight = function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = l - 1; i >= 0; --i) { + if (i in arr2) { + f.call(opt_obj, arr2[i], i, arr); + } + } +}; + + +/** + * Calls a function for each element in an array, and if the function returns + * true adds the element to a new array. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-filter} + * + * @param {Array.|goog.array.ArrayLike} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?):boolean} f The function to call for + * every element. This function + * takes 3 arguments (the element, the index and the array) and must + * return a Boolean. If the return value is true the element is added to the + * result array. If it is false the element is not included. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within f. + * @return {!Array.} a new array in which only elements that passed the test + * are present. + * @template T,S + */ +goog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || + goog.array.ARRAY_PROTOTYPE_.filter) ? + function(arr, f, opt_obj) { + goog.asserts.assert(arr.length != null); + + return goog.array.ARRAY_PROTOTYPE_.filter.call(arr, f, opt_obj); + } : + function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var res = []; + var resLength = 0; + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = 0; i < l; i++) { + if (i in arr2) { + var val = arr2[i]; // in case f mutates arr2 + if (f.call(opt_obj, val, i, arr)) { + res[resLength++] = val; + } + } + } + return res; + }; + + +/** + * Calls a function for each element in an array and inserts the result into a + * new array. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-map} + * + * @param {Array.|goog.array.ArrayLike} arr Array or array like object + * over which to iterate. + * @param {function(this:THIS, VALUE, number, ?): RESULT} f The function to call + * for every element. This function takes 3 arguments (the element, + * the index and the array) and should return something. The result will be + * inserted into a new array. + * @param {THIS=} opt_obj The object to be used as the value of 'this' within f. + * @return {!Array.} a new array with the results from f. + * @template THIS, VALUE, RESULT + */ +goog.array.map = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || + goog.array.ARRAY_PROTOTYPE_.map) ? + function(arr, f, opt_obj) { + goog.asserts.assert(arr.length != null); + + return goog.array.ARRAY_PROTOTYPE_.map.call(arr, f, opt_obj); + } : + function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var res = new Array(l); + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = 0; i < l; i++) { + if (i in arr2) { + res[i] = f.call(opt_obj, arr2[i], i, arr); + } + } + return res; + }; + + +/** + * Passes every element of an array into a function and accumulates the result. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce} + * + * For example: + * var a = [1, 2, 3, 4]; + * goog.array.reduce(a, function(r, v, i, arr) {return r + v;}, 0); + * returns 10 + * + * @param {Array.|goog.array.ArrayLike} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, R, T, number, ?) : R} f The function to call for + * every element. This function + * takes 4 arguments (the function's previous result or the initial value, + * the value of the current array element, the current array index, and the + * array itself) + * function(previousValue, currentValue, index, array). + * @param {?} val The initial value to pass into the function on the first call. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within f. + * @return {R} Result of evaluating f repeatedly across the values of the array. + * @template T,S,R + */ +goog.array.reduce = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || + goog.array.ARRAY_PROTOTYPE_.reduce) ? + function(arr, f, val, opt_obj) { + goog.asserts.assert(arr.length != null); + if (opt_obj) { + f = goog.bind(f, opt_obj); + } + return goog.array.ARRAY_PROTOTYPE_.reduce.call(arr, f, val); + } : + function(arr, f, val, opt_obj) { + var rval = val; + goog.array.forEach(arr, function(val, index) { + rval = f.call(opt_obj, rval, val, index, arr); + }); + return rval; + }; + + +/** + * Passes every element of an array into a function and accumulates the result, + * starting from the last element and working towards the first. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright} + * + * For example: + * var a = ['a', 'b', 'c']; + * goog.array.reduceRight(a, function(r, v, i, arr) {return r + v;}, ''); + * returns 'cba' + * + * @param {Array.|goog.array.ArrayLike} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, R, T, number, ?) : R} f The function to call for + * every element. This function + * takes 4 arguments (the function's previous result or the initial value, + * the value of the current array element, the current array index, and the + * array itself) + * function(previousValue, currentValue, index, array). + * @param {?} val The initial value to pass into the function on the first call. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within f. + * @return {R} Object returned as a result of evaluating f repeatedly across the + * values of the array. + * @template T,S,R + */ +goog.array.reduceRight = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || + goog.array.ARRAY_PROTOTYPE_.reduceRight) ? + function(arr, f, val, opt_obj) { + goog.asserts.assert(arr.length != null); + if (opt_obj) { + f = goog.bind(f, opt_obj); + } + return goog.array.ARRAY_PROTOTYPE_.reduceRight.call(arr, f, val); + } : + function(arr, f, val, opt_obj) { + var rval = val; + goog.array.forEachRight(arr, function(val, index) { + rval = f.call(opt_obj, rval, val, index, arr); + }); + return rval; + }; + + +/** + * Calls f for each element of an array. If any call returns true, some() + * returns true (without checking the remaining elements). If all calls + * return false, some() returns false. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-some} + * + * @param {Array.|goog.array.ArrayLike} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call for + * for every element. This function takes 3 arguments (the element, the + * index and the array) and should return a boolean. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within f. + * @return {boolean} true if any element passes the test. + * @template T,S + */ +goog.array.some = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || + goog.array.ARRAY_PROTOTYPE_.some) ? + function(arr, f, opt_obj) { + goog.asserts.assert(arr.length != null); + + return goog.array.ARRAY_PROTOTYPE_.some.call(arr, f, opt_obj); + } : + function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = 0; i < l; i++) { + if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) { + return true; + } + } + return false; + }; + + +/** + * Call f for each element of an array. If all calls return true, every() + * returns true. If any call returns false, every() returns false and + * does not continue to check the remaining elements. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-every} + * + * @param {Array.|goog.array.ArrayLike} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call for + * for every element. This function takes 3 arguments (the element, the + * index and the array) and should return a boolean. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within f. + * @return {boolean} false if any element fails the test. + * @template T,S + */ +goog.array.every = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || + goog.array.ARRAY_PROTOTYPE_.every) ? + function(arr, f, opt_obj) { + goog.asserts.assert(arr.length != null); + + return goog.array.ARRAY_PROTOTYPE_.every.call(arr, f, opt_obj); + } : + function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = 0; i < l; i++) { + if (i in arr2 && !f.call(opt_obj, arr2[i], i, arr)) { + return false; + } + } + return true; + }; + + +/** + * Counts the array elements that fulfill the predicate, i.e. for which the + * callback function returns true. Skips holes in the array. + * + * @param {!(Array.|goog.array.ArrayLike)} arr Array or array like object + * over which to iterate. + * @param {function(this: S, T, number, ?): boolean} f The function to call for + * every element. Takes 3 arguments (the element, the index and the array). + * @param {S=} opt_obj The object to be used as the value of 'this' within f. + * @return {number} The number of the matching elements. + * @template T,S + */ +goog.array.count = function(arr, f, opt_obj) { + var count = 0; + goog.array.forEach(arr, function(element, index, arr) { + if (f.call(opt_obj, element, index, arr)) { + ++count; + } + }, opt_obj); + return count; +}; + + +/** + * Search an array for the first element that satisfies a given condition and + * return that element. + * @param {Array.|goog.array.ArrayLike} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call + * for every element. This function takes 3 arguments (the element, the + * index and the array) and should return a boolean. + * @param {S=} opt_obj An optional "this" context for the function. + * @return {?T} The first array element that passes the test, or null if no + * element is found. + * @template T,S + */ +goog.array.find = function(arr, f, opt_obj) { + var i = goog.array.findIndex(arr, f, opt_obj); + return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i]; +}; + + +/** + * Search an array for the first element that satisfies a given condition and + * return its index. + * @param {Array.|goog.array.ArrayLike} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call for + * every element. This function + * takes 3 arguments (the element, the index and the array) and should + * return a boolean. + * @param {S=} opt_obj An optional "this" context for the function. + * @return {number} The index of the first array element that passes the test, + * or -1 if no element is found. + * @template T,S + */ +goog.array.findIndex = function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = 0; i < l; i++) { + if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) { + return i; + } + } + return -1; +}; + + +/** + * Search an array (in reverse order) for the last element that satisfies a + * given condition and return that element. + * @param {Array.|goog.array.ArrayLike} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call + * for every element. This function + * takes 3 arguments (the element, the index and the array) and should + * return a boolean. + * @param {S=} opt_obj An optional "this" context for the function. + * @return {?T} The last array element that passes the test, or null if no + * element is found. + * @template T,S + */ +goog.array.findRight = function(arr, f, opt_obj) { + var i = goog.array.findIndexRight(arr, f, opt_obj); + return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i]; +}; + + +/** + * Search an array (in reverse order) for the last element that satisfies a + * given condition and return its index. + * @param {Array.|goog.array.ArrayLike} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call + * for every element. This function + * takes 3 arguments (the element, the index and the array) and should + * return a boolean. + * @param {Object=} opt_obj An optional "this" context for the function. + * @return {number} The index of the last array element that passes the test, + * or -1 if no element is found. + * @template T,S + */ +goog.array.findIndexRight = function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = l - 1; i >= 0; i--) { + if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) { + return i; + } + } + return -1; +}; + + +/** + * Whether the array contains the given object. + * @param {goog.array.ArrayLike} arr The array to test for the presence of the + * element. + * @param {*} obj The object for which to test. + * @return {boolean} true if obj is present. + */ +goog.array.contains = function(arr, obj) { + return goog.array.indexOf(arr, obj) >= 0; +}; + + +/** + * Whether the array is empty. + * @param {goog.array.ArrayLike} arr The array to test. + * @return {boolean} true if empty. + */ +goog.array.isEmpty = function(arr) { + return arr.length == 0; +}; + + +/** + * Clears the array. + * @param {goog.array.ArrayLike} arr Array or array like object to clear. + */ +goog.array.clear = function(arr) { + // For non real arrays we don't have the magic length so we delete the + // indices. + if (!goog.isArray(arr)) { + for (var i = arr.length - 1; i >= 0; i--) { + delete arr[i]; + } + } + arr.length = 0; +}; + + +/** + * Pushes an item into an array, if it's not already in the array. + * @param {Array.} arr Array into which to insert the item. + * @param {T} obj Value to add. + * @template T + */ +goog.array.insert = function(arr, obj) { + if (!goog.array.contains(arr, obj)) { + arr.push(obj); + } +}; + + +/** + * Inserts an object at the given index of the array. + * @param {goog.array.ArrayLike} arr The array to modify. + * @param {*} obj The object to insert. + * @param {number=} opt_i The index at which to insert the object. If omitted, + * treated as 0. A negative index is counted from the end of the array. + */ +goog.array.insertAt = function(arr, obj, opt_i) { + goog.array.splice(arr, opt_i, 0, obj); +}; + + +/** + * Inserts at the given index of the array, all elements of another array. + * @param {goog.array.ArrayLike} arr The array to modify. + * @param {goog.array.ArrayLike} elementsToAdd The array of elements to add. + * @param {number=} opt_i The index at which to insert the object. If omitted, + * treated as 0. A negative index is counted from the end of the array. + */ +goog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) { + goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd); +}; + + +/** + * Inserts an object into an array before a specified object. + * @param {Array.} arr The array to modify. + * @param {T} obj The object to insert. + * @param {T=} opt_obj2 The object before which obj should be inserted. If obj2 + * is omitted or not found, obj is inserted at the end of the array. + * @template T + */ +goog.array.insertBefore = function(arr, obj, opt_obj2) { + var i; + if (arguments.length == 2 || (i = goog.array.indexOf(arr, opt_obj2)) < 0) { + arr.push(obj); + } else { + goog.array.insertAt(arr, obj, i); + } +}; + + +/** + * Removes the first occurrence of a particular value from an array. + * @param {Array.|goog.array.ArrayLike} arr Array from which to remove + * value. + * @param {T} obj Object to remove. + * @return {boolean} True if an element was removed. + * @template T + */ +goog.array.remove = function(arr, obj) { + var i = goog.array.indexOf(arr, obj); + var rv; + if ((rv = i >= 0)) { + goog.array.removeAt(arr, i); + } + return rv; +}; + + +/** + * Removes from an array the element at index i + * @param {goog.array.ArrayLike} arr Array or array like object from which to + * remove value. + * @param {number} i The index to remove. + * @return {boolean} True if an element was removed. + */ +goog.array.removeAt = function(arr, i) { + goog.asserts.assert(arr.length != null); + + // use generic form of splice + // splice returns the removed items and if successful the length of that + // will be 1 + return goog.array.ARRAY_PROTOTYPE_.splice.call(arr, i, 1).length == 1; +}; + + +/** + * Removes the first value that satisfies the given condition. + * @param {Array.|goog.array.ArrayLike} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call + * for every element. This function + * takes 3 arguments (the element, the index and the array) and should + * return a boolean. + * @param {S=} opt_obj An optional "this" context for the function. + * @return {boolean} True if an element was removed. + * @template T,S + */ +goog.array.removeIf = function(arr, f, opt_obj) { + var i = goog.array.findIndex(arr, f, opt_obj); + if (i >= 0) { + goog.array.removeAt(arr, i); + return true; + } + return false; +}; + + +/** + * Returns a new array that is the result of joining the arguments. If arrays + * are passed then their items are added, however, if non-arrays are passed they + * will be added to the return array as is. + * + * Note that ArrayLike objects will be added as is, rather than having their + * items added. + * + * goog.array.concat([1, 2], [3, 4]) -> [1, 2, 3, 4] + * goog.array.concat(0, [1, 2]) -> [0, 1, 2] + * goog.array.concat([1, 2], null) -> [1, 2, null] + * + * There is bug in all current versions of IE (6, 7 and 8) where arrays created + * in an iframe become corrupted soon (not immediately) after the iframe is + * destroyed. This is common if loading data via goog.net.IframeIo, for example. + * This corruption only affects the concat method which will start throwing + * Catastrophic Errors (#-2147418113). + * + * See http://endoflow.com/scratch/corrupted-arrays.html for a test case. + * + * Internally goog.array should use this, so that all methods will continue to + * work on these broken array objects. + * + * @param {...*} var_args Items to concatenate. Arrays will have each item + * added, while primitives and objects will be added as is. + * @return {!Array} The new resultant array. + */ +goog.array.concat = function(var_args) { + return goog.array.ARRAY_PROTOTYPE_.concat.apply( + goog.array.ARRAY_PROTOTYPE_, arguments); +}; + + +/** + * Returns a new array that contains the contents of all the arrays passed. + * @param {...!Array.} var_args + * @return {!Array.} + * @template T + */ +goog.array.join = function(var_args) { + return goog.array.ARRAY_PROTOTYPE_.concat.apply( + goog.array.ARRAY_PROTOTYPE_, arguments); +}; + + +/** + * Converts an object to an array. + * @param {Array.|goog.array.ArrayLike} object The object to convert to an + * array. + * @return {!Array.} The object converted into an array. If object has a + * length property, every property indexed with a non-negative number + * less than length will be included in the result. If object does not + * have a length property, an empty array will be returned. + * @template T + */ +goog.array.toArray = function(object) { + var length = object.length; + + // If length is not a number the following it false. This case is kept for + // backwards compatibility since there are callers that pass objects that are + // not array like. + if (length > 0) { + var rv = new Array(length); + for (var i = 0; i < length; i++) { + rv[i] = object[i]; + } + return rv; + } + return []; +}; + + +/** + * Does a shallow copy of an array. + * @param {Array.|goog.array.ArrayLike} arr Array or array-like object to + * clone. + * @return {!Array.} Clone of the input array. + * @template T + */ +goog.array.clone = goog.array.toArray; + + +/** + * Extends an array with another array, element, or "array like" object. + * This function operates 'in-place', it does not create a new Array. + * + * Example: + * var a = []; + * goog.array.extend(a, [0, 1]); + * a; // [0, 1] + * goog.array.extend(a, 2); + * a; // [0, 1, 2] + * + * @param {Array.} arr1 The array to modify. + * @param {...(Array.|VALUE)} var_args The elements or arrays of elements + * to add to arr1. + * @template VALUE + */ +goog.array.extend = function(arr1, var_args) { + for (var i = 1; i < arguments.length; i++) { + var arr2 = arguments[i]; + // If we have an Array or an Arguments object we can just call push + // directly. + var isArrayLike; + if (goog.isArray(arr2) || + // Detect Arguments. ES5 says that the [[Class]] of an Arguments object + // is "Arguments" but only V8 and JSC/Safari gets this right. We instead + // detect Arguments by checking for array like and presence of "callee". + (isArrayLike = goog.isArrayLike(arr2)) && + // The getter for callee throws an exception in strict mode + // according to section 10.6 in ES5 so check for presence instead. + Object.prototype.hasOwnProperty.call(arr2, 'callee')) { + arr1.push.apply(arr1, arr2); + } else if (isArrayLike) { + // Otherwise loop over arr2 to prevent copying the object. + var len1 = arr1.length; + var len2 = arr2.length; + for (var j = 0; j < len2; j++) { + arr1[len1 + j] = arr2[j]; + } + } else { + arr1.push(arr2); + } + } +}; + + +/** + * Adds or removes elements from an array. This is a generic version of Array + * splice. This means that it might work on other objects similar to arrays, + * such as the arguments object. + * + * @param {Array.|goog.array.ArrayLike} arr The array to modify. + * @param {number|undefined} index The index at which to start changing the + * array. If not defined, treated as 0. + * @param {number} howMany How many elements to remove (0 means no removal. A + * value below 0 is treated as zero and so is any other non number. Numbers + * are floored). + * @param {...T} var_args Optional, additional elements to insert into the + * array. + * @return {!Array.} the removed elements. + * @template T + */ +goog.array.splice = function(arr, index, howMany, var_args) { + goog.asserts.assert(arr.length != null); + + return goog.array.ARRAY_PROTOTYPE_.splice.apply( + arr, goog.array.slice(arguments, 1)); +}; + + +/** + * Returns a new array from a segment of an array. This is a generic version of + * Array slice. This means that it might work on other objects similar to + * arrays, such as the arguments object. + * + * @param {Array.|goog.array.ArrayLike} arr The array from + * which to copy a segment. + * @param {number} start The index of the first element to copy. + * @param {number=} opt_end The index after the last element to copy. + * @return {!Array.} A new array containing the specified segment of the + * original array. + * @template T + */ +goog.array.slice = function(arr, start, opt_end) { + goog.asserts.assert(arr.length != null); + + // passing 1 arg to slice is not the same as passing 2 where the second is + // null or undefined (in that case the second argument is treated as 0). + // we could use slice on the arguments object and then use apply instead of + // testing the length + if (arguments.length <= 2) { + return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start); + } else { + return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start, opt_end); + } +}; + + +/** + * Removes all duplicates from an array (retaining only the first + * occurrence of each array element). This function modifies the + * array in place and doesn't change the order of the non-duplicate items. + * + * For objects, duplicates are identified as having the same unique ID as + * defined by {@link goog.getUid}. + * + * Alternatively you can specify a custom hash function that returns a unique + * value for each item in the array it should consider unique. + * + * Runtime: N, + * Worstcase space: 2N (no dupes) + * + * @param {Array.|goog.array.ArrayLike} arr The array from which to remove + * duplicates. + * @param {Array=} opt_rv An optional array in which to return the results, + * instead of performing the removal inplace. If specified, the original + * array will remain unchanged. + * @param {function(T):string=} opt_hashFn An optional function to use to + * apply to every item in the array. This function should return a unique + * value for each item in the array it should consider unique. + * @template T + */ +goog.array.removeDuplicates = function(arr, opt_rv, opt_hashFn) { + var returnArray = opt_rv || arr; + var defaultHashFn = function(item) { + // Prefix each type with a single character representing the type to + // prevent conflicting keys (e.g. true and 'true'). + return goog.isObject(current) ? 'o' + goog.getUid(current) : + (typeof current).charAt(0) + current; + }; + var hashFn = opt_hashFn || defaultHashFn; + + var seen = {}, cursorInsert = 0, cursorRead = 0; + while (cursorRead < arr.length) { + var current = arr[cursorRead++]; + var key = hashFn(current); + if (!Object.prototype.hasOwnProperty.call(seen, key)) { + seen[key] = true; + returnArray[cursorInsert++] = current; + } + } + returnArray.length = cursorInsert; +}; + + +/** + * Searches the specified array for the specified target using the binary + * search algorithm. If no opt_compareFn is specified, elements are compared + * using goog.array.defaultCompare, which compares the elements + * using the built in < and > operators. This will produce the expected + * behavior for homogeneous arrays of String(s) and Number(s). The array + * specified must be sorted in ascending order (as defined by the + * comparison function). If the array is not sorted, results are undefined. + * If the array contains multiple instances of the specified target value, any + * of these instances may be found. + * + * Runtime: O(log n) + * + * @param {Array.|goog.array.ArrayLike} arr The array to be searched. + * @param {TARGET} target The sought value. + * @param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison + * function by which the array is ordered. Should take 2 arguments to + * compare, and return a negative number, zero, or a positive number + * depending on whether the first argument is less than, equal to, or + * greater than the second. + * @return {number} Lowest index of the target value if found, otherwise + * (-(insertion point) - 1). The insertion point is where the value should + * be inserted into arr to preserve the sorted property. Return value >= 0 + * iff target is found. + * @template TARGET, VALUE + */ +goog.array.binarySearch = function(arr, target, opt_compareFn) { + return goog.array.binarySearch_(arr, + opt_compareFn || goog.array.defaultCompare, false /* isEvaluator */, + target); +}; + + +/** + * Selects an index in the specified array using the binary search algorithm. + * The evaluator receives an element and determines whether the desired index + * is before, at, or after it. The evaluator must be consistent (formally, + * goog.array.map(goog.array.map(arr, evaluator, opt_obj), goog.math.sign) + * must be monotonically non-increasing). + * + * Runtime: O(log n) + * + * @param {Array.|goog.array.ArrayLike} arr The array to be searched. + * @param {function(this:THIS, VALUE, number, ?): number} evaluator + * Evaluator function that receives 3 arguments (the element, the index and + * the array). Should return a negative number, zero, or a positive number + * depending on whether the desired index is before, at, or after the + * element passed to it. + * @param {THIS=} opt_obj The object to be used as the value of 'this' + * within evaluator. + * @return {number} Index of the leftmost element matched by the evaluator, if + * such exists; otherwise (-(insertion point) - 1). The insertion point is + * the index of the first element for which the evaluator returns negative, + * or arr.length if no such element exists. The return value is non-negative + * iff a match is found. + * @template THIS, VALUE + */ +goog.array.binarySelect = function(arr, evaluator, opt_obj) { + return goog.array.binarySearch_(arr, evaluator, true /* isEvaluator */, + undefined /* opt_target */, opt_obj); +}; + + +/** + * Implementation of a binary search algorithm which knows how to use both + * comparison functions and evaluators. If an evaluator is provided, will call + * the evaluator with the given optional data object, conforming to the + * interface defined in binarySelect. Otherwise, if a comparison function is + * provided, will call the comparison function against the given data object. + * + * This implementation purposefully does not use goog.bind or goog.partial for + * performance reasons. + * + * Runtime: O(log n) + * + * @param {Array.|goog.array.ArrayLike} arr The array to be searched. + * @param {function(TARGET, VALUE): number| + * function(this:THIS, VALUE, number, ?): number} compareFn Either an + * evaluator or a comparison function, as defined by binarySearch + * and binarySelect above. + * @param {boolean} isEvaluator Whether the function is an evaluator or a + * comparison function. + * @param {TARGET=} opt_target If the function is a comparison function, then + * this is the target to binary search for. + * @param {THIS=} opt_selfObj If the function is an evaluator, this is an + * optional this object for the evaluator. + * @return {number} Lowest index of the target value if found, otherwise + * (-(insertion point) - 1). The insertion point is where the value should + * be inserted into arr to preserve the sorted property. Return value >= 0 + * iff target is found. + * @template THIS, VALUE, TARGET + * @private + */ +goog.array.binarySearch_ = function(arr, compareFn, isEvaluator, opt_target, + opt_selfObj) { + var left = 0; // inclusive + var right = arr.length; // exclusive + var found; + while (left < right) { + var middle = (left + right) >> 1; + var compareResult; + if (isEvaluator) { + compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr); + } else { + compareResult = compareFn(opt_target, arr[middle]); + } + if (compareResult > 0) { + left = middle + 1; + } else { + right = middle; + // We are looking for the lowest index so we can't return immediately. + found = !compareResult; + } + } + // left is the index if found, or the insertion point otherwise. + // ~left is a shorthand for -left - 1. + return found ? left : ~left; +}; + + +/** + * Sorts the specified array into ascending order. If no opt_compareFn is + * specified, elements are compared using + * goog.array.defaultCompare, which compares the elements using + * the built in < and > operators. This will produce the expected behavior + * for homogeneous arrays of String(s) and Number(s), unlike the native sort, + * but will give unpredictable results for heterogenous lists of strings and + * numbers with different numbers of digits. + * + * This sort is not guaranteed to be stable. + * + * Runtime: Same as Array.prototype.sort + * + * @param {Array.} arr The array to be sorted. + * @param {?function(T,T):number=} opt_compareFn Optional comparison + * function by which the + * array is to be ordered. Should take 2 arguments to compare, and return a + * negative number, zero, or a positive number depending on whether the + * first argument is less than, equal to, or greater than the second. + * @template T + */ +goog.array.sort = function(arr, opt_compareFn) { + // TODO(arv): Update type annotation since null is not accepted. + arr.sort(opt_compareFn || goog.array.defaultCompare); +}; + + +/** + * Sorts the specified array into ascending order in a stable way. If no + * opt_compareFn is specified, elements are compared using + * goog.array.defaultCompare, which compares the elements using + * the built in < and > operators. This will produce the expected behavior + * for homogeneous arrays of String(s) and Number(s). + * + * Runtime: Same as Array.prototype.sort, plus an additional + * O(n) overhead of copying the array twice. + * + * @param {Array.} arr The array to be sorted. + * @param {?function(T, T): number=} opt_compareFn Optional comparison function + * by which the array is to be ordered. Should take 2 arguments to compare, + * and return a negative number, zero, or a positive number depending on + * whether the first argument is less than, equal to, or greater than the + * second. + * @template T + */ +goog.array.stableSort = function(arr, opt_compareFn) { + for (var i = 0; i < arr.length; i++) { + arr[i] = {index: i, value: arr[i]}; + } + var valueCompareFn = opt_compareFn || goog.array.defaultCompare; + function stableCompareFn(obj1, obj2) { + return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index; + }; + goog.array.sort(arr, stableCompareFn); + for (var i = 0; i < arr.length; i++) { + arr[i] = arr[i].value; + } +}; + + +/** + * Sorts an array of objects by the specified object key and compare + * function. If no compare function is provided, the key values are + * compared in ascending order using goog.array.defaultCompare. + * This won't work for keys that get renamed by the compiler. So use + * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}. + * @param {Array.} arr An array of objects to sort. + * @param {string} key The object key to sort by. + * @param {Function=} opt_compareFn The function to use to compare key + * values. + */ +goog.array.sortObjectsByKey = function(arr, key, opt_compareFn) { + var compare = opt_compareFn || goog.array.defaultCompare; + goog.array.sort(arr, function(a, b) { + return compare(a[key], b[key]); + }); +}; + + +/** + * Tells if the array is sorted. + * @param {!Array.} arr The array. + * @param {?function(T,T):number=} opt_compareFn Function to compare the + * array elements. + * Should take 2 arguments to compare, and return a negative number, zero, + * or a positive number depending on whether the first argument is less + * than, equal to, or greater than the second. + * @param {boolean=} opt_strict If true no equal elements are allowed. + * @return {boolean} Whether the array is sorted. + * @template T + */ +goog.array.isSorted = function(arr, opt_compareFn, opt_strict) { + var compare = opt_compareFn || goog.array.defaultCompare; + for (var i = 1; i < arr.length; i++) { + var compareResult = compare(arr[i - 1], arr[i]); + if (compareResult > 0 || compareResult == 0 && opt_strict) { + return false; + } + } + return true; +}; + + +/** + * Compares two arrays for equality. Two arrays are considered equal if they + * have the same length and their corresponding elements are equal according to + * the comparison function. + * + * @param {goog.array.ArrayLike} arr1 The first array to compare. + * @param {goog.array.ArrayLike} arr2 The second array to compare. + * @param {Function=} opt_equalsFn Optional comparison function. + * Should take 2 arguments to compare, and return true if the arguments + * are equal. Defaults to {@link goog.array.defaultCompareEquality} which + * compares the elements using the built-in '===' operator. + * @return {boolean} Whether the two arrays are equal. + */ +goog.array.equals = function(arr1, arr2, opt_equalsFn) { + if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) || + arr1.length != arr2.length) { + return false; + } + var l = arr1.length; + var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality; + for (var i = 0; i < l; i++) { + if (!equalsFn(arr1[i], arr2[i])) { + return false; + } + } + return true; +}; + + +/** + * 3-way array compare function. + * @param {!Array.|!goog.array.ArrayLike} arr1 The first array to + * compare. + * @param {!Array.|!goog.array.ArrayLike} arr2 The second array to + * compare. + * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison + * function by which the array is to be ordered. Should take 2 arguments to + * compare, and return a negative number, zero, or a positive number + * depending on whether the first argument is less than, equal to, or + * greater than the second. + * @return {number} Negative number, zero, or a positive number depending on + * whether the first argument is less than, equal to, or greater than the + * second. + * @template VALUE + */ +goog.array.compare3 = function(arr1, arr2, opt_compareFn) { + var compare = opt_compareFn || goog.array.defaultCompare; + var l = Math.min(arr1.length, arr2.length); + for (var i = 0; i < l; i++) { + var result = compare(arr1[i], arr2[i]); + if (result != 0) { + return result; + } + } + return goog.array.defaultCompare(arr1.length, arr2.length); +}; + + +/** + * Compares its two arguments for order, using the built in < and > + * operators. + * @param {VALUE} a The first object to be compared. + * @param {VALUE} b The second object to be compared. + * @return {number} A negative number, zero, or a positive number as the first + * argument is less than, equal to, or greater than the second. + * @template VALUE + */ +goog.array.defaultCompare = function(a, b) { + return a > b ? 1 : a < b ? -1 : 0; +}; + + +/** + * Compares its two arguments for equality, using the built in === operator. + * @param {*} a The first object to compare. + * @param {*} b The second object to compare. + * @return {boolean} True if the two arguments are equal, false otherwise. + */ +goog.array.defaultCompareEquality = function(a, b) { + return a === b; +}; + + +/** + * Inserts a value into a sorted array. The array is not modified if the + * value is already present. + * @param {Array.|goog.array.ArrayLike} array The array to modify. + * @param {VALUE} value The object to insert. + * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison + * function by which the array is ordered. Should take 2 arguments to + * compare, and return a negative number, zero, or a positive number + * depending on whether the first argument is less than, equal to, or + * greater than the second. + * @return {boolean} True if an element was inserted. + * @template VALUE + */ +goog.array.binaryInsert = function(array, value, opt_compareFn) { + var index = goog.array.binarySearch(array, value, opt_compareFn); + if (index < 0) { + goog.array.insertAt(array, value, -(index + 1)); + return true; + } + return false; +}; + + +/** + * Removes a value from a sorted array. + * @param {!Array.|!goog.array.ArrayLike} array The array to modify. + * @param {VALUE} value The object to remove. + * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison + * function by which the array is ordered. Should take 2 arguments to + * compare, and return a negative number, zero, or a positive number + * depending on whether the first argument is less than, equal to, or + * greater than the second. + * @return {boolean} True if an element was removed. + * @template VALUE + */ +goog.array.binaryRemove = function(array, value, opt_compareFn) { + var index = goog.array.binarySearch(array, value, opt_compareFn); + return (index >= 0) ? goog.array.removeAt(array, index) : false; +}; + + +/** + * Splits an array into disjoint buckets according to a splitting function. + * @param {Array.} array The array. + * @param {function(this:S, T,number,Array.):?} sorter Function to call for + * every element. This takes 3 arguments (the element, the index and the + * array) and must return a valid object key (a string, number, etc), or + * undefined, if that object should not be placed in a bucket. + * @param {S=} opt_obj The object to be used as the value of 'this' within + * sorter. + * @return {!Object} An object, with keys being all of the unique return values + * of sorter, and values being arrays containing the items for + * which the splitter returned that key. + * @template T,S + */ +goog.array.bucket = function(array, sorter, opt_obj) { + var buckets = {}; + + for (var i = 0; i < array.length; i++) { + var value = array[i]; + var key = sorter.call(opt_obj, value, i, array); + if (goog.isDef(key)) { + // Push the value to the right bucket, creating it if necessary. + var bucket = buckets[key] || (buckets[key] = []); + bucket.push(value); + } + } + + return buckets; +}; + + +/** + * Creates a new object built from the provided array and the key-generation + * function. + * @param {Array.|goog.array.ArrayLike} arr Array or array like object over + * which to iterate whose elements will be the values in the new object. + * @param {?function(this:S, T, number, ?) : string} keyFunc The function to + * call for every element. This function takes 3 arguments (the element, the + * index and the array) and should return a string that will be used as the + * key for the element in the new object. If the function returns the same + * key for more than one element, the value for that key is + * implementation-defined. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within keyFunc. + * @return {!Object.} The new object. + * @template T,S + */ +goog.array.toObject = function(arr, keyFunc, opt_obj) { + var ret = {}; + goog.array.forEach(arr, function(element, index) { + ret[keyFunc.call(opt_obj, element, index, arr)] = element; + }); + return ret; +}; + + +/** + * Creates a range of numbers in an arithmetic progression. + * + * Range takes 1, 2, or 3 arguments: + *
    + * range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]
    + * range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]
    + * range(-2, -5, -1) produces [-2, -3, -4]
    + * range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.
    + * 
    + * + * @param {number} startOrEnd The starting value of the range if an end argument + * is provided. Otherwise, the start value is 0, and this is the end value. + * @param {number=} opt_end The optional end value of the range. + * @param {number=} opt_step The step size between range values. Defaults to 1 + * if opt_step is undefined or 0. + * @return {!Array.} An array of numbers for the requested range. May be + * an empty array if adding the step would not converge toward the end + * value. + */ +goog.array.range = function(startOrEnd, opt_end, opt_step) { + var array = []; + var start = 0; + var end = startOrEnd; + var step = opt_step || 1; + if (opt_end !== undefined) { + start = startOrEnd; + end = opt_end; + } + + if (step * (end - start) < 0) { + // Sign mismatch: start + step will never reach the end value. + return []; + } + + if (step > 0) { + for (var i = start; i < end; i += step) { + array.push(i); + } + } else { + for (var i = start; i > end; i += step) { + array.push(i); + } + } + return array; +}; + + +/** + * Returns an array consisting of the given value repeated N times. + * + * @param {VALUE} value The value to repeat. + * @param {number} n The repeat count. + * @return {!Array.} An array with the repeated value. + * @template VALUE + */ +goog.array.repeat = function(value, n) { + var array = []; + for (var i = 0; i < n; i++) { + array[i] = value; + } + return array; +}; + + +/** + * Returns an array consisting of every argument with all arrays + * expanded in-place recursively. + * + * @param {...*} var_args The values to flatten. + * @return {!Array} An array containing the flattened values. + */ +goog.array.flatten = function(var_args) { + var result = []; + for (var i = 0; i < arguments.length; i++) { + var element = arguments[i]; + if (goog.isArray(element)) { + result.push.apply(result, goog.array.flatten.apply(null, element)); + } else { + result.push(element); + } + } + return result; +}; + + +/** + * Rotates an array in-place. After calling this method, the element at + * index i will be the element previously at index (i - n) % + * array.length, for all values of i between 0 and array.length - 1, + * inclusive. + * + * For example, suppose list comprises [t, a, n, k, s]. After invoking + * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k]. + * + * @param {!Array.} array The array to rotate. + * @param {number} n The amount to rotate. + * @return {!Array.} The array. + * @template T + */ +goog.array.rotate = function(array, n) { + goog.asserts.assert(array.length != null); + + if (array.length) { + n %= array.length; + if (n > 0) { + goog.array.ARRAY_PROTOTYPE_.unshift.apply(array, array.splice(-n, n)); + } else if (n < 0) { + goog.array.ARRAY_PROTOTYPE_.push.apply(array, array.splice(0, -n)); + } + } + return array; +}; + + +/** + * Moves one item of an array to a new position keeping the order of the rest + * of the items. Example use case: keeping a list of JavaScript objects + * synchronized with the corresponding list of DOM elements after one of the + * elements has been dragged to a new position. + * @param {!(Array|Arguments|{length:number})} arr The array to modify. + * @param {number} fromIndex Index of the item to move between 0 and + * {@code arr.length - 1}. + * @param {number} toIndex Target index between 0 and {@code arr.length - 1}. + */ +goog.array.moveItem = function(arr, fromIndex, toIndex) { + goog.asserts.assert(fromIndex >= 0 && fromIndex < arr.length); + goog.asserts.assert(toIndex >= 0 && toIndex < arr.length); + // Remove 1 item at fromIndex. + var removedItems = goog.array.ARRAY_PROTOTYPE_.splice.call(arr, fromIndex, 1); + // Insert the removed item at toIndex. + goog.array.ARRAY_PROTOTYPE_.splice.call(arr, toIndex, 0, removedItems[0]); + // We don't use goog.array.insertAt and goog.array.removeAt, because they're + // significantly slower than splice. +}; + + +/** + * Creates a new array for which the element at position i is an array of the + * ith element of the provided arrays. The returned array will only be as long + * as the shortest array provided; additional values are ignored. For example, + * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]]. + * + * This is similar to the zip() function in Python. See {@link + * http://docs.python.org/library/functions.html#zip} + * + * @param {...!goog.array.ArrayLike} var_args Arrays to be combined. + * @return {!Array.} A new array of arrays created from provided arrays. + */ +goog.array.zip = function(var_args) { + if (!arguments.length) { + return []; + } + var result = []; + for (var i = 0; true; i++) { + var value = []; + for (var j = 0; j < arguments.length; j++) { + var arr = arguments[j]; + // If i is larger than the array length, this is the shortest array. + if (i >= arr.length) { + return result; + } + value.push(arr[i]); + } + result.push(value); + } +}; + + +/** + * Shuffles the values in the specified array using the Fisher-Yates in-place + * shuffle (also known as the Knuth Shuffle). By default, calls Math.random() + * and so resets the state of that random number generator. Similarly, may reset + * the state of the any other specified random number generator. + * + * Runtime: O(n) + * + * @param {!Array} arr The array to be shuffled. + * @param {function():number=} opt_randFn Optional random function to use for + * shuffling. + * Takes no arguments, and returns a random number on the interval [0, 1). + * Defaults to Math.random() using JavaScript's built-in Math library. + */ +goog.array.shuffle = function(arr, opt_randFn) { + var randFn = opt_randFn || Math.random; + + for (var i = arr.length - 1; i > 0; i--) { + // Choose a random array index in [0, i] (inclusive with i). + var j = Math.floor(randFn() * (i + 1)); + + var tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } +}; diff --git a/node_modules/selenium-webdriver/lib/goog/asserts/asserts.js b/node_modules/selenium-webdriver/lib/goog/asserts/asserts.js new file mode 100644 index 0000000..4afdac3 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/goog/asserts/asserts.js @@ -0,0 +1,316 @@ +// Copyright 2008 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Utilities to check the preconditions, postconditions and + * invariants runtime. + * + * Methods in this package should be given special treatment by the compiler + * for type-inference. For example, goog.asserts.assert(foo) + * will restrict foo to a truthy value. + * + * The compiler has an option to disable asserts. So code like: + * + * var x = goog.asserts.assert(foo()); goog.asserts.assert(bar()); + * + * will be transformed into: + * + * var x = foo(); + * + * The compiler will leave in foo() (because its return value is used), + * but it will remove bar() because it assumes it does not have side-effects. + * + */ + +goog.provide('goog.asserts'); +goog.provide('goog.asserts.AssertionError'); + +goog.require('goog.debug.Error'); +goog.require('goog.dom.NodeType'); +goog.require('goog.string'); + + +/** + * @define {boolean} Whether to strip out asserts or to leave them in. + */ +goog.define('goog.asserts.ENABLE_ASSERTS', goog.DEBUG); + + + +/** + * Error object for failed assertions. + * @param {string} messagePattern The pattern that was used to form message. + * @param {!Array.<*>} messageArgs The items to substitute into the pattern. + * @constructor + * @extends {goog.debug.Error} + * @final + */ +goog.asserts.AssertionError = function(messagePattern, messageArgs) { + messageArgs.unshift(messagePattern); + goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs)); + // Remove the messagePattern afterwards to avoid permenantly modifying the + // passed in array. + messageArgs.shift(); + + /** + * The message pattern used to format the error message. Error handlers can + * use this to uniquely identify the assertion. + * @type {string} + */ + this.messagePattern = messagePattern; +}; +goog.inherits(goog.asserts.AssertionError, goog.debug.Error); + + +/** @override */ +goog.asserts.AssertionError.prototype.name = 'AssertionError'; + + +/** + * Throws an exception with the given message and "Assertion failed" prefixed + * onto it. + * @param {string} defaultMessage The message to use if givenMessage is empty. + * @param {Array.<*>} defaultArgs The substitution arguments for defaultMessage. + * @param {string|undefined} givenMessage Message supplied by the caller. + * @param {Array.<*>} givenArgs The substitution arguments for givenMessage. + * @throws {goog.asserts.AssertionError} When the value is not a number. + * @private + */ +goog.asserts.doAssertFailure_ = + function(defaultMessage, defaultArgs, givenMessage, givenArgs) { + var message = 'Assertion failed'; + if (givenMessage) { + message += ': ' + givenMessage; + var args = givenArgs; + } else if (defaultMessage) { + message += ': ' + defaultMessage; + args = defaultArgs; + } + // The '' + works around an Opera 10 bug in the unit tests. Without it, + // a stack trace is added to var message above. With this, a stack trace is + // not added until this line (it causes the extra garbage to be added after + // the assertion message instead of in the middle of it). + throw new goog.asserts.AssertionError('' + message, args || []); +}; + + +/** + * Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is + * true. + * @template T + * @param {T} condition The condition to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {T} The value of the condition. + * @throws {goog.asserts.AssertionError} When the condition evaluates to false. + */ +goog.asserts.assert = function(condition, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !condition) { + goog.asserts.doAssertFailure_('', null, opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return condition; +}; + + +/** + * Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case + * when we want to add a check in the unreachable area like switch-case + * statement: + * + *
    + *  switch(type) {
    + *    case FOO: doSomething(); break;
    + *    case BAR: doSomethingElse(); break;
    + *    default: goog.assert.fail('Unrecognized type: ' + type);
    + *      // We have only 2 types - "default:" section is unreachable code.
    + *  }
    + * 
    + * + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @throws {goog.asserts.AssertionError} Failure. + */ +goog.asserts.fail = function(opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS) { + throw new goog.asserts.AssertionError( + 'Failure' + (opt_message ? ': ' + opt_message : ''), + Array.prototype.slice.call(arguments, 1)); + } +}; + + +/** + * Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {number} The value, guaranteed to be a number when asserts enabled. + * @throws {goog.asserts.AssertionError} When the value is not a number. + */ +goog.asserts.assertNumber = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) { + goog.asserts.doAssertFailure_('Expected number but got %s: %s.', + [goog.typeOf(value), value], opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return /** @type {number} */ (value); +}; + + +/** + * Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {string} The value, guaranteed to be a string when asserts enabled. + * @throws {goog.asserts.AssertionError} When the value is not a string. + */ +goog.asserts.assertString = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) { + goog.asserts.doAssertFailure_('Expected string but got %s: %s.', + [goog.typeOf(value), value], opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return /** @type {string} */ (value); +}; + + +/** + * Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {!Function} The value, guaranteed to be a function when asserts + * enabled. + * @throws {goog.asserts.AssertionError} When the value is not a function. + */ +goog.asserts.assertFunction = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) { + goog.asserts.doAssertFailure_('Expected function but got %s: %s.', + [goog.typeOf(value), value], opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return /** @type {!Function} */ (value); +}; + + +/** + * Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {!Object} The value, guaranteed to be a non-null object. + * @throws {goog.asserts.AssertionError} When the value is not an object. + */ +goog.asserts.assertObject = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) { + goog.asserts.doAssertFailure_('Expected object but got %s: %s.', + [goog.typeOf(value), value], + opt_message, Array.prototype.slice.call(arguments, 2)); + } + return /** @type {!Object} */ (value); +}; + + +/** + * Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {!Array} The value, guaranteed to be a non-null array. + * @throws {goog.asserts.AssertionError} When the value is not an array. + */ +goog.asserts.assertArray = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) { + goog.asserts.doAssertFailure_('Expected array but got %s: %s.', + [goog.typeOf(value), value], opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return /** @type {!Array} */ (value); +}; + + +/** + * Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {boolean} The value, guaranteed to be a boolean when asserts are + * enabled. + * @throws {goog.asserts.AssertionError} When the value is not a boolean. + */ +goog.asserts.assertBoolean = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) { + goog.asserts.doAssertFailure_('Expected boolean but got %s: %s.', + [goog.typeOf(value), value], opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return /** @type {boolean} */ (value); +}; + + +/** + * Checks if the value is a DOM Element if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {!Element} The value, likely to be a DOM Element when asserts are + * enabled. + * @throws {goog.asserts.AssertionError} When the value is not a boolean. + */ +goog.asserts.assertElement = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && (!goog.isObject(value) || + value.nodeType != goog.dom.NodeType.ELEMENT)) { + goog.asserts.doAssertFailure_('Expected Element but got %s: %s.', + [goog.typeOf(value), value], opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return /** @type {!Element} */ (value); +}; + + +/** + * Checks if the value is an instance of the user-defined type if + * goog.asserts.ENABLE_ASSERTS is true. + * + * The compiler may tighten the type returned by this function. + * + * @param {*} value The value to check. + * @param {function(new: T, ...)} type A user-defined constructor. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @throws {goog.asserts.AssertionError} When the value is not an instance of + * type. + * @return {!T} + * @template T + */ +goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) { + goog.asserts.doAssertFailure_('instanceof check failed.', null, + opt_message, Array.prototype.slice.call(arguments, 3)); + } + return value; +}; + + +/** + * Checks that no enumerable keys are present in Object.prototype. Such keys + * would break most code that use {@code for (var ... in ...)} loops. + */ +goog.asserts.assertObjectPrototypeIsIntact = function() { + for (var key in Object.prototype) { + goog.asserts.fail(key + ' should not be enumerable in Object.prototype.'); + } +}; diff --git a/node_modules/selenium-webdriver/lib/goog/base.js b/node_modules/selenium-webdriver/lib/goog/base.js new file mode 100644 index 0000000..68f871b --- /dev/null +++ b/node_modules/selenium-webdriver/lib/goog/base.js @@ -0,0 +1,1706 @@ +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Bootstrap for the Google JS Library (Closure). + * + * In uncompiled mode base.js will write out Closure's deps file, unless the + * global CLOSURE_NO_DEPS is set to true. This allows projects to + * include their own deps file(s) from different locations. + * + * + * @provideGoog + */ + + +/** + * @define {boolean} Overridden to true by the compiler when --closure_pass + * or --mark_as_compiled is specified. + */ +var COMPILED = false; + + +/** + * Base namespace for the Closure library. Checks to see goog is already + * defined in the current scope before assigning to prevent clobbering if + * base.js is loaded more than once. + * + * @const + */ +var goog = goog || {}; + + +/** + * Reference to the global context. In most cases this will be 'window'. + */ +goog.global = this; + + +/** + * A hook for overriding the define values in uncompiled mode. + * + * In uncompiled mode, {@code CLOSURE_UNCOMPILED_DEFINES} may be defined before + * loading base.js. If a key is defined in {@code CLOSURE_UNCOMPILED_DEFINES}, + * {@code goog.define} will use the value instead of the default value. This + * allows flags to be overwritten without compilation (this is normally + * accomplished with the compiler's "define" flag). + * + * Example: + *
    + *   var CLOSURE_UNCOMPILED_DEFINES = {'goog.DEBUG': false};
    + * 
    + * + * @type {Object.|undefined} + */ +goog.global.CLOSURE_UNCOMPILED_DEFINES; + + +/** + * A hook for overriding the define values in uncompiled or compiled mode, + * like CLOSURE_UNCOMPILED_DEFINES but effective in compiled code. In + * uncompiled code CLOSURE_UNCOMPILED_DEFINES takes precedence. + * + * Also unlike CLOSURE_UNCOMPILED_DEFINES the values must be number, boolean or + * string literals or the compiler will emit an error. + * + * While any @define value may be set, only those set with goog.define will be + * effective for uncompiled code. + * + * Example: + *
    + *   var CLOSURE_DEFINES = {'goog.DEBUG': false};
    + * 
    + * + * @type {Object.|undefined} + */ +goog.global.CLOSURE_DEFINES; + + +/** + * Returns true if the specified value is not undefined. + * WARNING: Do not use this to test if an object has a property. Use the in + * operator instead. + * + * @param {?} val Variable to test. + * @return {boolean} Whether variable is defined. + */ +goog.isDef = function(val) { + // void 0 always evaluates to undefined and hence we do not need to depend on + // the definition of the global variable named 'undefined'. + return val !== void 0; +}; + + +/** + * Builds an object structure for the provided namespace path, ensuring that + * names that already exist are not overwritten. For example: + * "a.b.c" -> a = {};a.b={};a.b.c={}; + * Used by goog.provide and goog.exportSymbol. + * @param {string} name name of the object that this file defines. + * @param {*=} opt_object the object to expose at the end of the path. + * @param {Object=} opt_objectToExportTo The object to add the path to; default + * is |goog.global|. + * @private + */ +goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) { + var parts = name.split('.'); + var cur = opt_objectToExportTo || goog.global; + + // Internet Explorer exhibits strange behavior when throwing errors from + // methods externed in this manner. See the testExportSymbolExceptions in + // base_test.html for an example. + if (!(parts[0] in cur) && cur.execScript) { + cur.execScript('var ' + parts[0]); + } + + // Certain browsers cannot parse code in the form for((a in b); c;); + // This pattern is produced by the JSCompiler when it collapses the + // statement above into the conditional loop below. To prevent this from + // happening, use a for-loop and reserve the init logic as below. + + // Parentheses added to eliminate strict JS warning in Firefox. + for (var part; parts.length && (part = parts.shift());) { + if (!parts.length && goog.isDef(opt_object)) { + // last part and we have an object; use it + cur[part] = opt_object; + } else if (cur[part]) { + cur = cur[part]; + } else { + cur = cur[part] = {}; + } + } +}; + + +/** + * Defines a named value. In uncompiled mode, the value is retreived from + * CLOSURE_DEFINES or CLOSURE_UNCOMPILED_DEFINES if the object is defined and + * has the property specified, and otherwise used the defined defaultValue. + * When compiled, the default can be overridden using compiler command-line + * options. + * + * @param {string} name The distinguished name to provide. + * @param {string|number|boolean} defaultValue + */ +goog.define = function(name, defaultValue) { + var value = defaultValue; + if (!COMPILED) { + if (goog.global.CLOSURE_UNCOMPILED_DEFINES && + Object.prototype.hasOwnProperty.call( + goog.global.CLOSURE_UNCOMPILED_DEFINES, name)) { + value = goog.global.CLOSURE_UNCOMPILED_DEFINES[name]; + } else if (goog.global.CLOSURE_DEFINES && + Object.prototype.hasOwnProperty.call( + goog.global.CLOSURE_DEFINES, name)) { + value = goog.global.CLOSURE_DEFINES[name]; + } + } + goog.exportPath_(name, value); +}; + + +/** + * @define {boolean} DEBUG is provided as a convenience so that debugging code + * that should not be included in a production js_binary can be easily stripped + * by specifying --define goog.DEBUG=false to the JSCompiler. For example, most + * toString() methods should be declared inside an "if (goog.DEBUG)" conditional + * because they are generally used for debugging purposes and it is difficult + * for the JSCompiler to statically determine whether they are used. + */ +goog.DEBUG = true; + + +/** + * @define {string} LOCALE defines the locale being used for compilation. It is + * used to select locale specific data to be compiled in js binary. BUILD rule + * can specify this value by "--define goog.LOCALE=" as JSCompiler + * option. + * + * Take into account that the locale code format is important. You should use + * the canonical Unicode format with hyphen as a delimiter. Language must be + * lowercase, Language Script - Capitalized, Region - UPPERCASE. + * There are few examples: pt-BR, en, en-US, sr-Latin-BO, zh-Hans-CN. + * + * See more info about locale codes here: + * http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers + * + * For language codes you should use values defined by ISO 693-1. See it here + * http://www.w3.org/WAI/ER/IG/ert/iso639.htm. There is only one exception from + * this rule: the Hebrew language. For legacy reasons the old code (iw) should + * be used instead of the new code (he), see http://wiki/Main/IIISynonyms. + */ +goog.define('goog.LOCALE', 'en'); // default to en + + +/** + * @define {boolean} Whether this code is running on trusted sites. + * + * On untrusted sites, several native functions can be defined or overridden by + * external libraries like Prototype, Datejs, and JQuery and setting this flag + * to false forces closure to use its own implementations when possible. + * + * If your JavaScript can be loaded by a third party site and you are wary about + * relying on non-standard implementations, specify + * "--define goog.TRUSTED_SITE=false" to the JSCompiler. + */ +goog.define('goog.TRUSTED_SITE', true); + + +/** + * @define {boolean} Whether a project is expected to be running in strict mode. + * + * This define can be used to trigger alternate implementations compatible with + * running in EcmaScript Strict mode or warn about unavailable functionality. + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode + */ +goog.define('goog.STRICT_MODE_COMPATIBLE', false); + + +/** + * Creates object stubs for a namespace. The presence of one or more + * goog.provide() calls indicate that the file defines the given + * objects/namespaces. Provided objects must not be null or undefined. + * Build tools also scan for provide/require statements + * to discern dependencies, build dependency files (see deps.js), etc. + * @see goog.require + * @param {string} name Namespace provided by this file in the form + * "goog.package.part". + */ +goog.provide = function(name) { + if (!COMPILED) { + // Ensure that the same namespace isn't provided twice. This is intended + // to teach new developers that 'goog.provide' is effectively a variable + // declaration. And when JSCompiler transforms goog.provide into a real + // variable declaration, the compiled JS should work the same as the raw + // JS--even when the raw JS uses goog.provide incorrectly. + if (goog.isProvided_(name)) { + throw Error('Namespace "' + name + '" already declared.'); + } + delete goog.implicitNamespaces_[name]; + + var namespace = name; + while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) { + if (goog.getObjectByName(namespace)) { + break; + } + goog.implicitNamespaces_[namespace] = true; + } + } + + goog.exportPath_(name); +}; + + +/** + * Marks that the current file should only be used for testing, and never for + * live code in production. + * + * In the case of unit tests, the message may optionally be an exact namespace + * for the test (e.g. 'goog.stringTest'). The linter will then ignore the extra + * provide (if not explicitly defined in the code). + * + * @param {string=} opt_message Optional message to add to the error that's + * raised when used in production code. + */ +goog.setTestOnly = function(opt_message) { + if (COMPILED && !goog.DEBUG) { + opt_message = opt_message || ''; + throw Error('Importing test-only code into non-debug environment' + + opt_message ? ': ' + opt_message : '.'); + } +}; + + +/** + * Forward declares a symbol. This is an indication to the compiler that the + * symbol may be used in the source yet is not required and may not be provided + * in compilation. + * + * The most common usage of forward declaration is code that takes a type as a + * function parameter but does not need to require it. By forward declaring + * instead of requiring, no hard dependency is made, and (if not required + * elsewhere) the namespace may never be required and thus, not be pulled + * into the JavaScript binary. If it is required elsewhere, it will be type + * checked as normal. + * + * + * @param {string} name The namespace to forward declare in the form of + * "goog.package.part". + */ +goog.forwardDeclare = function(name) {}; + + +if (!COMPILED) { + + /** + * Check if the given name has been goog.provided. This will return false for + * names that are available only as implicit namespaces. + * @param {string} name name of the object to look for. + * @return {boolean} Whether the name has been provided. + * @private + */ + goog.isProvided_ = function(name) { + return !goog.implicitNamespaces_[name] && + goog.isDefAndNotNull(goog.getObjectByName(name)); + }; + + /** + * Namespaces implicitly defined by goog.provide. For example, + * goog.provide('goog.events.Event') implicitly declares that 'goog' and + * 'goog.events' must be namespaces. + * + * @type {Object} + * @private + */ + goog.implicitNamespaces_ = {}; +} + + +/** + * Returns an object based on its fully qualified external name. The object + * is not found if null or undefined. If you are using a compilation pass that + * renames property names beware that using this function will not find renamed + * properties. + * + * @param {string} name The fully qualified name. + * @param {Object=} opt_obj The object within which to look; default is + * |goog.global|. + * @return {?} The value (object or primitive) or, if not found, null. + */ +goog.getObjectByName = function(name, opt_obj) { + var parts = name.split('.'); + var cur = opt_obj || goog.global; + for (var part; part = parts.shift(); ) { + if (goog.isDefAndNotNull(cur[part])) { + cur = cur[part]; + } else { + return null; + } + } + return cur; +}; + + +/** + * Globalizes a whole namespace, such as goog or goog.lang. + * + * @param {Object} obj The namespace to globalize. + * @param {Object=} opt_global The object to add the properties to. + * @deprecated Properties may be explicitly exported to the global scope, but + * this should no longer be done in bulk. + */ +goog.globalize = function(obj, opt_global) { + var global = opt_global || goog.global; + for (var x in obj) { + global[x] = obj[x]; + } +}; + + +/** + * Adds a dependency from a file to the files it requires. + * @param {string} relPath The path to the js file. + * @param {Array} provides An array of strings with the names of the objects + * this file provides. + * @param {Array} requires An array of strings with the names of the objects + * this file requires. + */ +goog.addDependency = function(relPath, provides, requires) { + if (goog.DEPENDENCIES_ENABLED) { + var provide, require; + var path = relPath.replace(/\\/g, '/'); + var deps = goog.dependencies_; + for (var i = 0; provide = provides[i]; i++) { + deps.nameToPath[provide] = path; + if (!(path in deps.pathToNames)) { + deps.pathToNames[path] = {}; + } + deps.pathToNames[path][provide] = true; + } + for (var j = 0; require = requires[j]; j++) { + if (!(path in deps.requires)) { + deps.requires[path] = {}; + } + deps.requires[path][require] = true; + } + } +}; + + + + +// NOTE(nnaze): The debug DOM loader was included in base.js as an original way +// to do "debug-mode" development. The dependency system can sometimes be +// confusing, as can the debug DOM loader's asynchronous nature. +// +// With the DOM loader, a call to goog.require() is not blocking -- the script +// will not load until some point after the current script. If a namespace is +// needed at runtime, it needs to be defined in a previous script, or loaded via +// require() with its registered dependencies. +// User-defined namespaces may need their own deps file. See http://go/js_deps, +// http://go/genjsdeps, or, externally, DepsWriter. +// http://code.google.com/closure/library/docs/depswriter.html +// +// Because of legacy clients, the DOM loader can't be easily removed from +// base.js. Work is being done to make it disableable or replaceable for +// different environments (DOM-less JavaScript interpreters like Rhino or V8, +// for example). See bootstrap/ for more information. + + +/** + * @define {boolean} Whether to enable the debug loader. + * + * If enabled, a call to goog.require() will attempt to load the namespace by + * appending a script tag to the DOM (if the namespace has been registered). + * + * If disabled, goog.require() will simply assert that the namespace has been + * provided (and depend on the fact that some outside tool correctly ordered + * the script). + */ +goog.define('goog.ENABLE_DEBUG_LOADER', true); + + +/** + * Implements a system for the dynamic resolution of dependencies that works in + * parallel with the BUILD system. Note that all calls to goog.require will be + * stripped by the JSCompiler when the --closure_pass option is used. + * @see goog.provide + * @param {string} name Namespace to include (as was given in goog.provide()) in + * the form "goog.package.part". + */ +goog.require = function(name) { + + // If the object already exists we do not need do do anything. + // TODO(arv): If we start to support require based on file name this has to + // change. + // TODO(arv): If we allow goog.foo.* this has to change. + // TODO(arv): If we implement dynamic load after page load we should probably + // not remove this code for the compiled output. + if (!COMPILED) { + if (goog.isProvided_(name)) { + return; + } + + if (goog.ENABLE_DEBUG_LOADER) { + var path = goog.getPathFromDeps_(name); + if (path) { + goog.included_[path] = true; + goog.writeScripts_(); + return; + } + } + + var errorMessage = 'goog.require could not find: ' + name; + if (goog.global.console) { + goog.global.console['error'](errorMessage); + } + + + throw Error(errorMessage); + + } +}; + + +/** + * Path for included scripts. + * @type {string} + */ +goog.basePath = ''; + + +/** + * A hook for overriding the base path. + * @type {string|undefined} + */ +goog.global.CLOSURE_BASE_PATH; + + +/** + * Whether to write out Closure's deps file. By default, the deps are written. + * @type {boolean|undefined} + */ +goog.global.CLOSURE_NO_DEPS; + + +/** + * A function to import a single script. This is meant to be overridden when + * Closure is being run in non-HTML contexts, such as web workers. It's defined + * in the global scope so that it can be set before base.js is loaded, which + * allows deps.js to be imported properly. + * + * The function is passed the script source, which is a relative URI. It should + * return true if the script was imported, false otherwise. + * @type {(function(string): boolean)|undefined} + */ +goog.global.CLOSURE_IMPORT_SCRIPT; + + +/** + * Null function used for default values of callbacks, etc. + * @return {void} Nothing. + */ +goog.nullFunction = function() {}; + + +/** + * The identity function. Returns its first argument. + * + * @param {*=} opt_returnValue The single value that will be returned. + * @param {...*} var_args Optional trailing arguments. These are ignored. + * @return {?} The first argument. We can't know the type -- just pass it along + * without type. + * @deprecated Use goog.functions.identity instead. + */ +goog.identityFunction = function(opt_returnValue, var_args) { + return opt_returnValue; +}; + + +/** + * When defining a class Foo with an abstract method bar(), you can do: + * Foo.prototype.bar = goog.abstractMethod + * + * Now if a subclass of Foo fails to override bar(), an error will be thrown + * when bar() is invoked. + * + * Note: This does not take the name of the function to override as an argument + * because that would make it more difficult to obfuscate our JavaScript code. + * + * @type {!Function} + * @throws {Error} when invoked to indicate the method should be overridden. + */ +goog.abstractMethod = function() { + throw Error('unimplemented abstract method'); +}; + + +/** + * Adds a {@code getInstance} static method that always returns the same + * instance object. + * @param {!Function} ctor The constructor for the class to add the static + * method to. + */ +goog.addSingletonGetter = function(ctor) { + ctor.getInstance = function() { + if (ctor.instance_) { + return ctor.instance_; + } + if (goog.DEBUG) { + // NOTE: JSCompiler can't optimize away Array#push. + goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor; + } + return ctor.instance_ = new ctor; + }; +}; + + +/** + * All singleton classes that have been instantiated, for testing. Don't read + * it directly, use the {@code goog.testing.singleton} module. The compiler + * removes this variable if unused. + * @type {!Array.} + * @private + */ +goog.instantiatedSingletons_ = []; + + +/** + * True if goog.dependencies_ is available. + * @const {boolean} + */ +goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER; + + +if (goog.DEPENDENCIES_ENABLED) { + /** + * Object used to keep track of urls that have already been added. This record + * allows the prevention of circular dependencies. + * @type {Object} + * @private + */ + goog.included_ = {}; + + + /** + * This object is used to keep track of dependencies and other data that is + * used for loading scripts. + * @private + * @type {Object} + */ + goog.dependencies_ = { + pathToNames: {}, // 1 to many + nameToPath: {}, // 1 to 1 + requires: {}, // 1 to many + // Used when resolving dependencies to prevent us from visiting file twice. + visited: {}, + written: {} // Used to keep track of script files we have written. + }; + + + /** + * Tries to detect whether is in the context of an HTML document. + * @return {boolean} True if it looks like HTML document. + * @private + */ + goog.inHtmlDocument_ = function() { + var doc = goog.global.document; + return typeof doc != 'undefined' && + 'write' in doc; // XULDocument misses write. + }; + + + /** + * Tries to detect the base path of base.js script that bootstraps Closure. + * @private + */ + goog.findBasePath_ = function() { + if (goog.global.CLOSURE_BASE_PATH) { + goog.basePath = goog.global.CLOSURE_BASE_PATH; + return; + } else if (!goog.inHtmlDocument_()) { + return; + } + var doc = goog.global.document; + var scripts = doc.getElementsByTagName('script'); + // Search backwards since the current script is in almost all cases the one + // that has base.js. + for (var i = scripts.length - 1; i >= 0; --i) { + var src = scripts[i].src; + var qmark = src.lastIndexOf('?'); + var l = qmark == -1 ? src.length : qmark; + if (src.substr(l - 7, 7) == 'base.js') { + goog.basePath = src.substr(0, l - 7); + return; + } + } + }; + + + /** + * Imports a script if, and only if, that script hasn't already been imported. + * (Must be called at execution time) + * @param {string} src Script source. + * @private + */ + goog.importScript_ = function(src) { + var importScript = goog.global.CLOSURE_IMPORT_SCRIPT || + goog.writeScriptTag_; + if (!goog.dependencies_.written[src] && importScript(src)) { + goog.dependencies_.written[src] = true; + } + }; + + + /** + * The default implementation of the import function. Writes a script tag to + * import the script. + * + * @param {string} src The script source. + * @return {boolean} True if the script was imported, false otherwise. + * @private + */ + goog.writeScriptTag_ = function(src) { + if (goog.inHtmlDocument_()) { + var doc = goog.global.document; + + // If the user tries to require a new symbol after document load, + // something has gone terribly wrong. Doing a document.write would + // wipe out the page. + if (doc.readyState == 'complete') { + // Certain test frameworks load base.js multiple times, which tries + // to write deps.js each time. If that happens, just fail silently. + // These frameworks wipe the page between each load of base.js, so this + // is OK. + var isDeps = /\bdeps.js$/.test(src); + if (isDeps) { + return false; + } else { + throw Error('Cannot write "' + src + '" after document load'); + } + } + + doc.write( + '")' + Response.Output.Write(""); + } +} diff --git a/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx b/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx new file mode 100644 index 0000000..52d2e67 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx @@ -0,0 +1,11 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Redirect.aspx.cs" Inherits="Redirect" %> + + + + + + Untitled Page + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx.cs b/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx.cs new file mode 100644 index 0000000..9e0650b --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx.cs @@ -0,0 +1,9 @@ +using System; + +public partial class Redirect : Page +{ + protected new void Page_Load(object sender, EventArgs e) + { + Response.Redirect("resultPage.html"); + } +} diff --git a/node_modules/selenium-webdriver/lib/test/data/Settings.StyleCop b/node_modules/selenium-webdriver/lib/test/data/Settings.StyleCop new file mode 100644 index 0000000..fc955f8 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/Settings.StyleCop @@ -0,0 +1,759 @@ + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/Web.Config b/node_modules/selenium-webdriver/lib/test/data/Web.Config new file mode 100644 index 0000000..68b648f --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/Web.Config @@ -0,0 +1,59 @@ + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/actualXhtmlPage.xhtml b/node_modules/selenium-webdriver/lib/test/data/actualXhtmlPage.xhtml new file mode 100644 index 0000000..a0f5470 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/actualXhtmlPage.xhtml @@ -0,0 +1,14 @@ + + + + + + Title + + + +

    + Foo +

    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/ajaxy_page.html b/node_modules/selenium-webdriver/lib/test/data/ajaxy_page.html new file mode 100644 index 0000000..4b34031 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/ajaxy_page.html @@ -0,0 +1,81 @@ + + + +
    + + +
    + + Red + Green +
    + +
    + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/alerts.html b/node_modules/selenium-webdriver/lib/test/data/alerts.html new file mode 100644 index 0000000..1add0db --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/alerts.html @@ -0,0 +1,85 @@ + + + + + Testing Alerts + + + + + +

    Testing Alerts and Stuff

    + +

    This tests alerts: click me

    + +

    This tests alerts: click me

    + +

    Let's make the prompt happen

    + +

    Let's make the prompt with default happen

    + +

    Let's make TWO prompts happen

    + +

    A SLOW alert

    + +

    This is a test of a confirm: + test confirm

    + +

    This is a test of showModalDialog: test dialog

    + +

    This is a test of an alert in an iframe: + +

    + +

    This is a test of an alert in a nested iframe: + +

    + +

    This is a test of an alert open from onload event handler: open new page

    + +

    This is a test of an alert open from onload event handler: open new window

    + +

    This is a test of an alert open from onunload event handler: open new page

    + +

    This is a test of an alert open from onclose event handler: open new window

    + +

    This is a test of an alert open from onclose event handler: open new window

    + +
    +
    +
    + +

    +

    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/banner.gif b/node_modules/selenium-webdriver/lib/test/data/banner.gif new file mode 100644 index 0000000000000000000000000000000000000000..3f3435401f878af30930bfb19ee1e340d823e706 GIT binary patch literal 2109 zcmeIx`BxJM0>E+bD*8|&JPjI1kjMrM8g;584s?(K1|8O+jxuP} z0iy5TvQK34$RI0^h!UJ2^Qi1chB)T>?Px z@#9B6!0+zvo}Qkrudkn(nK7HqJb)*Y%SZ{S)oImQwcel~9v;R>j014wYB@zy2#&Bo z7JvgXg-nPDAq*0L0)#*$5(yz8>&edT3|}A|OnR8JY}yh~M7cPD)8O z#O8n;0V0qqZG6_!M9EigM zc`{limWss^F&kuy|0EMjje-un92%5}-z_sW;S1Wm1_^CZQ!tr4m2@f+8Ri zf>21IP=FYy)F>&65}_iRrj=?XilchHUIdG@S}lShAP#CY8o69fQY0m#*f5)i@L&Qa zNJ6TRN@*!dqLh@v37l5YQn?gGQ5c1B92Y?%gTcTD`51+vViZPTT1mIIwkp($rluwl zCW1*A#n9RR`(J^zR)6~M3syF>R=XFvh21S~$h2`_9B8>)@{jX&t9S)rRf@(e=MC^c zOI2y}WseZbjjJs)=6FY`4;Z!OPp$_XX)WMZD@`{xr;ZO8t5v(NTaj}{?#5UeNa%An`r>a+3HRbxBBTjB?HC;WK8teC=K>GA>J=-`281s7BK z{&o5jPq%;n{Qie2$C%PX)(>Zo-a54Yb5GbgbW;|P7*jdwv;>(Bf=`mt-|n5~zpwkH z=S+a=OzKWkj7QRpwVgZha!hBJ+z~8v%}_-L7K{2%p7-NOSDE%@!+Y7Z_-M*nG$``=>8lsa8FB7A1}_BJyA&p+{^nGaeH>5?pXqn0 zS(!Na^ix?T2T={>el6bFU-0DS8n2QXpEZ3YXI*{ligI*8%E(iYF1pldiR);Fquymq zl?O1(E@z_CKZH0d8D6PJW@epeX^3affI>RL7~k&DJ(iGtu$y*GIxPwkR%wUkS6&=k zoW5sYoj>)aB7EIf9_(gV{RWl{1^S+?W$qE~jnv52=Ji6lHyLq(wUun(1O3Z=xB7+3 zINup{(uw^zb1c2jb;2*U(VQOruw>n)YleT1ivoU{TUxi`(YyrTlqw-G4Z9#0_Z-{qEEWeesuql+K8L zoM8rsZPUzw{s)f_U=y>2X@jT3w}QEYnnceVxAt8+p65N+{o~8vf89KI^VGXb_xf^2 z;Kc1Fd&lyF=O%391^Lf^w2biNrkdnuXr=C@XpT>D|GlUCHFs}LOqb|qMl=Jx`c;le zii=BYYSrY1-r!%`dUg!N5?#0TuR?AgV=C|Le6~3udpcY{#f93P`|Kq*q_qbtKgYKCinEi~bmFc>bM1Z%cpPA} zI)3||gqG#!y_oaHRDKZS@~}I)?P1<6wk!Ql=fAwJ9Ww3S{>3=_v3J2^79${bO+!!5 zA7L#H!(XpXV3c`I%@515=}OMZ{?ZEJ`tHGW%t|4{nLz3fa%HWk8D>jEe~k}T`hSnyOis%8`~hJ zCBHLUxlzS6!HX<(Z<{jcp3#KhmK!f@Rhyf+?I>+27~Q2}_88kSy`}Jdwrb03ZU=6* x$Un8ISW`yN4r1C;WVN_r+gH3!()IUZn}`bb^43l<^Y;?FOBFlnT=4z;!@L@{)-6_DV6`-qdK*vM-ofwS(v4~M&MgV@`0mO6S=@TyBe}(%Oe3L)pO8-p5 z1g;#3}=P55MDpEC?sVrv%tOa}v+5x%UaHFPNb1 zQOrMc_(tZhOMm&{%XojNHAZ#lH2?5_p*~(UmLKT-ETOL{TJxnJK!dW%geC6FSYMC( zRm-n?NPy#hlJW%Czk#wRfQfOF3C6Iuv`HBxs3=DDf;~AF$V^zD3H1p0tx4OE&RNaQ zBse)ZI1_xKYe^vZtw~8+o0*VK2uzK$TR@0OP9~_@WDwF5G7{3W65{R9ZzpUXg}^kw zn3RO{7y|0r=;><`ImrpC`iaYbfBRL#{|=5nz!p>2a}ogv4OLl;CeXy_11$VX1C~^b zfeMCp0x~gE0S?|VsIS170Cg1%Kp|$k!ge8IgflGZu2!RpHSOhm02SOm~Dp0?#@=B^Z`BeR$;qJ@_X#7cQL)-*c)=dbL>qL(J=o9vP)aaB zYXS>wK*^VSdWqWS`iK(s&+Vg2@RQ?0-jqz4grUDF(fZtmE&7Cyql1G8GuZ}mRD}J+ zAuLaX`vha|i}gN#n{G z)fO}U0MpIR%uI8)w@=Nmi-}(on_w5WCdGbzOq#u;or68_T<^X$|^=?Mg~9of#o(p!r_Ab6(7C%QA2&?Y~JPhOUj zBd%Mw&TgHv-J0~(_Kt3DZuSmN_D)W=u!U{LhSbcM^|q-QRui3k>Sqa@q|-TRnVdDL z1hn6n*fnc2y(}%!fj<8x@QhgtG5sgf5}*O9XoD^6KX(tm_JkGgAqlA&-Y#~owocA= zPK1;cPy5fcUj|XNq;b+y*2SbJcz*&2-z21GpqN3%IZS-_>6MBT69`Uxn;etDMx7KK zEe55=+ri#(@{|8~H94-QJxcLc9GGCQsuuFsTg%h_v#h+e!1yibgQx2oOf%4(KFx5N z(ah<_1Q#oUnHj;?-qFS-bP0nVvLrZgS@cHsvTrk^0)xNblbpFZZ|AO^tkvZQ%ko7V zx9{AFc7mB{WJE9}_*hx_Y>fzx*!sWzjW+>9P0W2P4~MY?SVIiX5Ho%WK()oF!!;+m z?40~zusAh!4ZP+QEp6DK0Xjnr4u@64sjI6&cZSJu zz4+TD#pUKJSFb5MI{)bUv-@VxgWkS}kNO854?g+p^_!u$!|(nc8Aa)W9$|v4&y@We zU51b@teP554Uf`=!LEY^XQ-w=+fiexF9RRLoo4BjtBEY$bMW|uDOS$RSJPwD+qGuQ zAwQV=7fPCnvi~>2w)}rl_L;CRboBro90m#xX9#>ilfv??m65`|sCT;ZPu8q$BresK zzEz>)RC9m|Xp%L)3TvnM(WRYt&W0ZepKo?0rP=ly{B+ZK8aYXkgtKjXAD%dq{;at6 ztyr!K>(75047sO$50VE>@}D&g-;aow1Ogu1_C*QGKFf300Fc89|44pWdu`kQ%ep6 z!p|Io(JP59(rD*Ll5~O~c_r_UVhrRpY4z3yP1%wFJ|M z(z0!LF7ip79dKL`mOoi4Npd-Orpybe#qlYw4OS)`2^mz#%s3gr3g9|avrcBcUkDZx zWgh+gUcSa$BM9j*!fw$>peOP>d2Gd2aXAvpo63)3Kuk&9 zEp|O10cn&eaI>g(M3hJssYs&)RfgUIlmUE4s1tTXNL@KXpG}l0j6Mdcm58nuF)USt3&<6#7!-rvf~B|o8?1Zm)M5p~O+BG<@H>OQ zsoj@BG3+g1y&^V=G-BbMP`J;;48(D==g>WG7pMRRK@~RH{G}^8x7}M8}?FAc+k*j_R9A%Mf`il$A;{ zA&~VZP__l_Lf}XvWl(4DQ7V}o2J!8sP=n%?50wmxcBArzx4eglxz$1}?%+~HQ*c7< zzJ^8Qt%=3WFUFHTqXJK@D6Jy$DKdD*;HQQf!#gut8Lxan z1`Haf+?R7{x620YQum+ohY_YAO0&*&~sCPDdnVfA#* zk7rnoKYk;wq|RM2n~FN_f8~?PouQ;eItG8zKIq*hwW;x6kc;~7o-7#7hU#A#@uyBy zW=%u=#DDry)a)B&=={0X2)Y-lPl`2(cbnN;sqRx0MDe8(kw;POX$D$lR08s7x~-u2 zfx>pK9Y;rhx^_cAD2>uWwx)4N51Fxbd!P)vB}fx=TOLTGNCWz|$)^I>51@H7Jar`8rY& z7EpXL#JRSp;-VCzdV;M4X7zG8Zyi!0m5J0%vqT?B>bAIPxjh1hAqhmp@NE7f`&qZid8WJzav;#n0b5IODDT*7QjJgD}}8CD}VMbeiT!qb_+=-@wPI#p6#jtl;4osorR=|Lrac3 zvEjs3Gut^>=tv`i7Go3-o%Vlzpksv2R3qq`7|@a@)PG{W{7-e~QX%0e>r&u+0nKDW zS!|(0Sv%pZCT$;`N@F2@y{a})<>0(ZCmLab`3!{zM462=UXdUV0yI)2DL%;Q3~Cb_ z(OMrw7yRU*BU5-pn|APeck!CkU9~n5n`GQ>RHWDfMw-ct@)Qpwc2{n7AzLxmE@=m% zmE#Yw-_GSUbvV=5$D&Hf`StrG+X$VuP#7G9i`jmWEk(%Z1Q!m4MJQ(seT$V}dybwcL z4jbz}FN7qCep{P%+|1S^VOA)17L9Z()Vf2pY~-(GV;1tilXO**vigg!3~y|gcUFBz z41uDYK~#kQOx}cGIk2l?48upBcW%wp* z<^3KP7F8wJF|K%9PyZmUKuVP|9F~WrNa|`%lw<^n-bn$T{DH|0hN{D$v2m{a5N4jQ z+hIZod}<}Xn6Hjx_>-d+pzBC=1Ww6cITmHxSF@4IUZ}QqM2wtOr(z^rUM<{HSPx`9q$thf!Te%dyB<3a!`N~SX%Df7 z*cefyQ6hCkbWGMw-=(qj6}uGvNdIv~DPW)y1-l zmuBhO{Wi#AP@7{d7AQw(HR4_QJAU|8ZLJFuwP0}^IbXB>vG_r(?sjF7?V)Tq%JyqX zt4L=LMe&`f-4Xc`%Zl|b9_g-i0nJ^z^7Ax!dK+r(vW3fxq2LxF_ZtXwxEs3o8(vwk zk@Xi1YL7Epb_>pY;s-IO*$}XuscraNlH$#`n_*yU2hBn!#`8X%bZVqNVi?iXNA6z~ zO00x>`axiE1{IS;WmK^-`>sedejG`nG%2iT%TM|rnO}IxBa9lL4kwlNKpNZV3F(xy zg&{BD8k=yOUXj^2T)Hau*?Mqln-T9Kgh8(fndI4#9{~ z-ETZ92#Sj-bPlqL_Ki`58jtw;;s)Yr4zTtkM*b03-c28xY0P7#gaTBTE{`QDxX(8#5 zbC53??6bOCCHUQ7LvQ7(HoDqAiHl*zE&lYg935fdAI5Q2MB`>Mcy+Pdt?p#yD^61{ z&w`fo#Hslh`SvkSEg$U`YCWqLcZM*QPqjDe(;p`fd2Lw=RUUu1PV!VCZ>}~ zcdNnX3d;-w%;h9{qZg;CZotL1Aos{E?q$-TfmwQJNZP$D0dQwFM*P$sU8zS}XxQ^( z?$dxvvAgp5-Qud=;@O_VhZ=Xr46@9ri>v2)R_gR06y#m^eOnj*U2S*A^*0JDv)_=m z9Y539o~%FxeLG`ueas$Z@isHaN|tuploxEwP~yHbtC3U@e#Q_|?f8_&(Pm+8iiD}_ zZI0D1G{tJVNpT#_mHDywJGGlx66@0olLbi{qo^kaTs9uEN8`Kz3Ul z^24u%_N^CDhYA8T+*v;}=Cj^Vw7x}JM#$3DXBXkRcxI>h9CFILT0q2{QRZK*WfT*E zmb&}CGmO(!a$wqDTG)Hwv=<3=COwrB(~b?+<@hchQq^~aeEhA9uuj^`o4J5Pv8g|p z%^VV`k1~~7krcHylCCY>AvC_LSzRRnPe^cz!JzYsNL>t<@sVGi@eE-K0-m)CQ-~tG zUQ$4tX}?70tTU5@Ej2N^fABI#^v18UVPVA#mh1hFQ-`koT{|KwNR%DCUExilX&zGi z$|}2xMA$_bJq=mitd!iTa^~;e@AdaV!l}6RR!6K~%=^XW?7R}!77wk5vQstk3bUkz z(GqL1+nkck`az*m@=qaALc`w{>Mp+>5m)0e+OgC1J~Q29XWB`9Gg9zWw?m8lUENxO z5;5t`)j@U@D~i&l?fp={h4St9`ZB-%nI46qv>Wwy>`4V+_+}i z;Ih7oU+-5@J-9~ALUS4a1 z-@c$ZTVpNNztQo%;F(o#eAUgy?QLDeRCi^V!X-WJuKYLRo##*K8@8u8Lt%rx1L!Kpu381!(C`nSi|pdKl5>Ds~4_{+2kH)ing*q z37t&+TUjd^-G|n-EG+kAf;+UnK&peD98NJr^0N+N3-BPHLas%Es5c5?QUU_T&T^bQ zpa+C#F}L6up>P(&-Q2cbs^=e+2=||Xzm~hqfWvs^ZaOEpoQON>5;n}8T5adskLys@ zj{|lXO|RqcrGY2@*iDP=Ze`q+KHhRX^x;F(lln@b-3$B&xzBE2TG#Ej&x0@P%}4J3 z?t4ADs#j>2_&7e9u5qDMjcBTzw|CBQMWSM(r~kWjhj&jy_9m9SyAl}J*{0EI-aXox z`gqn$kmDR7Ey)(9fK<};gmCZ9AMaaKd%Nc)n z5mKbw5HjZ2p9ZD*dje}ditS(8#%Gf08jbs=pZM|offXz0yx=%1mp!r9eo2bpX?j+b z)!JSP;2l2vra(&?eEYypM>>3554F}^Rz8pF>-u?a%4?6K#%>D#ysjEW)UBDXbTR_g z8aZEe*;Q#+*tzv#f7$ko=qCWxcQ8ad)~9BPdJ-y zoU7ptEV&!IdHtr$4ZA)*U}(!eO2Uh+S=f=UFni0}V|B|Y0yy3hvigzD&n@11%l-UT*Z7U+>5cS#i6<)Jm z%iiE6o0e8Fvl)+$$}rE>-}uAF4U+cr^E~Ba&&?ypK^AW~x4($?p$@)cj&MHqz!#6< zNcUW`UCh}-J~EH%t6uQG+x4-XveCCHZEWx(@y+&k;r*odGvAAMtEy?vH!SY>R7h0U z`h`WlwD!kDy)6F${TE~6BG>FqVrh?;y3sI_cVN%Hq6CX~ZPGW@K5I9>JhXq!F^PF+ z#LD(P8=Bus#zrMKhAj>R7sb$s$1+aXlSd(=UC#e{{s0_?pF^vD9|!q%BVIG#!aCBf1H~`P+c#VJ@3VjJv!@>J-1M^i&aD~VY(*P9 ze{&q13k_BEX4>-P{JR#5b7QYyUD6K>KCX(o`QA8Kzxf`yvHJZu`1^S{j6AzNTz+XB z!1`vY-Ocj@2S4OTz&)Yc%~kQ|-?WV_EjTf+B*AmpfpeWH<^sI4dE2K^mtJOfPStZYHXk~QM9;<_U6s`Rn)QCy2(yA- z`E1p-Li+GFXG(72U5Xj|^$z1c*H)K?hes1E%4~{j50O3)AE_^^INp3_(c-2=sex|( z$yXW~k@r@Izp#H4_TIg37XFbxaU(76M+79!G4Ev>L+tY zI<|&gIlXRmBlh(4hWu>W`Le*{IqLI^$|~1%%Sy*qoXfcEpCsV0PA*&$?($~}uE7Y2 z`r+uQ>wP^1%=Yi_2CCrJTx-4TUKr%EzL)Kg!|9~s7FM&udeCT&!VV3{D2&jkM1@RY z3xm1vL183yP~Aj;dy9N(7=f<{v+_p2tHY!0-VXL z;r5d}V+HaN?o>1wOt^Uk{!`OnQjgk~htS5tCzNW!Qw1CQYWcHS)z{Pcn zgj2u8B8V}~oWFVAa*O$d9`=R9mUsQe!Gc?_Yj?SwAJ`}Refza*`#D*ETu5*n)5!^S zjR?NS{=n|{8(wqVKV{bUOE@p@2w2;yTkW8LA0JKp{f<24h;Q`ydr&M9&9_T~59r@? zo}WMr>Y9^pKUu5TM@~N9EuNuc*TlHd0J`RqZb0d7S8#z_+u`&qT^o|=g19y6?ETdjrnCKl) zM%}V5>qGt3)l)0)S07m+9c|Atty^7c@ecnefUqOem&pj~J7Hpor&^TRo8{XgI?hzY z1d!ZX(0FDB)r>tEND(xO^x}}lTDbMdG+k)S|4#l&T16UT=`|wiJGiuYYv$i(j(Fxg zphRp(Vt-sSi(e&1S>aa$RGvre@pGY95(k5q_fdKnfy2%n*>9!b1cmb{6) zPI92=rWJ9;@0;^1Sd zR$Y2McWAoh;9o^&eowmBC@y!lm=kn9X8Ruyu^IGr%*`gp{2P#;ny;H*!rs7qnDa5z zHS(g*ql)^C88q%oYWK+USjRP*K2N$Tt$f>&O~@$GtT>nQSd^n~RtE;$ddp>mX;yy< z-P<+^;>aLVG;mBN5yBNvC5}(Ta1Q3W8h@zoq+>U}lT;09g~8R6e=7Sa4F=tf#kp5R z*wXXJc^Lv1VlX;-cGTQM`Bq{I7gt+sNE> zemAi9u83{59xn8b^+Mbir-34VyYl77ZLnwp41s_~k7!Q<-V11>E1mKxGh! z;ELT;<^gn)3HTKn*D`>O)yBWFqS^0 z=-vp&pO<-5vjPHE)|3TU@qrs6Kkyd}_|FD!B{EZsY#1Ij^2xWE^9}(ug}2dIOWMZv zz&2Bi5G*_@1Kh;}rhTtqxaYz%4qH+v2e+$w3o6q{>m{N-nDC)4>K_!+=3oP_3@HF< zPNteNuUY2ut!p2)lEwzorvXUO#d6b)ZCK?D@Fp0BC|l+lw;nMY1$qN$~1BEH0XeIkO1&`-D5u3!kX&^Cxb4pHJQ*dJ)&h^D46a;~3F zp&k)f^ElGy#t%QLlV{k75X@X8k1Pj_7Aprvi%a72$C{&j5c;(LnQ`k%D%>E$R5}pn z1uA)1jN6d7^k|r1ntYu|z152-RjZbn4#440y(MoQWfZi-KyB)rK92d&DR049lJhe* z2K$a22jgq+VVpCsZBH;y9s2D%hcDpnmJ1^n6EQ|p^!P|3^`Ybd>2tMGUt9t!>fy!epSR!%5p(FE|K`i( zxFcx(%xpwzn^%x{AY}c!El&Ptf$Kv55N78lCf2oII;iAnIR;FTF4%l}v<+8RliD;= zNNUQv0&Q3?l#o0$=-;Wsd1L2Pb%nkFIp|c-hardhk+__31mTFRVPeBkTmf})Noxet5{s3AA+VHp885-s*h-w zcE<8%{t_AHf7T8jp%5-+$8wt=1qWbD5&6CvOaP73DFD2V~B30d37XUHT#C@ z1jli3U1jB)+^oz65+44INL^M_8u-S%muKpfahb#snGZlElQUxrGAP>3Nntr8_MCMh zwfR*KnaOHveGa&9;eb42!fO6nXWJ@G+0`1{&%QRtq*sSzBAhT)F=RCuX496KTOGm# zIArUdHvJn10w`Wo2ZL#YVN#z+Y+qNg9we^=h)Zp|^)GeIYH0;bY?v3j<|pozS}hP6 zMwHGo`r#ta@MPs)H*EgwQ%r7HlY)?N0|R&S3M+#=YgLE9a^ZtY!zBgF0vV-)VG0B& z60OQE)Mh-H$i<;~-Pu;IP>Y(ad1irscJTtALngoe(@kN2l89soLE>-K=eUDmO$d~` zy6s%jC>_%Rr#yJIaf4}Zpnt^J%=uH+V0Nt=Xy!AqGZ-nuf$YJ?Mh`5n!&$ z^-6Dhao8|_=okW&dK$Vg`-Vl&L^Q)(H9S$GJJ|Uqtog`nV_EYNFk3n&w;5Um9ScaD z!_~bCQgRmbVxc+#H+P(V9(X zi(tHT+H=Zah&pf^BXIvtFbxt*Nf3P zsEQjHMB*hDUF5qn;X*}_zb$*{84(5!TN`X)fVxsS!LY!>3?WQ29y;y&u(I+shpn)( zd$1*7)Rc}b80gsx4>5f@I54SHBsLHgySHtCGbzf`R#$Q9x@cYhH#0_VvAuw2n^RC^ zw3dXQ#iitnOY6{+Fi>YP^za}D4=yBUYkagaH&?|d5|p{>q)s7wpo=$y4?mp9XHxO5 zeMf-JpTbDr>fYuDlS%y^zbgv&5}rY(tS0qJ@4lVR@9Hs*QHAHrv`*8UM>;g_ySb5T zYqHyLy8!gmBNub ziqs%uCsYC+7`WF{Bm+odDPh3u*Y-*}R!KK97r;fwn}RWD;372~o-9Y#$sjTW)5cV; zyAcXZ+o`z15fNOviXaNJ%>~s9v-w~xazGuxG*ST7T0f4W#iiPK3ve(~gj96`Iirwt zkTM9TBKJ0ZXzeI9HQ3dVE>Ar+##$1H=494`n)s?p z){6K$Wids50aNOL*7q7sm!0n(plAz;a0MMn!k@Kum{$5c2x>dD%%2avCF9TmevXYKT||DpmM`4rRz9C}g&YW@{`RMADA1(odJr761t z#a3LY!po z#fvTGWh<3a;VEX-K@Nlwcq*fS527{-q12#*OnpGn6PH>--#{e)ZV0_EcT1orvobc< zZ?&mT8x~V2s1Z&XLM{fioaVS0_44NQm#V$Wrbmo!TC4Vp`O36KaIIEBWHn(6{&4Ax zOB}gCIh%32^QkAz;leg=IT$XkACTES|HCNZhrGNNQj`hE!qg@T;W-#RSxq|(6Z{-3 zj5eyJWBUvEVeBRw>k5sRaY1@HY;m!MMn)m$M8F=q?~Ydqo)xTaaJ=iZ@HpP94s1&h zOm)3*nKUv~XSs#A-*JocOI9zmA?OcnSjq#`xen7Rm8hAaXL^cJmxXQbfx&4;hmcC8 zWYrnF^-8M3?X0az-_{*@w3mv16!Y?eNP8(O-26;O-Q)o`c%%`oob7{9k+%l`yw_vQ zLXz7&=b>7-y0)F|YAoKfZRtlMhQ@7$NeCg-WfD=Oad?|;VY88Jeq{!K<%pzSgnQKL zD|EmIQ2?CqU|vrESSuoi(n*kV#Pvzj7&7Wi1x7W8iZ>)f?}|ayM;bHOwYQWEbni4F z@b(`v-wTU0d!?)s7wqhSO(u zOXoKP-kvwQQ(&N%blank diff --git a/node_modules/selenium-webdriver/lib/test/data/bodyTypingTest.html b/node_modules/selenium-webdriver/lib/test/data/bodyTypingTest.html new file mode 100644 index 0000000..f2b1939 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/bodyTypingTest.html @@ -0,0 +1,41 @@ + + + + Testing Typing into body + + + + +

    Type Stuff

    + +
    +   +
    + +
    +   +
    + + + + +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/booleanAttributes.html b/node_modules/selenium-webdriver/lib/test/data/booleanAttributes.html new file mode 100644 index 0000000..16fbbe9 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/booleanAttributes.html @@ -0,0 +1,19 @@ + + + Elements with boolean attributes + + +
    + + + + + +
    + + +
    + +
    Unwrappable text
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/child/childPage.html b/node_modules/selenium-webdriver/lib/test/data/child/childPage.html new file mode 100644 index 0000000..9192b54 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/child/childPage.html @@ -0,0 +1,8 @@ + + + Depth one child page + + +

    I'm a page in a child directory

    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/child/grandchild/grandchildPage.html b/node_modules/selenium-webdriver/lib/test/data/child/grandchild/grandchildPage.html new file mode 100644 index 0000000..f52685e --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/child/grandchild/grandchildPage.html @@ -0,0 +1,8 @@ + + + Depth two child page + + +

    I'm a page in a grandchild directory! How cute!

    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/clickEventPage.html b/node_modules/selenium-webdriver/lib/test/data/clickEventPage.html new file mode 100644 index 0000000..8e0355d --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/clickEventPage.html @@ -0,0 +1,26 @@ + + + + Testing click events + + + +
    + Click me to view my coordinates +
    + +
    +

     

    +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/click_frames.html b/node_modules/selenium-webdriver/lib/test/data/click_frames.html new file mode 100644 index 0000000..bd055c7 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_frames.html @@ -0,0 +1,10 @@ + + + click frames + + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/click_jacker.html b/node_modules/selenium-webdriver/lib/test/data/click_jacker.html new file mode 100644 index 0000000..0ff3900 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_jacker.html @@ -0,0 +1,38 @@ + + + + click-jacking + + + +
    +
    Click jacked!
    +
    Click Me
    + +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds.html b/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds.html new file mode 100644 index 0000000..8a51659 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds.html @@ -0,0 +1,23 @@ + + + + + + + + + + + +
    +
    +
    +
    +
    + +
    +
    +
    + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds_overflow.html b/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds_overflow.html new file mode 100644 index 0000000..15ac17f --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds_overflow.html @@ -0,0 +1,85 @@ + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    click me
    +
    + diff --git a/node_modules/selenium-webdriver/lib/test/data/click_rtl.html b/node_modules/selenium-webdriver/lib/test/data/click_rtl.html new file mode 100644 index 0000000..e84fffa --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_rtl.html @@ -0,0 +1,19 @@ + + +RTL test + + + +
    + +
    Ù…ÙØªØ§Ø­ معايير الويب
    + +
    פעילות הבינ×ו×
    + +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/click_source.html b/node_modules/selenium-webdriver/lib/test/data/click_source.html new file mode 100644 index 0000000..22e9319 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_source.html @@ -0,0 +1,18 @@ + + + Click Source + + + I go to a target + + + + + + Click Source + + + I go to a target + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/click_tests/click_iframe.html b/node_modules/selenium-webdriver/lib/test/data/click_tests/click_iframe.html new file mode 100644 index 0000000..7b749bc --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_tests/click_iframe.html @@ -0,0 +1,6 @@ + + + click iframe + +Click me + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/click_tests/click_in_iframe.html b/node_modules/selenium-webdriver/lib/test/data/click_tests/click_in_iframe.html new file mode 100644 index 0000000..60b1cca --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_tests/click_in_iframe.html @@ -0,0 +1,8 @@ + + + click in iframe + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_frame.html b/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_frame.html new file mode 100644 index 0000000..d6f4caf --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_frame.html @@ -0,0 +1 @@ +Continue \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_target.html b/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_target.html new file mode 100644 index 0000000..cbc16e8 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_target.html @@ -0,0 +1,10 @@ + + + + Target page for issue 5237 + + +

    Test passed

    + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/click_tests/link_that_wraps.html b/node_modules/selenium-webdriver/lib/test/data/click_tests/link_that_wraps.html new file mode 100644 index 0000000..0443436 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_tests/link_that_wraps.html @@ -0,0 +1,11 @@ + + + + Link that continues on next line + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page1.html b/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page1.html new file mode 100644 index 0000000..245f038 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page1.html @@ -0,0 +1,9 @@ + + + + Target Page 1 + + +
    Target Page 1
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page2.html b/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page2.html new file mode 100644 index 0000000..6f9636c --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page2.html @@ -0,0 +1,9 @@ + + + + Target Page 2 + + +
    Target Page 2
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page3.html b/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page3.html new file mode 100644 index 0000000..87a35f3 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page3.html @@ -0,0 +1,9 @@ + + + + Target Page 3 + + +
    Target Page 3
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/click_tests/span_that_wraps.html b/node_modules/selenium-webdriver/lib/test/data/click_tests/span_that_wraps.html new file mode 100644 index 0000000..77a9d6d --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_tests/span_that_wraps.html @@ -0,0 +1,11 @@ + + + + Link that continues on next line + + +
    +
    placeholder
    Span that continues on next line +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/click_tests/submitted_page.html b/node_modules/selenium-webdriver/lib/test/data/click_tests/submitted_page.html new file mode 100644 index 0000000..0ed2cba --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_tests/submitted_page.html @@ -0,0 +1,9 @@ + + + +Submitted Successfully! + + +

    Submitted Successfully!

    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/click_too_big.html b/node_modules/selenium-webdriver/lib/test/data/click_too_big.html new file mode 100644 index 0000000..568ee77 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_too_big.html @@ -0,0 +1,10 @@ + + + + +
    +       +
    +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/click_too_big_in_frame.html b/node_modules/selenium-webdriver/lib/test/data/click_too_big_in_frame.html new file mode 100644 index 0000000..cda990e --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_too_big_in_frame.html @@ -0,0 +1,11 @@ + + + This page has iframes + + +

    This is the heading

    + + + + +
    +I'm a normal link +
    +I go to an anchor +
    +I open a window with javascript +
    +Click me +
    + +
    +I'm a green link +

    looooooooooong short looooooooooong +

    + +333333 +

    I have a span

    And another span

    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/closeable_window.html b/node_modules/selenium-webdriver/lib/test/data/closeable_window.html new file mode 100644 index 0000000..e64c599 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/closeable_window.html @@ -0,0 +1,8 @@ + + +closeable window + + +This window can be closed by clicking on this. + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/cn-test.html b/node_modules/selenium-webdriver/lib/test/data/cn-test.html new file mode 100644 index 0000000..df846ad --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/cn-test.html @@ -0,0 +1,156 @@ + + + + + + + + + + +
    +
    + + +

    Õ¹Íû2008ÊÀ½ç´óÊÆ£º·çÆðÔÆÓ¿ ¼¤µ´ÈËÐÄ


    +
    + 8ÔÂ8ÈÕÍí£¬±±¾©2008Äê°ÂÔ˻ᵹ¼ÆÊ±Ò»ÖÜÄêÇì×£»î¶¯ÔÚÌì°²ÃŹ㳡¾ÙÐС£Í¼ÎªÇì×£»î¶¯ÖеÄÎÄÒÕÑݳö¡£ лªÉç¼ÇÕßÁõÎÀ±øÉã + + £²£°£°£¸ÄêÊÀ½ç·çÆðÔÆÓ¿£¬¼¤µ´ÈËÐÄ¡£µ«Òª×÷³öÒ»¸öÔ¤²â£¬Ê×ÏÈÒª¶Ô½ñÌìËù´¦µÄÊÀ½çÓÐÒ»¸ö»ù±¾¹²Ê¶¡£
    +
    +ÖйúÖ®Éù
    +
    +
    + +
    + +
    + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/colorPage.html b/node_modules/selenium-webdriver/lib/test/data/colorPage.html new file mode 100644 index 0000000..0d1bfc0 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/colorPage.html @@ -0,0 +1,20 @@ + + + + Color Page + + +
    namedColor
    +
    rgb
    +
    rgbpct
    +
    hex
    +
    hex
    +
    hsl
    +
    rgba
    +
    rgba
    +
    hsla
    + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/cookies.html b/node_modules/selenium-webdriver/lib/test/data/cookies.html new file mode 100644 index 0000000..7db5b49 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/cookies.html @@ -0,0 +1,30 @@ + + + Testing cookies + + + + +

    Cookie Mashing

    + .com Click
    + . Click
    + google.com Click
    + .google.com Click
    + 127.0.0.1 Click
    + localhost:3001 Click
    + .google:3001 Click
    + 172.16.12.225 Click
    + 172.16.12.225:port Click
    + Set on a different path + +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_frame.html b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_frame.html new file mode 100644 index 0000000..7714a48 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_frame.html @@ -0,0 +1,9 @@ + + + + Welcome Page + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_nested_frame.html b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_nested_frame.html new file mode 100644 index 0000000..b3143b0 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_nested_frame.html @@ -0,0 +1,9 @@ + + + + Welcome Page + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_element_out_of_view.html b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_element_out_of_view.html new file mode 100644 index 0000000..6f2bcd4 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_element_out_of_view.html @@ -0,0 +1,11 @@ + + + + Page With Element Out Of View + + +
    Placeholder
    +
    Red box
    +
    Tex after box
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_empty_element.html b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_empty_element.html new file mode 100644 index 0000000..b07972a --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_empty_element.html @@ -0,0 +1,10 @@ + + + + Page With Empty Element + + +
    +
    Tex after box
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_fixed_element.html b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_fixed_element.html new file mode 100644 index 0000000..b815891 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_fixed_element.html @@ -0,0 +1,12 @@ + + + + Page With Fixed Element + + +
    fixed red box
    +
    Placeholder
    +
    Element at the bottom
    +
    Tex after box
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_hidden_element.html b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_hidden_element.html new file mode 100644 index 0000000..286b04b --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_hidden_element.html @@ -0,0 +1,10 @@ + + + + Page With Hidden Element + + + +
    Tex after box
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_invisible_element.html b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_invisible_element.html new file mode 100644 index 0000000..dc33c71 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_invisible_element.html @@ -0,0 +1,10 @@ + + + + Page With Invisible Element + + + +
    Tex after box
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_transparent_element.html b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_transparent_element.html new file mode 100644 index 0000000..d0090d9 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_transparent_element.html @@ -0,0 +1,10 @@ + + + + Page With Transparent Element + + +
    Hidden box
    +
    Tex after box
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/simple_page.html b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/simple_page.html new file mode 100644 index 0000000..7b857b9 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/simple_page.html @@ -0,0 +1,10 @@ + + + + Simple Page + + +
    Red box
    +
    Tex after box
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png new file mode 100644 index 0000000000000000000000000000000000000000..954e22dbd99e8c6dd7091335599abf2d10bf8003 GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z^dEr#)R9Ln2z=UU%d=WFXS=@V?HT z#xG*`>Yvsgk=}99w^d^D^d*@m74oMo<%#FcopJf?u00-~YVKV2wzrI*_R6;UORMea zBFVSEnN~eiVA6V&z`E)YLz5Aok^D)In}Yn=OzDpgR5Wv0XfT8pOkmV{sKAJ-PO9#T zZK}IXj&Q-V!U)!LcB_3K0&C*{ literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png b/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png new file mode 100644 index 0000000000000000000000000000000000000000..64ece5707d91a6edf9fad4bfcce0c4dbcafcf58d GIT binary patch literal 251 zcmVbvPcjKS|RKP(6sDcCAB(_QB%0978a<$Ah$!b|E zwn;|HO0i8cQj@~)s!ajF0S002ovPDHLkV1oEp BYH0uf literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png b/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png new file mode 100644 index 0000000000000000000000000000000000000000..abdc01082bf3534eafecc5819d28c9574d44ea89 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FsY*{5$B>N1x91EQ4=4yQY-ImG zFPf9b{J;c_6SHRK%WcbN_hZpM=(Ry;4Rxv2@@2Y=$K57eF$X$=!PC{xWt~$(69B)$ BI)4BF literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png b/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..9b383f4d2eab09c0f2a739d6b232c32934bc620b GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnour1U*q978O6-yYw{%b*}|_(02F z@qbE9)0CJMo;*v*PWv`Vh2h6EmG8IS-Cm{3U~` zFlmZ}YMcJY=eo?o%*@I?2`NblNeMudl#t?{+tN>ySr~=F{k$>;_x^_y?afmf9pRKH0)6?eSP?3s5hEr>mdKI;Vst E0O;M1& literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png b/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png new file mode 100644 index 0000000000000000000000000000000000000000..39d5824d6af5456f1e89fc7847ea3599ea5fd815 GIT binary patch literal 3762 zcmb_eYgiKKwx-=Q?Pdi0+w!yaC|_1uvA>yaxz|iX3eBv#HR0ASmSVIKMS&kf`CSAV4g0DJLgPkRO79xj%J<(hH6`bTGj zrr^$JeiHJI?;s&<5pRw-^kj}=E;X0OX+pgz+f5GVt0NQv_gbu0>-8J+F$O>HpW?Lx z+YFO`CV&6VV9fsEwG#js0_-|v*!ujZ*M=jfo457?0Do-z<^}+8bI+qk+W~+$zz%Z& z;L7&@&ns`l8Ofh*WdU0pO%RP^?Xa_h7I}7K#}4Xt`s%-(m-enaPWX$O&- zX~a1aOzn?!r?5wJVBNPJ_o8-(9Fz<_c1LYGxUl(E+Wdx?wkNHH2T%eWq9Kz00h#RB zYKI~=a<9_QqC^n<>hyWlS66waWgyAP#t&TfTWP=Sxa)ukRY%j7WH}(@r=B^W_;b&M zRzPYsb*j^Kou%%`K6VP+dKtR@x~qEHq4rXMxoX-gcSf&->lMY%TMXF!Gw_A)(tp6} z2A%kN3twbr%KyUrrmw24V3d%wzK<-q(M;MTr41}un`P!!xejADEv_CJ{CTif907B& zEP`pDJIZHVgnmxh$EZnBOUxz~Ap+ZzKbFmg39_n-)$wY!Q@i~5aGmHbN7&*gkq9zWgV|2(Zhxl zoDqJp&MxW(qX#C@oF8L)*r$RdSjVFSc$%z?*9%YoZ6sOZ!vtxXtBM<*r82vyC}_Eiz1PJ2L$bttko`=+fH{Ne@G#lMDxkKt_y)O(J5&Ak)w-I znm!vzYX3$kLDG$hOp-KJg~7}M;73BFWA{!a61fe?NJkjR_}Xw+*`O0=AGg7&dUA`A?9`whW zM{fkFf`G`P^9j*|-q9KLvS<191z9a^mK3Lss}W8O=sZ}N$V4Fh*SWF5NbZQ>p{0>$ z0pe}d$*s!y*R&NSXbjmld6{4Y;O89MuDTK0Hn0C?QdL9z1qGegXs! z7$MIGkPkwdHF2os-Z-e85B?5An>yc|m<}>!Iirg%H-%F11XY{{>@kgL>a#6fM9JzBE&an&F>eWh|b0^kJ zNBM5*nCa~(xwn~rG~>GSG9mz3h z9F~64y}giIrz^lfl|_5HpUsG}?Wpr*&f?bS=|9biqivN)-a~u>uK<{Lfcng{663QL zLXzO@*N5)q4C=j6E8nC+P%lEwI#~0wkt;M4Y8!+DYzN2rBuYao1*HRIa^NC9nFeep z+ns5$X9Bh48S-`ss!k&!J#Ddd=j1O-9}?`v(B|>R7wD97BV;nK~quUHx^mj^G6K2GZ1*uSN?iLm!7vHB7_1^TGbKhmnK+K`GYA zocp2=on8LxJH^`7^1ch0ft(MTU$vJB!R@gQ^R`qoX>(=iY#u++3K>oqSpG={?#YVw zp3m99FXk^~<6#X9X1oKYXEH%8t2btG65(u0zF-J)^>8dj0Evc+9_Bd^Y)k9AfW~FV z%iDV(ClS6)TC7eVzh{ml;p4cx8)$TV&qhRWp+dqiw>i32?1;5d>HLrNj=^OdJ<}L) zWxqw8aFI<~_TkMDQHS?`z+KQ?+{ASoy%}RBu6i9?BXbh%OEx1OuZ}?n(VjrT(!B1; zQ!#WA0NBx=^6rJrFVsDCuT4)OTGzZ3$Z4Yqz z&c9+7%g!%zxtv#p2fhHbo98KBwfE&Y(&2#=}qEEU`ECEjlCp=X^_tIoMx>%kBT5k)^c=zyV5w3 zc>DLKY6%=y0igWi9B@4hB}bR6K|+jYBt+}i6Ld|b`*s62c6Ge?zGYvdW)=p90~$Ad zxGB>c<3Dy~hPJ#vNXierOl41xBn_0L<5NhK6JO-LvtS&Z{xjGKfIC6*9%*?tv*?+! zv;Q{?mHN2b|3DEJO}R9w11ZT5QVC(H0u|0n9cVK_@2r%C<)OnZ(3aS0Ux^6G$ja*< z9R~o~9XjhPL)w@vYi6r;H$tR>wW`0-Z&Qed`X0LZY9-~mfso!@dt?5Q;@|K6$mAB& z$J41&y)<{N;QATPeU}BC{lM_@-LlQ2hjX;}6~qdglT zGm%qJm*F^in=w*?j;@C_PCMnXK5Fd^wXV**pZOdS1KbSJsC~s#R;tmXIMb` zHB>sxQg&E5Yf@}d#~Z9D4R{}ZpLm7S=bY0x#k<=H?=R+=W$=Bm2aU*n z)qgD*0#4>GGlHhQ`bx#k=Njc;+9D@{F5`xI^tMkBf{XIzwB=b9KbuuLF7jMTR~Mwt zN#!)9J4&^V@JRe9Y!b2!;$rCLPWZfG`C;Qz`u~TJdCzv->e`=R8uHX_2{Fp&pWJ*h z#A60&bY(j(^P@t_`_pktBV7{tFVoeNWlNA|zgNr&DMjJ_!k2%2s2~F@la$M6k%hWi z7}}hoDuoaN7?lchVk@4DunpEIS$72&uuF&F;&4uhC$L)6IzHHUryR9emzpxwsRXmj zfc}pI#oRCB7Y1;t=*58Gsv7x3PGuW^spn6V&dWf#?*TQ0(|*rr=EeE1o~y1wyQi%)e*oX6iX@$m0F1RtKUT0vgg!8^fWhYLqS zF@EOpFld7>f^kprb~YwMq=^<e|gw?QFyf8ck|ZC^>)3c`b$^C>jCB4Fne_1e$Cqt=4Ud#K~~8Nfa91W zwk17&D?X?4FRzR+5qCiIqPf0};K4$tW$}l~A?u_E=JSe;*f_DO>r{z=U4_<)dY)M! z7O#mizC+GN&#;)k)vkBUS@fZesb{v?YuFlCPRjsT5bxB4@+sqdq}xvvBhTngZ(N1LUCS-ei=5sgE-Tbc z7HK+A_O23MP@sUoc?I?*ZB|F)&%us|2O$#G7V$6z zq>G%6!cu7OEf+_#^A=23Hd6Db9-yK*NQ#S+kjJI7 zhLiLz{>zKKtHH>H;B-cALzj`>@+-~?X2aP7ypf9WMf8q0m)wS!Nkf+&R&&zEjFOUx zlq^>v#VAq}=)?dKRMe+010g9O;qAiaTA4dV+==mw%i3Re)DwZ$Wd5CK1m4Ivy&&Ef zO8W!SpcgA>zfTGAE!{IPJMhdZ`T4{K#7ndDT8K2&*jf=J8O>H*iDJ}ZK}z|$C3U62 z$nZhk4v$QIYzMaV+0`B8S!=9RSYzi*QG#tp>ZY|lY_`}A-zI7)(tV$B9G-tC#zt8m zre~pD7oIFkmIAM=s zw+Iili%nSC?yks)t~q4lTlZW(#5^yUV@+^KvIuQzZDO^*TBz!j#nX%*uiW|{x9q0w literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png new file mode 100644 index 0000000000000000000000000000000000000000..f1273672d253263b7564e9e21d69d7d9d0b337d9 GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^j6j^i!3HGVb)pi0l%l7LV~E7mxPQ=F85a&M@g_{ d|GeK{$Y5lo%PMu^>wln`44$rjF6*2UngE4^EGqy2 literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_222222_256x240.png b/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_222222_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..b273ff111d219c9b9a8b96d57683d0075fb7871a GIT binary patch literal 4369 zcmd^?`8O2)_s3^phOrG}UnfiUEn8(9QW1?MNkxXVDEpFin2{xWrLx5kBC;k~GmPmYTG^FX}c% zlGE{DS1Q;~I7-6ze&TN@+F-xsI6sd%SwK#*O5K|pDRZqEy< zJg0Nd8F@!OxqElm`~U#piM22@u@8B<moyKE%ct`B(jysxK+1m?G)UyIFs1t0}L zemGR&?jGaM1YQblj?v&@0iXS#fi-VbR9zLEnHLP?xQ|=%Ihrc7^yPWR!tW$yH!zrw z#I2}_!JnT^(qk)VgJr`NGdPtT^dmQIZc%=6nTAyJDXk+^3}wUOilJuwq>s=T_!9V) zr1)DT6VQ2~rgd@!Jlrte3}}m~j}juCS`J4(d-5+e-3@EzzTJNCE2z)w(kJ90z*QE) zBtnV@4mM>jTrZZ*$01SnGov0&=A-JrX5Ge%Pce1Vj}=5YQqBD^W@n4KmFxxpFK`uH zP;(xKV+6VJ2|g+?_Lct7`uElL<&jzGS8Gfva2+=8A@#V+xsAj9|Dkg)vL5yhX@~B= zN2KZSAUD%QH`x>H+@Ou(D1~Pyv#0nc&$!1kI?IO01yw3jD0@80qvc?T*Nr8?-%rC8 z@5$|WY?Hqp`ixmEkzeJTz_`_wsSRi1%Zivd`#+T{Aib6-rf$}M8sz6v zb6ERbr-SniO2wbOv!M4)nb}6UVzoVZEh5kQWh_5x4rYy3c!871NeaM(_p=4(kbS6U#x<*k8Wg^KHs2ttCz<+pBxQ$Z zQMv;kVm5_fF_vH`Mzrq$Y&6u?j6~ftIV0Yg)Nw7JysIN_ z-_n*K_v1c&D}-1{NbBwS2h#m1y0a5RiEcYil+58$8IDh49bPnzE7R8In6P%V{2IZU z7#clr=V4yyrRe@oXNqbqo^^LvlLE?%8XaI&N(Np90-psU}7kqmbWk zZ;YBwJNnNs$~d!mx9oMGyT( znaBoj0d}gpQ^aRr?6nW)$4god*`@Uh2e+YpS@0(Mw{|z|6ko3NbTvDiCu3YO+)egL z>uW(^ahKFj>iJ-JF!^KhKQyPTznJa;xyHYwxJgr16&Wid_9)-%*mEwo{B_|M9t@S1 zf@T@q?b2Qgl!~_(Roe;fdK)y|XG0;ls;ZbT)w-aOVttk#daQcY7$cpY496H*`m@+L zeP#$&yRbBjFWv}B)|5-1v=(66M_;V1SWv6MHnO}}1=vby&9l+gaP?|pXwp0AFDe#L z&MRJ^*qX6wgxhA_`*o=LGZ>G_NTX%AKHPz4bO^R72ZYK}ale3lffDgM8H!Wrw{B7A z{?c_|dh2J*y8b04c37OmqUw;#;G<* z@nz@dV`;7&^$)e!B}cd5tl0{g(Q>5_7H^@bEJi7;fQ4B$NGZerH#Ae1#8WDTH`iB&) zC6Et3BYY#mcJxh&)b2C^{aLq~psFN)Q1SucCaBaBUr%5PYX{~-q{KGEh)*;n;?75k z=hq%i^I}rd;z-#YyI`8-OfMpWz5kgJE3I!3ean6=UZi!BxG7i(YBk? z02HM7wS0)Wni{dWbQMRtd-A)_Az!t>F;IwWf~!*)-Az4}yryNkz&9)w>ElA80Oc`6 zHo#9H!Y3*Qx9n@Jn)!w6G^hb;e_n8zpIyXCN`JFkPc)^Q?2MsLNFhMgrcZI-<#1ne zjH;KFf?4eAT9mQZ}ZfHLGA#d%s;SZK4p0FwZT2S^{ zQ2BG1xJsbK6?yrHTjJi|5C0u=!|r!?*4FL%y%3q#(d+e>b_2I9!*iI!30}42Ia0bq zUf`Z?LGSEvtz8s``Tg5o_CP(FbR0X$FlE0yCnB7suDPmI2=yOg^*2#cY9o`X z;NY-3VBHZjnVcGS){GZ98{e+lq~O$u6pEcgd0CrnIsWffN1MbCZDH<7c^hv+Z0Ucf0{w zSzi^qKuUHD9Dgp0EAGg@@$zr32dQx>N=ws`MESEsmzgT2&L;?MSTo&ky&!-JR3g~1 zPGTt515X)wr+Bx(G9lWd;@Y3^Vl}50Wb&6-Tiy;HPS0drF`rC}qYq22K4)G#AoD0X zYw$E+Bz@Zr^50MAwu@$?%f9$r4WHH?*2|67&FXFhXBrVFGmg)6?h3^-1?t;UzH0*I zNVf9wQLNLnG2@q>6CGm>&y|lC`iCFfYd}9i%+xkl^5oBJ?<;aneCfcHqJh7Yl5uLS z9Fx-(kMdcNyZejXh22N{mCw_rX1O!cOE&3>e(ZH81PR95wQC37En4O{w;{3q9n1t&;p)D%&Z%Nw$gSPa!nz8Slh7=ko2am)XARwOWw zpsz0~K!s{(dM$NB=(A=kkp>T(*yU6<_dwIx>cH4+LWl282hXa6-EUq>R3t?G2623< z*RwTN%-fgBmD{fu*ejNn)1@KG?Sg*8z3hYtkQJQjB6 zQ|x>wA=o$=O)+nLmgTXW3_6diA;b4EY{*i*R%6dO2EMg z@6g?M3rpbnfB@hOdUeb96=~I?OIA3@BWAGmTwiQ{x5Cqq<8c10L!P zd@Qk^BseTX%$Q7^s}5n%HB|)gKx}H$d8Sb$bBnq9-AglT2dGR2(+I;_fL|R4p$odJ zllfb0NqI)7=^z~qAm1V{(PkpxXsQ#4*NH9yYZ`Vf@)?#ueGgtCmGGY|9U#v|hRdg- zQ%0#cGIfXCd{Y)JB~qykO;KPvHu|5Ck&(Hn%DF~cct@}j+87xhs2ew;fLm5#2+mb| z8{9e*YI(u|gt|{x1G+U=DA3y)9s2w7@cvQ($ZJIA)x$e~5_3LKFV~ASci8W}jF&VeJoPDUy(BB>ExJpck;%;!`0AAo zAcHgcnT8%OX&UW_n|%{2B|<6Wp2MMGvd5`T2KKv;ltt_~H+w00x6+SlAD`{K4!9zx z*1?EpQ%Lwiik){3n{-+YNrT;fH_niD_Ng9|58@m8RsKFVF!6pk@qxa{BH-&8tsim0 zdAQ(GyC^9ane7_KW*#^vMIoeQdpJqmPp%%px3GIftbwESu#+vPyI*YTuJ6+4`z{s? zpkv~0x4c_PFH`-tqafw5)>4AuQ78SkZ!$8}INLK;Egr;2tS18hEO5=t;QDmZ-qu?I zG+=DN`nR72Xto{{bJp||`k}-2G;5#xg8E~xgz22)^_Z;=K|4@(E&5J)SY2of=olcw z5)@L)_Ntcm!*5nEy0M9v0`S33;pO4TN;>4(Z+19p_0>u#e-vE zXCU(6gAvu~I7Cw(xd%0e59MNLw^U37ZDbsBrj%eDCexw8a3G`nTcXVNL6{B7Hj@i& zbVB{;ApEtHk76q08DJ48dSxd$C(;$K6=FpU<~l9pVoT9arW^Vu{%Bcn4`eIpkOVC| z$)AKYG_`ypM{0@BUb3^9lqi_c?ONH|4UJMJWDowMVjacycX7}9g={O7swOB+{;+?; zjBo!9?+nd)ie#x5IbFW-zBOo0c4q@9wGVt5;pNt`=-~Zgcw#*`m($6ibxtZ`H=e=} zF#GZ~5$%AUn};8U#tRem0J(JTR}d4vR(dgK2ML~lZsPhayJ2h1%sD4FVst| zKF)+@`iNzLRjg4=K8@**0=5cE>%?FDc({I^+g9USk<8$&^qD~@%W0i4b|yMG*p4`N zh}I!ltTRI8Ex$+@V{02Br%xq#O?UlhO{r8WsaZnZCZq0MK9%AXU%MDLT;3=0A9(BV z9VxxxJd7jo$hw3q;3o?yBLmA=azBUrd9>-<_ANs0n3?-Ic*6&ytb@H~?0E(*d>T5n z-HiH2jsDf6uWhID%#n>SzOqrFCPDfUcu5QPd?<(=w6pv1BE#nsxS{n!UnC9qAha1< z;3cpZ9A-e$+Y)%b;w@!!YRA9p%Kf9IHGGg^{+p`mh;q8i7}&e@V3EQaMsItEMS&=X plT@$;k0WcB_jb;cn%_Idz4HO$QU*abf4}+wi?e96N>fbq{{i|W0@(ln literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_228ef1_256x240.png b/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_228ef1_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..a641a371afa0fbb08ba599dc7ddf14b9bfc3c84f GIT binary patch literal 4369 zcmd^?`8O2)_s3^phOrG}UnfiUEn8(9QW1?MNkxXVDEpFin2{xWrLx5kBC;k~Gmw z<@?HsG!Qg3zaV+-xQ3ldtad!U<6iGz_enGH*2akP_r)o1D&8p^5M)_c8IIj6Wy*7HJo&CBLuo~nj>(63pZzO(Vv^ZuB3 zMYigjkwA;FEy|G}1jpiMj6|NTm7Uyiw=@FDE*nX<>jR!W@9XIyf%$Fd*J5*D0Z0Lm z9}ZQxyT|x5ftNy?V>EbJz-K>bV9gs9RaXUP<^=;e?&Fqxj;6{ieR-a-@HycA1KMKhql8GOmcxwZ?_-(3hMK^^a*(gaFvBH ziIC!fgH4$W*NbKIaY&T?%&13``KbD@S-0`xQ%v3TV+B!;RC7O!+1a9QCA$H@3tR;k z)SSoR7(s4)f{zM}eWgFN{(ZH5d1O}l)f$ruT!)Q&NImXyZsTzOf9TwctcSfr+M)aJ z5otO+$jvm-P4)ykH)x|cO5xeb>?!`qGw$(>&axqLL6yoB${vsMXgL_-bz@2J_tS92 zdvZG-+vKl@K4Vr(EL{WQt@Z+Ea-hxX0}nTSZxnpi^#Kn8Ox8FgIS|hc}KJQ4tm*HO16ui{(O9} z1YN)GjiQt6fGq`Cj+^`zUf?8hk^(T{{cOQGWFP98am}is28A!5%{R#ENv8fCN!j69 zlMEK(2z?|BY=Je$XD9mB-Kkem*(d-j^9j$2#6r$Dz?s)-TCDCGCs z8>6Pvj{Y+YIeFA@qY22V$)awy@q!9A4rgk5b9TcC;s9Ig^G|6nDP+5=Fzg&?(L=vc zCbGd>fSu~@6!94td+o#d@sid!EIX$rx7*cawe6 z`dScJ+$HssdOjE)O#Ybs56vm-FQ$7yuJJD^Zqk%hMaIgAJ<2yb_MFQte_i;62ScT$ zpjifYyR_E=rQ+>H)pmlr-Udzg*-!|ssw(D7wJvC+Sf8bb9;;q8#z?0p!!bsd{wy|5 zpBaMHE-Ve>i#LLjHRaMLtp%9&(HCng7Sw96jVv!#0k%?F^K7&=T)mnYn)D9(i;4x5 z^NJTJwq~pv;kH@#ejTd*48~(J(r6j34|m`h9fEDj0im)~+%I5XphWymhT;_Zty|Q& zzjPg#-ufAHZ1M*Gccw?Kf|8Pnhtb0`!{N`Bqsa37J+>wC$!e z00k+2Egzz;rbcWoUB%Jvp8W1}$XD%e3>4y;;OZ1ccT-O#uW6Ys@C}Pa`nZrNKzR(2 z4e%3)@QI4SE&E!lW`5y14QhbepBG%_XBV-O(%5tj)@9#|;sC-MNev!zGDHk}JdpGC`iJF#8=8-P$Xoku_=Dw%Cv3{U7L>gf zRQ?<$t`cZ*MP5GQmbmx#!+*!zu>0MewRO9GFGS{b^m_fJ-N0?j@EqoFf>$khj+E|@ z7r3We&^tR^YZrxKe*d22agXqCO0l44&kqCv{u)T|(lv`~PK@DvE z{QI_TlCH5z*gR!>LO)k67{^R+vWx24U2^2ODXpwT;6y+6+$5m)_*w4WY&#do9dCeE z)>p+Ykdhq($DhmMiaYXey!@N%L26uz($aJ!QT{B^Wu}U$^9e#5)=c+XF9@Ill?ZmM zlNgHiz*9!vDc&uxOo;ZVxb`Q!Sk0*gnfxWzmbZh4(=%CD%qP?0=);n$&zaW_$UKV9 z8axdcN#AyZ{P)wj?V{P}vM)YY!>6@}^>U+iv$`9>nMTCPjN>z%yF&3yf%>+T@0vh4 zlC8Xa6zeo?%=o3}M8{aebLHcO{^1Ar8qiM=Gquf?Jo)q5`-+?sUpg?QXyEUpWSm+n z$K-UyqkIwHLquru~o(OF)hhz$Y*|X>ZIbswnxRvr~ z2=rdOGVuD|xRlpAZE<0!X1F(%Anpl^@V^D3vbM}qxe|NI;TTiZy7(IM;R69RkA>a& z6gwYE2sREzQ_LHmWqB+ogMk(fMaSFeoDq-!HkFB_nXt5+2ncFuk9BQL1I&oB1zZi) zYW{6_&-Ip1l*OVRA##1ILQS;5R{-K^0wGTiJbVSi@LA^$D$;@J>^G{6@&+%4{b3(s zC~LEHiTv(0b#zxt?YJ0r_~pUZM~mQ(??(n#>&tD%+@nq=Abj5*8R!~Ul1`G~=qFJ4 zfl|m8ZDCYgtr`4LcOpgiJYX9qRY5;DcWti~PmS$VB$E-Zt^f4)vLDOe_3XTq5^ylW zJ9PKm!V-8sAOJXnUfuFNIf0R9tK-pNs2hO04zr620}5B(Ok>yB)Of-3sP59qfQNbm zA4{w!2@cB;GbR(~szVrbO%(w=5S!X`o@o@x++wbN_tMPT0Vc)*I;Fgsbf^*g0 z2Di?HTApwKq3+YwfNsqd3iP%{hyK1iyuVZc@*0tO_3+N0#GFsz>8MjeJ2UJ%L!%hi zGYYAthH`E+ywA*u{(eJ=ia3h*%k?779rk-K<0VZAPkl;TFUbmei|$fqWO8!_zIvqt z$ly$VrlH46nnpX~X5Yk0iBJl;=WuA4>~X4-f&K0yWf42h&0b30t@NYX$7egQ1Fp!a zbui-D6cWCWV&|R1CY@G8(qOmWjWeX3eX7UggZPGimA}soOuQdXe4uZ#2>5zN>qlI0 z9xk}lE=tNpX1m6*nFr2EQ3xs79!^sCldDJYE$m(qYv3q7>}1R7?iZW7>$~*%zKaC| z=$N?ME$>#+%T&MZC`dW1wUl6Z)JgyCn~V%K&i0H|iwE%$>xsZW3tTfZxIUePci@p;cRu|d=ItIwF z1clVHy{hH?@SD|(Zfqi^0DQ1hczHN7xq85h)rzQqLHMX2^IkuK7FB!kI40s$|CY7~ zNX^{_UjN8}L%Med;|+=4RNTMozn8KT;2tb77bUPCmioh+rZBfIiM6f_P34cQ__o1G zWqQp3VL~~pE5?qODf%iiQQ3f42YF@09tQ*$4v_EKUx;t1KCPCBtgqg z@+Tn;O)a0uky_%jm+WjNB?=~VyH>V#L!*=l*@OS6SVyt_UEH&NA=?V2stHPyKkVNy z&jg<#cjros){#ji)dK z%)We0L_478=HZ8-@xnwsKrWs8)x`MB;(Y`Cmu2c-&SH(vN-F(*e`l?c%+l$|y_AJJ zhcDGnwLvN+bu;_sX|1AiePhx@u&%P$hf*xE+O=~D?_(_KGWQ!158YL-y9$*6mmPo;Rp*Dl5lm-mVM2i`h- zM@nxv590_tvMwPD_{l=b$iOm|+|S{D9&P%zeT$GgX6Akl-tfUF>tL@Ld!B&{pN39t zH>3Vhqkr}2Yul+jb7UiouWVGPNsxX7Ueba+9|~dz?d*QM$ng0DZfO0`7fAy?2yMm| zcnRzUhZ&IcwgjH9cuU!w+VStYa{p*)4IgBf|E8)sqMYtB2KH_}SfsFq(c9i(Q6S3U oBo%DI*Kv;w;*%(i9W@e{{5C=l}o! literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ef8c08_256x240.png b/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ef8c08_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..85e63e9f604ce042d59eb06a8428eeb7cb7896c9 GIT binary patch literal 4369 zcmd^?`8O2)_s3^phOrG}UnfiUEn8(9QW1?MNkxXVDEpFin2{xWrLx5kBC;k~GmC-Ajq!3AfU8Dx90^_ zp3}MKjJzYC+`T(&egFXQ#9Ek{*oVAaa!zrZtmlRFnwQPRJXH<%pkK2*eP`pT=lwD7 zifq+4BY_rUTa+U|2#&?i7>PVvD?7R4ZfOLPT{e9G~G!Ls3s8JtQE`jMM9wl2V9&Q+K2DHW0M+uQmEr%nYJ^7cK?uIpU-)=wn71ZZ-=@ar0;3^AY z5+TI{2b(e%t{2PZ^HKF*vu@+Xr&BAc@2BC4 z_vCgww#i=)ea5Vo$glEEVBBg_VPBj!)OO>)f@}#dg6ULOeC>LBHz<;*5Y;YfE0lNx zg{N+4@lO~ozxpF69qV@VOGnc248Iuag4C1T)P^(hWkpP!{h!JekX}m^Q#b2B4f1oT zIjsGz)4}-$rQ*-tSuc%qG>%<4xM#E& zN)7lRK~^2VdiloY4>;#}A!yHOAXEmEi^+eA#05pawGXs>!z)gSoDuI#>bRCq-qjJe zZ)r=A`*EMX6+)~er1kdv1L^)0-PsAEM7JF$O6G8>496$24lkOSR^RTfUuIz%iSfn5b-t!##cs7sQI);gdAvqmn_v|%I9k;fCPl0Z)R1+hNQONJN zH%3jT9sOq*a`LF*MiY=zlSSQZ;{_FL9M07A=In+O!~wR}=bzGEQpk2!Vc0p)qKAH? zOk{(%06W#)DdICQ_S%Q@<0Y+!?9%#$gWJ%)EO->^YZP{<`oB4~9xh zL9-0*c4@B#O2ylYs_g`Ky$zb~v!M`NRaMNFYF*Gsu|7)=JyyMHjFC=HhGUE@{aI|B zJ~ITXU052%7jFb5Ys#fhS_?4kqc7H0EU49B8(Chg0&JzU=Gka#xOz1)H0d4m7ZnRA z=M^tdY|U6T!fmte{W?_r8H~qdq|q{5AMU_2It1I4143n~xL?4&K#BOB48l9_Rdm!(c^C?JU;tF0 zEh@o1y6Qa_>}#AwX{VY+`C^kNkxhgb1P5cB0%xupAXyg9NO=SnXrJUE?rQg{Lcsn+ zAZKctGLfbK_B#^&Nev|0^fB&?DN=ak8|0!np524LD25=s84BP8Vl(3=jflNp{X>e@ z637Ri5xx;&JNl+XYImA|{;XR~P*svYDEWYJ6I5!6uO~2twFC1ZQevB7#3z~(apxn& z^J@>Mc`>PJair{yT`iuan-V+i%|Ho-pA<1?V-k^R2Q<5;Co%XxmL` z018t4T0TTwO^w)Gx{9OSJ^9_|kgwX`7%0Rw!PO~@?xvnfUehvN;2Rc;^l>3kfbtk3 z8{j7p;S&{uTlTe9&HTc38q@%_KQFk<&n{vmrN7y&Cz{etcE->rq!6HL)2F!aa=0%! zM%Bwo!7TQ5t;@a_#Q}sjk{UebWQZ8{cp&HN^$*JfH#8spkhk{R@CVBiPuP@yEhu{} zsQfuhTqV%rioATpEphMfhyRYbVfVW`YwLFXUWm-===J(byMf!5;W^CV1g~2194Xx) zFK|z{pm%n-)-DRe{Qhk(d!QaoI*y%Wn6h7<6A{i*Sob&B^y|Spg!&J$`kN>zwUJ3x zaB$ciu*0FJKg}T ztgnh)ASF8njz5>h6?f#{c=*Yr4W_34$GmVIo8OLWjcZK4a0`+Yv-!*}9 zBwKm;DAsA(nDI-`iH@;`=gP+m{lgFLHK3m$W@?)&dGhDA_Z2xOzI0$p(ZJtH$vCxE zj>+kYNBJzs-TlSx!tSH}%I9fQv)mc!C7X0bKlZv4f&}C3+O-4k7AmVO|KYZ9ydP%(N1^uisV8y;~p`x4qFXD?!_OyN9=w(Od6W; zGrT?G;l2v@Ob5k^8w<9w%Jbjb^|H}PYKo}I~bobd!XrTbzp2Zp~H8lgJ)I3?l&(bDiWf8gE&6b z>)9GB=Iu-6%I((+>=jGP>CzD8c0oWITFZGgM!Q7|JrUYq4#^Y(vuDu-a>OWDa4Y4} z5a_*lW#IL_aVf8L+Ty}c&2VojLEIA-;eQK6Wo?xAuK>i;1VWx3c=!s2;j_*iRHOsb*>6-CgcYP+Ho=L@XLd*j~2ln-;WHg)|cCixksH$K={5rGSD@yB%LI|(NCc8 z1Er8H+QO)~S~K{g?nH|2dB8SKs)BxQ?%G}}o*LV!NG2m*TmR|pWj~g`>)ClJCE#F$ zcj)fBg(dKOKmc$Cy}IRlasngIR>z~kP&WW~9cC951{AKmnZ~ZMsqup6QQf7J0T1;C zK9*Qd5*(HxW=tl|RfjO>nkoW#AU3t>JkuzWxy4-l?xmTv15_r1X@p@dz^{&j&;{Mq z$^0$0q&y?kbdZh)kZ+NfXfqLTG}Q^j>qHlUH4VEK`3y^-z6Y<6O88Hf4v^;}!{t-a zDWg;znYu%6zA1~A5~w?fxO~i8-Ib(^02{c4pXjhDI^2 zXB1LP4dvWuc%PXQ{r!d#6>${rm+M8EJM8yf#!H$Kp8AxwUXm5`7Tu-J$mHeCG>vw|&Ay415}_1w&*9K8+2d3v1N+@a$|820o4u60Tj@u&kI!~q2V9X; z>tMvQDI|O$#m+m2O**ZHq`_{#8)ry6`&5s~2k{O4Du16Fn0P;&_(0!e5%Bel){nU0 zJX~<8U6hoI%yx}qGY_1Tq7YKDJ)ETOCs&W)TiCrK*1%DE*vXdD-7hwE*LUgjeHRM` z&@pkhTi>m#Kc+QIK+2Ybn9-sFVKNHyIgfob4H_77yYh))Rq$7Pw|+aD6&yZ|ki9 z8Zb6s{oBt1G+PgfIcxd}{m@~1nzhe;LH)5;!gS8@ddyabpdBc?7JVl?tS+<#bPSMT z2@0uYdsWN(;Ww)n-PlA-0r+62@bYkEa`k{0s})fJgYZ#5=DmIdEvok7aZJRi{w-|} zkea&6X}ZA3b7&vbDb7)v8CuI(+zzSf3z&P2eOrPNP?D~ zf zn0@)0h;~5F&BG5vOFU!=woW&ZSl~nrs{?1w>nWfW_dnpTd z4qvLDYJ*ft>Sp%M(^_xCZpNBnc66JX}A|ZL9IENM`U>`ph7d<+RQiI}@E8Y)70s zMC*_&))}GlmR}@{v9*nm)29-=rn`Q$rc^4G)GVQHlTr6BpGxtHuU(8AF7Ffh54?5w zj+EYT9>x)PWL-iQ@RNmT?R+|c@=FOmj)5Za6_ z@DkVy4l^L>Z3#SI@s_eVwd3D)<^Ivq8a~J{|4mhOL^<7M4D8){ut;GIqqn`oqCk|x pNh;Wa$C0(mdpqYz&F>xK-uVD=DT5%Jzh8ZT#aXmjr70%*{{RacS`YvL literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffd27a_256x240.png b/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffd27a_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..e117effa3dca24e7978cfc5f8b967f661e81044f GIT binary patch literal 4369 zcmd^?`8O2)_s3@pGmLE*`#M>&Z`mr_kcwz5Nh&g=McJ3E!;CE1E0ryV5Ro;>nvtvt zk&I==Xd;cVGZ@>q_xtnx{1u%7-D)N|5YqOB>i;(bZ#o62{J2Y9&^D3~R^$o+X? zwbxAEIb)xwCwK3TSR4QVym6N1rVgPmmt0caryBUceHP_&u}{?^Jn7f0PT$#h>UDqI zr!q(F&1jJ2_!jxdAB<)7H$foI*2zuncvu;;$SoU7br=AiJ@4=BC4vNO>DS`&UIB=K z;2)0F*t^FBvVfPuT4FVMSwUw%Xksjyl+;#*DDy%=ocFOyzDLvLR(`zCSOuJ=?FWYn z5ZD!UaoF>-$@=Vt?a&;UQYM$Oqe0ZB?Je?8ZnMxDe&uzzs*zlHd)V58nfJPc8S^({_4bj5HQ_B&EXHWj6wx@B;!mr04b_Mx)UFL)W7`V!c zpMp#C!a!!sh3h491y}^qfimXVY%!+sYu0_DWoJMqpN(FR9LM#jdZ{vJzEck`P^9(1N=4J za9%u4$2J8TAkUaJk_FX%iHuv#svL_mMmp{SR}ifc#ZcXv%CFsT?*>N^6r(%D?1YnU zAaT?UZGlOna6UXXs0m)3YDp}d%hb@)@Y!lK_A&D6{OPlNnj zYY*$b>vnRzL8=CDbQSi!DL3D!P^xhNtwrYByo?h-&OvQZYJ6ka{Re# zSc0ry_d(K$_Q2M{Y^O~DOK(szDOnMi_*h_Rx%eSRxA%n|FuC&=F=)B z_Qsgmj8g!GA+LZOX)gOW}vbo9|l8QW3iYw9qCD{o~xt^HIU>;dV5MJgc0#uHTA z80%Ee_r;G`GUjssm z*AhtwpW%Ly;X4Lq1Zq#ZpuwzrZE$sR087dN{w7PA6|Mo#6wwJP085K+h7+D>NyeX# zk|?MJ^Es)JtP-2eNr0EQe*ZM`&}OU zCD*uSSviE&p}uX|@1g_%|3*ra*MbBV#~cshdcFQ(dGLnTqaO-3{u==x1;Pp2im!#` zuZ2`ThfAmiSzb|4h`c4?^ZoGOF*oXYcV}(ge!v@^bse?daA`Ma+bSZLIg;pIN17vM zIOYfK=@s_Pj?~#lqnY2o?d1$MpoqsYQw%eX%X6Y4*^27{hMWGqILEMnVYUEMW#x7f zu^I*nzXQ@6HJ8n;26 zo^1+Ewi$fN$Unum1(FTb8I#cYgcGklwIExt#Mb(D=x~OTeZ^ubJ)S-ywfdZS?SRCq zDm=eU+CCWO@8S_m!W{alT)zj zZJbjxm5&No5xe_~Jw-i7`&G}=r)POGGfFq+c@kQbB#)ay`coj&C3- z(#&xV@Q3@VJd{qdH4g@4ZJi&mx9e@Io7@~(o5vTrkW>QEO1T-gmlTRHH+3)gcUC0P zk07rvDnf*7Y5J}8!>F_7D^Z3IoH^uGH}_a(ax{Q(IrvV$olf3WN&DY?uYZfvXI(;Vv&EAoQtfH;+4VI_a>yh*J+Cj!?h!QX?O`QXk@@G7AjloJe51Cw*rPXQ>#y?B^^ExRQFui zolmv*C5K|-p){rZiCNai^0H`1(Qr(Hz3v%7NnmriXu2tD>xsbN#*R3*wsZhRj6Lvb zn0Cu=qkC?*e4{NF_3=^bTb1f!g?@ryFH6Zw2tz%A zzz&o{w`dDv66!6Wk9w1-dglS#Sm{doxw&h5Z8&ONmlBBte{J)puaDzc!LC==rPRQK zQNH23?-rIo^MQdt3Tk!B@8l#}fxVtrlc8Y<>ORaVE($DKc{77qV^`+`%_DotrUD=8 z4}L7QnZi3RgUy*tteY-=$SqA2@IZWe(}mI`nzhAT{qC)my#rJsfoS*)xCXj!Tk6=3)cr@Jw#OcNqgS3pg7x|4!A$|w15X!huR*vB3q9Ya4 zF{xuzEQz{9YPl(gk`}Gffut%jotgqp$jZvzRO4EsExf~93vY~04AxH=lR>R3v3Qs2 zy$v4SN%ee@Kz#kDtARaQD`d!R%}#@T1=v8DAow*r>+0d1KS{ZtA~KMtgm)+$JHumW zw=;@qWk&MuG@LKx#K3@&WMw?r=jD2_)(*$LmkCm4_@};QZI|SPe8hIC6xqBy!LQyK z01_xmfNA9UlBU@Kzu7;zQYxHE>OCADA$gwaVqm`eN?XQF@NkrocB}lU4hcCf>wqir z>Ya=PcE!Xm#JG8v@G0lj&~)hScM}X57vGw3g<$^SUls53f|Bk>5FQwqE&{%u(f$!1 zl8+53vyYZ`mEEp&YT<=(krhKrw?~pS{N)?q{0qBR#2Y!w4!hWMdj`a(@A@r$zVB+u z06Hb@_9(cQ_AxbXI|-2w>#QUhp7k<+`z9+(jkh~v-Renr#C9U+&jL4vg6-E$f7@UU z(1fxB8{U2vq}h3rE!Z+n7=(>D&}@9~3mJ^R5}|WVG@!RSh3r{!>QHwg!t29YS&jiR ztyn_q*k9H0efZ7hO*b(WR|G!TDY`rol~Ob4&1OwdM8kbGj`^$~L5gdWYceWwL=PB{~NX=cu3p-{S;hqaE?bSHv$g+SA6bxy+VU3YVTPDj6CN zKLb_(9gM2Y#KW8ONxjH9To^Y)r?ql2cq8+WE438uIF$hjfdLs6-;!jv55jGcc3Ipg z;}aT32NAEGeU;J}&j5=+u`4?%xlwL7?NDn%2={4WS39yn3f;&r=|}5=M-Y2yrxeSw zv%*PmV{_{#Qk1sD>?M2KDapb~z3!E*-LPmCe9q86D%MGSe;4~~K-jKQxq6b^902_{ z%>4G>@Xqk8muR*|vGe5{@7sds2i|i;g}oMkd!o^0=HG+vcPrcN54A zLGv$PlTePRxp~-OSb_*aACO1qc{MpfS-fv(@UmRv%UO)cSt;ee@9(S)f>|~bwU@eZ z=kTS*sdjLclwMZG#?%U3)bq-uj?@@vj~6tq)ZS||Jxz`+di-M5SXM=h3EL`?pB>W9A;`V2vM)vk&%KFy|TAh#AQA zb_?J==3f@%LL{`vU$3Z@A2a9C3aC-YY43dR> pI7J0n@;b3~`)ubvsr|iU(l;L{A#E6J`}eC4usn-0uQEf&{2ws1m(ltoqJ#RmwV2==ic*rz7lOw=eaq=H~;_ux21)-Jpcgw zdj+hrf&W^f<%Qk9Zpqf#;q3n5{{POY;f!wmTR1An9(4&I0z1LNX50QSTV2M%4|y9c z#{ZQIVJKu~aY5?ZaZP*GIGqGs=e@q6o|EPhZB3CC?@LnORK8O@z{{<0KtSn5?#~OW zy=L;x8T&*%xqElS;s5~Pjk7d2bqIaA)xZbovnZd7eX17WNxx=w`p(8vulwUZ zl{so}MuRNJx5!8S5G;$o2?BApPHt+)!^#*Ww`?rcVE}mcyuY`X2o|uVUyI9o1t11O zemGWR?;aD#0$vJhiPhv~0iXS#iLq!>Qd$` zU{}<|Vb9Md>$4TMbL7C3GP#r;4Wc$}Z;^j;n}yc!E3d;`wry$!JkmJP0%(tIh!!TET8=+{rhUi^60G0t2HJSxXv-*DgC(HrJd8`|Dp3NvL5yg>xAvU zho|fEA~w^-HrW&H-JwkqNX2I-bEXBR&Uhp+y2^)1h1IIlNCzC!v-Mz@&z&VPz+cl1 z=f&f6Y*U~C`ixm4Sy1hl$hg(4%Dy;bq~k7d1<@K&%%NLT`L+A)-QXyKVswX?op90( zB#yeFEih@c{OXU8Oq~1CFI_38GXmns3(`;W(i+bslovCx4u7gvK>DrGOug*?G|1nz z_OR}|ZYS3pq-p?rS7G0qa`TM}r5XqDT4cV>%Qyk#9ES}`jc+Ww|DcbZrF6UG>CeXp zOVIV}K1e#z9@tu#?X)Ri=?zXMB`X3G-_I7FL-Zq`nbfWtX_EO1*!+U6pJW-_k&+vk zMd}THh}{(Ch_wPk(PI4vVB_KT76kGxVytLxpWg}&bHw`a3G#QzxV@ICNax&@hk3<_ zBh`Tq66G{-tCw$V{(y0v7l!tp20~@gdFXjzFbF#bJE7i>T4ux zQdrF3org^wFcnw$#bQMv@SfN3$Fuo7HnB_`2ZGB{ZqGr>%xP;2_!Q{=N-ZhU1c~^5 zdt=OO#wmcpkXJyCG?{{&n=R{Sn=Ytg;<09CH)l7TA&wkt{Q;>RrA2Ia6-QixEPLrU z%0)N$3Nh0?U825&v($Sz}0G_(!v&xSSAzje4{rup+^W@^}ByqOb95$E0sbwK*%#GP}!6`%*Z@L;&C z3^dE&>5%bWAXmP*X1 z_m}Pivs*u7@9i>qA!58fDCwj^M<1P(u^m;urVdlM@>aIf+E3-d9ZW>fc4cS7w5O3sCmKKn z+94A?VyfSBb9{}rEbCIYtXORJBCv__fnZ>?a}edaA%bP$jI?J^q0UKO!mduA8U!3b z0CJ_Js}NWQZoebapVUHP%pPOUm?1<)zd%`hzUM-Y6g1z|@@3G_kio?S0bcbjQuxJd>vU$Uyz(4*peEDSVc-G;O;% z9Y97%Tq}TRsH+oN%2u(oyC=W<9`e@&m;i;jC%L;sP(9RBDQnth3;ZMEQNFH3GEf0c zU<3RF!hNG-vCDooYFS^nPlFnv4(ElI1=vNcr42TF^uq67f{MoN>{f&>xA91r4pz5Zc&@P^i-9||`98v$Si!U@}ouZ88W zg;YL=OQ;4}UQtkpyd~lD{qWy0H|lwJXKmenz#E=*9kt$YX*X!wDk7ITlIUGWnj>a7 z<_GQR752@J)Y(U)ncu(dIit7P}oBq8x$FP85)&Nsw<#rOW z8U_x(1J)Zgm(8tZXU%+(yYcO+Z7#ZszPwa2`ygiMPayX9KondtFMRK!7x`9uWN;(f zfWW?8yOdj;GA3We0YAW92gWipn(d>zcbA+vZ_21BxF?-pfcW` zbqY??6ie(6M)p@6@WQ?Tl7 zoKrKEj|x~2yZehhMLkFRRnOC>XL&L+N;m0B{_OQ9gzzTYb!!Jct=bk?_hIpY9rOwY zMnr69R(?8EN52qR+k!~qnCYc-KmV&*d$&NY?t5cjR)V+ncMor=puTRoo?{5dH;@!* z<~RrV!+ljAN+;Qx2LraY&JWnz^|sYbZjP+Y;|pC#DuHUH+>F~x3PqTkx)=OAE0X9( z(AO6gp~AH^{nq+n)LHYDD8mQN?DDFcd!U&d4PaajzSD1~lXq3p{x=^vItrq3gD^4O z=hYS`?&C-0&KuAV>Jv}T?ba0IafL$~+bZ}p$9lwyyx=-uPN`Hpvv<)Ia>OWHa4+N4 z6zscrW$^XA32EJw^7hYtkRJr{Q8 zQ|*1pp_q6Mno|D6EX!kgSv0h0I3~ef_l%$DTFjL`0y16n%^dGNQn;2V82mqoIi9i{15vu zLq&(BTl9CInUjZlTIa>^!!HlMK3W8Sd_Ow0+E8IT?h$=55$^Z)$WYIuig=O;Lp_1Q z4wOT;XbWQ!>Mh`pdXuSo=KBba;wT!wK`Hf1Ueh04*%D7Kfj*#b~BNfvz zsbf?uiMm5-xhaQ|7Om2OrYbU>ngUM9%F5nU<65IFyu(`yZ;Vb1)=wCd!L2K?c$ezE z4IbS|^?Z>)eEp}ZfjwF)Waw?pPJ?{~*g%;efxO~Nx7dQGLWZ)cPQ*T!((W- zGm2?tM)K}7oG<0Xz<`ltWjxvE<$AH!4*R{A2~uYGr@m!vm*j+e#CE9^*}Oc#uihB| z5;#kMY2^8mrr80%*+02bDx6B{Jsch(d7kQGV7~iGTgFZBu$Pf`tNf`B2{|t7fGhIq zos0xF#l$bfxOtcGDd*MDbdKBaCKxgCEbr8JTNd_1bjWC{Ubgk z9~)9;A1&=FyIt$l!VBXfD~6VCk0fjO%QwLJ7k00RH*%I8cCqF542VzP^;`OU-_?=< zbV}OoQE)HqV`|)X5+WbgSxGWH>t+7-O;(l~Z+FJJ)sygu^+eF01#Suj+pnAcw!s>p z$-xF}c>7t9X6H$^V9hvT5H{jKv+=zzWHA0pgw8e5fZpm9vIphVq3%S4*N3%&jsY^Q zK%sSPuj=?d{ATs0o0y6#0w3%YT^@-_sTuTUwI(Q{;l3KjeAbVk#Wmi%PDxm`zoqQ~ z((<-}*FSP%5gt7uI3t1&75ne{@1^bpdW1;MMGNkSr~UAuDbB4+VQi|x(gdO^zin_) zncfs2hj8xdiiy)@vVkfkItLKvsGtJhrTb0T~tFl4Q3J!flauS==b& z6Bm!g%dDvlCf(St$kVofvH90|9yl-gmvRvcKS&Ye9DdoTK@2m}iSvC{3m%4E0 z@TJD7c1V?!URM7+t?f3)%{X(6JXg~A9TvGQyX6n(^Yt0NX;>vDPcr~mICPooLWA_` z<1A>FuXr|C)dtDr*PQt%Xs5WePWUB&gBj$zZ#BIY%?jDdpbSA-PV0`dGf^oa_Jp}Z zlrGV7oe`#B^+nPIQ`ZDJeJas=ru#=*YL#+n?Go}f33>1GsZ{TTy2bdBihj}mz*mp! zOzn%{WgLM=*CpiuKUs*GnHa{B$2siJqfNi|Z;|rH%stM*8b26kAMCYY&NHwPGtlYn z7UVx_^sgR$Z8x27foS63FCPt|gtcG_ zy#@C|!VQV~TY}G5e57qp?F4jRxqq~@h6^?-cvD>ySwVLl2m7=gERtEn>Fw_@ND%pO oiVC*mbz<%I+0K1Z`+LWvZ$3~$+A!Gm?^hpSc@||}WrmLVKLvuzv;Y7A literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/jquery-ui-1.8.10.custom.css b/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/jquery-ui-1.8.10.custom.css new file mode 100644 index 0000000..1706e22 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/jquery-ui-1.8.10.custom.css @@ -0,0 +1,573 @@ +/* + * jQuery UI CSS Framework 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; } +.ui-widget-content a { color: #333333; } +.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; } +.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); } +.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/* + * jQuery UI Resizable 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* + * jQuery UI Selectable 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/* + * jQuery UI Accordion 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/* + * jQuery UI Autocomplete 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.10 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* + * jQuery UI Button 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Dialog 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* + * jQuery UI Slider 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* + * jQuery UI Tabs 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/* + * jQuery UI Datepicker 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/* + * jQuery UI Progressbar 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/cssTransform.html b/node_modules/selenium-webdriver/lib/test/data/cssTransform.html new file mode 100644 index 0000000..c3b9964 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/cssTransform.html @@ -0,0 +1,61 @@ + + +
    +You shouldn't see anything other than this sentence on the page +
    +
    + I have a hidden child +
    + I am a hidden child +
    +
    +
    + I have a hidden child +
    + I am a hidden child +
    +
    +
    I am a hidden element
    +
    I am a hidden element
    diff --git a/node_modules/selenium-webdriver/lib/test/data/cssTransform2.html b/node_modules/selenium-webdriver/lib/test/data/cssTransform2.html new file mode 100644 index 0000000..602924b --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/cssTransform2.html @@ -0,0 +1,20 @@ + + +
    +
    +
    +
    +
    +
    +
    I am not a hidden element
    diff --git a/node_modules/selenium-webdriver/lib/test/data/document_write_in_onload.html b/node_modules/selenium-webdriver/lib/test/data/document_write_in_onload.html new file mode 100644 index 0000000..a15fc47 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/document_write_in_onload.html @@ -0,0 +1,13 @@ + + + Document Write In Onload + + + +

    hello world

    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/dragAndDropInsideScrolledDiv.html b/node_modules/selenium-webdriver/lib/test/data/dragAndDropInsideScrolledDiv.html new file mode 100644 index 0000000..0b2ee9a --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/dragAndDropInsideScrolledDiv.html @@ -0,0 +1,67 @@ + + + + + + + +
    +
    +
    +
    +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/dragAndDropTest.html b/node_modules/selenium-webdriver/lib/test/data/dragAndDropTest.html new file mode 100644 index 0000000..fdee16b --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/dragAndDropTest.html @@ -0,0 +1,102 @@ + + + + + + + + +
    +
    +"Hi there +
    +
    +
    +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/dragDropOverflow.html b/node_modules/selenium-webdriver/lib/test/data/dragDropOverflow.html new file mode 100644 index 0000000..ecb2562 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/dragDropOverflow.html @@ -0,0 +1,104 @@ + + + + + + +
    +
    +
    +
    +
    12am
    +
    1am
    +
    2am
    +
    3am
    +
    4am
    +
    5am
    +
    6am
    +
    7am
    +
    8am
    +
    9am
    +
    10am
    +
    11am
    +
    12pm
    +
    1pm
    +
    2pm
    +
    3pm
    +
    4pm
    +
    5pm
    +
    6pm
    +
    7pm
    +
    8pm
    +
    9pm
    +
    10pm
    +
    11pm
    +
    +
    +
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/draggableLists.html b/node_modules/selenium-webdriver/lib/test/data/draggableLists.html new file mode 100644 index 0000000..f7e0dca --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/draggableLists.html @@ -0,0 +1,67 @@ + + + + + jQuery UI Sortable - Connect lists + + + + + + + + + +
    +
      +
    • LeftItem 1
    • +
    • LeftItem 2
    • +
    • LeftItem 3
    • +
    • LeftItem 4
    • +
    • LeftItem 5
    • +
    + +
      +
    • RightItem 1
    • +
    • RightItem 2
    • +
    • RightItem 3
    • +
    • RightItem 4
    • +
    • RightItem 5
    • +
    + +
    + +
    +
    +

    Nothing happened.

    +
    + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/droppableItems.html b/node_modules/selenium-webdriver/lib/test/data/droppableItems.html new file mode 100644 index 0000000..fc850ac --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/droppableItems.html @@ -0,0 +1,65 @@ + + + + + jQuery UI Droppable - Default Demo + + + + + + + +
    + +
    +

    Drag me to my target

    +
    + +
    +

    Drop here

    +
    + +
    +

    start

    +
    + +
    + +
    + +

    Taken from the JQuery demo.

    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/dynamic.html b/node_modules/selenium-webdriver/lib/test/data/dynamic.html new file mode 100644 index 0000000..b9e6067 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/dynamic.html @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/dynamicallyModifiedPage.html b/node_modules/selenium-webdriver/lib/test/data/dynamicallyModifiedPage.html new file mode 100644 index 0000000..ed7c7ed --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/dynamicallyModifiedPage.html @@ -0,0 +1,42 @@ + + + + Delayed remove of an element + + + + + +
    + +
    +

    element

    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/errors.html b/node_modules/selenium-webdriver/lib/test/data/errors.html new file mode 100644 index 0000000..78fb902 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/errors.html @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScroll.html b/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScroll.html new file mode 100644 index 0000000..ca65d1f --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScroll.html @@ -0,0 +1,13 @@ + + + + Fixed footer with no scrollbar + + +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScrollQuirksMode.html b/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScrollQuirksMode.html new file mode 100644 index 0000000..2593bf3 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScrollQuirksMode.html @@ -0,0 +1,12 @@ + + + Fixed footer with no scrollbar + + +
    +
    + Click me +
    +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/formPage.html b/node_modules/selenium-webdriver/lib/test/data/formPage.html new file mode 100644 index 0000000..7bcfea0 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/formPage.html @@ -0,0 +1,174 @@ + + + We Leave From Here + + + + +There should be a form here: + +
    + + + +
    + +
    + +
    + +
    + Here's a checkbox: + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + + Cheese
    + Peas
    + Cheese and peas
    + Not a sausage
    + Not another sausage + + + +

    I like cheese

    + + + Cumberland sausage +
    + +
    + + + + + + + + +
    + +
    + + + + + + + +
    + +
    + + + + + + + +
    + + +
    +
    + +
    + +
    + + +
    +

    + + + +

    +
    + +
    + + + +
    +

    + +

    +
    + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/formSelectionPage.html b/node_modules/selenium-webdriver/lib/test/data/formSelectionPage.html new file mode 100644 index 0000000..4890c08 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/formSelectionPage.html @@ -0,0 +1,46 @@ + + + + Testing Typing into body + + + + +

    Type Stuff

    + +
    +   +
    + +
    + +
    + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/form_handling_js_submit.html b/node_modules/selenium-webdriver/lib/test/data/form_handling_js_submit.html new file mode 100644 index 0000000..3023143 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/form_handling_js_submit.html @@ -0,0 +1,30 @@ + + + + + + Form with JS action + + +
    + +
    + +

    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/framePage3.html b/node_modules/selenium-webdriver/lib/test/data/framePage3.html new file mode 100644 index 0000000..3e62e45 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/framePage3.html @@ -0,0 +1,7 @@ + + + inner + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/frameScrollChild.html b/node_modules/selenium-webdriver/lib/test/data/frameScrollChild.html new file mode 100644 index 0000000..3eb3bf4 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/frameScrollChild.html @@ -0,0 +1,26 @@ + + + + Child frame + + +

    This is a scrolling frame test

    +
    + + + + + + + + + + + + + +
    First row
    Second row
    Third row
    Fourth row
    +
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/frameScrollPage.html b/node_modules/selenium-webdriver/lib/test/data/frameScrollPage.html new file mode 100644 index 0000000..b7fb8f2 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/frameScrollPage.html @@ -0,0 +1,14 @@ + + + + Welcome Page + + +
    + +
    +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/frameScrollParent.html b/node_modules/selenium-webdriver/lib/test/data/frameScrollParent.html new file mode 100644 index 0000000..8fccb6d --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/frameScrollParent.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876.html b/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876.html new file mode 100644 index 0000000..4ed597d --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876.html @@ -0,0 +1,9 @@ + + + +Test issue 4876 + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876_iframe.html b/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876_iframe.html new file mode 100644 index 0000000..57d47d8 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876_iframe.html @@ -0,0 +1,9 @@ + + + +
    + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame.html b/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame.html new file mode 100644 index 0000000..9c27e04 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame.html @@ -0,0 +1,29 @@ + + + Deleting frame: main page + + + + +
    + + +
    +
    + +
    + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe.html b/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe.html new file mode 100644 index 0000000..e4b9723 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe.html @@ -0,0 +1,8 @@ + + + Deleting frame: iframe + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe2.html b/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe2.html new file mode 100644 index 0000000..47764eb --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe2.html @@ -0,0 +1,7 @@ + + + Deleting frame: iframe 2 + + +
    Added back
    + diff --git a/node_modules/selenium-webdriver/lib/test/data/frameset.html b/node_modules/selenium-webdriver/lib/test/data/frameset.html new file mode 100644 index 0000000..039c5f2 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/frameset.html @@ -0,0 +1,14 @@ + + + Unique title + + + + + + + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/framesetPage2.html b/node_modules/selenium-webdriver/lib/test/data/framesetPage2.html new file mode 100644 index 0000000..4ea35ff --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/framesetPage2.html @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/framesetPage3.html b/node_modules/selenium-webdriver/lib/test/data/framesetPage3.html new file mode 100644 index 0000000..42a9300 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/framesetPage3.html @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/globalscope.html b/node_modules/selenium-webdriver/lib/test/data/globalscope.html new file mode 100644 index 0000000..e4ca97a --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/globalscope.html @@ -0,0 +1,15 @@ + + + + Global scope + + + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/hidden.html b/node_modules/selenium-webdriver/lib/test/data/hidden.html new file mode 100644 index 0000000..0e8097e --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/hidden.html @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/html5/blue.jpg b/node_modules/selenium-webdriver/lib/test/data/html5/blue.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8ea27c42faa7b5e56c43d3db317d5e4ecf1cb613 GIT binary patch literal 92 zcmZ?wbhEHbG-5DfXkcJaWSGJLB!991Nd^WT5CM{5U@~s$UwQg1|Kd4YZgp?Ix92y1 s+ar%@&pMaAI<@T`_wi3Y*T3~X|8?&BKYkvr_9KfvcKB$ivocr%04xP0fB*mh literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/html5/database.js b/node_modules/selenium-webdriver/lib/test/data/html5/database.js new file mode 100644 index 0000000..c6333be --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/html5/database.js @@ -0,0 +1,84 @@ +var database={}; +database.db={}; + +database.onError = function(tx, e) { + var log = document.createElement('div'); + log.setAttribute('name','error'); + log.setAttribute('style','background-color:red'); + log.innerText = e.message; + document.getElementById('logs').appendChild(log); +} + +database.onSuccess = function(tx, r) { + if (r.rows.length) { + var ol; + for (var i = 0; i < r.rows.length; i++) { + ol = document.createElement('ol'); + ol.innerHTML = r.rows.item(i).ID + ": " + r.rows.item(i).docname + " (" + r.rows.item(i).created + ")"; + document.getElementById('logs').appendChild(ol); + } + + } +} + +database.open=function(){ + database.db=openDatabase('HTML5', '1.0', 'Offline document storage', 100*1024); +} + +database.create=function(){ + database.db.transaction(function(tx) { + tx.executeSql("CREATE TABLE IF NOT EXISTS docs(ID INTEGER PRIMARY KEY ASC, docname TEXT, created TIMESTAMP DEFAULT CURRENT_TIMESTAMP)", + [], + database.onSuccess, + database.onError); + });} + +database.add = function(message) { + database.db.transaction(function(tx){ + tx.executeSql("INSERT INTO docs(docname) VALUES (?)", + [message], database.onSuccess, database.onError); + }); +} + +database.selectAll = function() { + database.db.transaction(function(tx) { + tx.executeSql("SELECT * FROM docs", [], database.onSuccess, + database.onError); + }); +} + +database.onDeleteAllSuccess = function(tx, r) { + var doc = document.documentElement; + var db_completed = document.createElement("div"); + db_completed.setAttribute("id", "db_completed"); + db_completed.innerText = "db operation completed"; + doc.appendChild(db_completed); +} + +database.deleteAll = function() { + database.db.transaction(function(tx) { + tx.executeSql("delete from docs", [], database.onDeleteAllSuccess, + database.onError); + }); +} + +var log = document.createElement('div'); +log.setAttribute('name','notice'); +log.setAttribute('style','background-color:yellow'); +log.innerText = typeof window.openDatabase == "function" ? "Web Database is supported." : "Web Database is not supported."; +document.getElementById('logs').appendChild(log); + +try { + database.open(); + database.create(); + database.add('Doc 1'); + database.add('Doc 2'); + database.selectAll(); + database.deleteAll(); +} catch(error) { + var log = document.createElement('div'); + log.setAttribute('name','critical'); + log.setAttribute('style','background-color:pink'); + log.innerText = error; + document.getElementById('logs').appendChild(log); +} diff --git a/node_modules/selenium-webdriver/lib/test/data/html5/geolocation.js b/node_modules/selenium-webdriver/lib/test/data/html5/geolocation.js new file mode 100644 index 0000000..f07af14 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/html5/geolocation.js @@ -0,0 +1,18 @@ +function success(position) { + var message = document.getElementById("status"); + message.innerHTML =""; + message.innerHTML += "

    Longitude: " + position.coords.longitude + "

    "; + message.innerHTML += "

    Latitude: " + position.coords.latitude + "

    "; + message.innerHTML += "

    Altitude: " + position.coords.altitude + "

    "; +} + +function error(msg) { + var message = document.getElementById("status"); + message.innerHTML = "Failed to get geolocation."; +} + +if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(success, error); +} else { + error('Geolocation is not supported.'); +} \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/html5/green.jpg b/node_modules/selenium-webdriver/lib/test/data/html5/green.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6a0d3bea4793a5fe3a3a36e29ba174540540513d GIT binary patch literal 92 zcmZ?wbhEHbG-5DfXkcJqT;s&Rz@Ye(1xPY5=zs{23bCU^SwR4 t`P&|OOncV3?A57l@3@bD^11%4_xZ1L-~aLRaJ3&<^s&Q7OP!U$8UQ`xB)R|q literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/html5/red.jpg b/node_modules/selenium-webdriver/lib/test/data/html5/red.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f296e271956d5d4e0939b9706e86b2c2bc0d65b7 GIT binary patch literal 92 zcmZ?wbhEHbG-5DfXkcLY$H2kBz@Ye(1xPY5=zs{23bCU^SwR4 t`P&|OOncV3?A57l@3@bD^11%4_xZ1L-~aLRaJ3&<^s&Q7OP!U$8URKdB+&o> literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/html5/status.html b/node_modules/selenium-webdriver/lib/test/data/html5/status.html new file mode 100644 index 0000000..394116a --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/html5/status.html @@ -0,0 +1 @@ +Online diff --git a/node_modules/selenium-webdriver/lib/test/data/html5/test.appcache b/node_modules/selenium-webdriver/lib/test/data/html5/test.appcache new file mode 100644 index 0000000..3bc4e00 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/html5/test.appcache @@ -0,0 +1,11 @@ +CACHE MANIFEST + +CACHE: +# Additional items to cache. +yellow.jpg +red.jpg +blue.jpg +green.jpg + +FALLBACK: +status.html offline.html diff --git a/node_modules/selenium-webdriver/lib/test/data/html5/yellow.jpg b/node_modules/selenium-webdriver/lib/test/data/html5/yellow.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7c609b371291aeb672feb6bc24497d5f64d20288 GIT binary patch literal 92 zcmZ?wbhEHbG-5DfXkcLYcZ>lD6o0aSC0GH&T#dHOB?;yGJxb#K16=Qn@b rBadm%I+wjVwe21E@lQV2zx6) + +HTML5 + + + +

    Geolocation Test

    +
    Location unknown
    + + +

    Web SQL Database Test

    +
    + + +

    Application Cache Test

    +
    +

    Current network status:

    + + + + + +
    + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/icon.gif b/node_modules/selenium-webdriver/lib/test/data/icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..bb994619275674a361f092333cbfa122209d6546 GIT binary patch literal 127 zcmZ?wbh9u|6k-r!Si}GX|AAob+W$d8|1~xLfB*iUgX2F?R0kvlQp3RPBO#^gd~AZ^ zsa&ybSCl~e@% literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/iframeAtBottom.html b/node_modules/selenium-webdriver/lib/test/data/iframeAtBottom.html new file mode 100644 index 0000000..a686ba3 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/iframeAtBottom.html @@ -0,0 +1,15 @@ + + + This page has iframes + + +

    This is the heading

    + +
    + diff --git a/node_modules/selenium-webdriver/lib/test/data/iframes.html b/node_modules/selenium-webdriver/lib/test/data/iframes.html new file mode 100644 index 0000000..e00b482 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/iframes.html @@ -0,0 +1,11 @@ + + + This page has iframes + + +

    This is the heading

    + +':"");a._keyEvent=false;return I},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='
    ', +o="";if(h||!j)o+=''+i[b]+"";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='"}u||(k+=o+(h||!(j&& +l)?" ":""));a.yearshtml="";if(h||!l)k+=''+c+"";else{g=this._get(a,"yearRange").split(":");var r=(new Date).getFullYear();i=function(s){s=s.match(/c[+-].*/)?c+parseInt(s.substring(1),10):s.match(/[+-].*/)?r+parseInt(s,10):parseInt(s,10);return isNaN(s)?r:s};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='";if(d.browser.mozilla)k+='";else{k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?" ":"")+o;k+="
    ";return k},_adjustInstDate:function(a,b,c){var e= +a.drawYear+(c=="Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&ba?a:b},_notifyChange:function(a){var b=this._get(a, +"onChangeMonthYear");if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a); +c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a, +"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker= +function(a){if(!this.length)return this;if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker, +[this[0]].concat(b));return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new K;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.10";window["DP_jQuery_"+y]=d})(jQuery); +;/* + * jQuery UI Progressbar 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("
    ").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); +this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100* +this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.10"})})(jQuery); +;/* + * jQuery UI Effects 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/ + */ +jQuery.effects||function(f,j){function n(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1], +16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return o.transparent;return o[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return n(b)}function p(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle, +a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function q(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d= +a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function m(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor", +"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=n(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var o={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0, +0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211, +211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},r=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b, +d){if(f.isFunction(b)){d=b;b=null}return this.queue("fx",function(){var e=f(this),g=e.attr("style")||" ",h=q(p.call(this)),l,v=e.attr("className");f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});l=q(p.call(this));e.attr("className",v);e.animate(u(h,l),a,b,function(){f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments)});h=f.queue(this);l=h.splice(h.length-1,1)[0]; +h.splice(1,0,l);f.dequeue(this)})};f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c, +a):f.effects.animateClass.apply(this,[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.10",save:function(c,a){for(var b=0;b
    ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent", +border:"none",margin:0,padding:0});c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c); +return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});return d.call(this,b)},_show:f.fn.show,show:function(c){if(m(c))return this._show.apply(this,arguments); +else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(m(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(m(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c), +b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c, +a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c, +a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a== +e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h
    ").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+ +e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); +;/* + * jQuery UI Effects Fade 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fade + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Fold 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fold + * + * Depends: + * jquery.effects.core.js + */ +(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1], +10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery); +;/* + * jQuery UI Effects Highlight 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Highlight + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&& +this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Pulsate 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Pulsate + * + * Depends: + * jquery.effects.core.js + */ +(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments); +b.dequeue()})})}})(jQuery); +; \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.inline.min.css b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.inline.min.css new file mode 100644 index 0000000..9f194f6 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.inline.min.css @@ -0,0 +1 @@ +.mce-object{border:1px dotted #3A3A3A;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0px}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp{background:#AAA}hr{cursor:default}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td.mce-item-selected,th.mce-item-selected{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333} \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.min.css b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.min.css new file mode 100644 index 0000000..ea08c68 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.min.css @@ -0,0 +1 @@ +body{background-color:#FFFFFF;color:#000000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px;scrollbar-3dlight-color:#F0F0EE;scrollbar-arrow-color:#676662;scrollbar-base-color:#F0F0EE;scrollbar-darkshadow-color:#DDDDDD;scrollbar-face-color:#E0E0DD;scrollbar-highlight-color:#F0F0EE;scrollbar-shadow-color:#F0F0EE;scrollbar-track-color:#F5F5F5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px}.mce-object{border:1px dotted #3A3A3A;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0px}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp{background:#AAA}hr{cursor:default}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td.mce-item-selected,th.mce-item-selected{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333} \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/readme.md b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/readme.md new file mode 100644 index 0000000..fa5d639 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/readme.md @@ -0,0 +1 @@ +Icons are generated and provided by the http://icomoon.io service. diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.dev.svg b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.dev.svg new file mode 100644 index 0000000..578b869 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.dev.svg @@ -0,0 +1,175 @@ + + + + +This is a custom SVG font generated by IcoMoon. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.eot b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.eot new file mode 100644 index 0000000000000000000000000000000000000000..60e2d2e5c747caf9d41310976af96c75c696b448 GIT binary patch literal 10316 zcmd5?U2GiJb-s80_iuKWyR$<|i^wk26^Xemt$M6rkdH=-X_ zc2hfUn@JD@L0c3`fwZn+6!X$TeJRuwZ4Vb8MX*7Hq~O^r8=LG0(H0twqkQSbjaN32 zmr#BUx$)xV*I(Fp`X?t)4jF6Sdg=L%=eBPB+fNvqqF1lJgbMk`(iqAwp*;1{l~-ST znP;8=`FkjLFJF6h;}@5H{vl)2G_31aHeTCgXZQmscTsk(Zd`f(ZR_|&#%56D*EX-c z@+#!S<&qo@lO@J)Fcr_v^A}L_Xg~jmjj?Z0yP=Ci?46en5!$@Fg+JZ}H?SFMKxHNt zl-^jyd+BMFDeMe#lNorXq0Z^fc9*;Dt^eD?JmGS>tUK3T5oNyhQ%7-RN9y+$4f;3E zIC>O^-U;RD92FvL%dvNz!W;hN~?WD zUhIgC-(x2tCo7A*-W6cU!l0lxA%H=cg3YENMT|@`lDaSF%}y zKWJpL3JQ3;VoQ?Dr7v@?$?EBR?>$tf*L(aMee%Uq3PeSLy7#`(@2(knjhD5OX(}~I zRu!3lN#@Gw-jDjdzMkY?=UalHabdN#y3olk#z$+>#<1LutIx{|yrr8MqHddVky|zf zrrVvmJjuPzn%uEF?wb4{clDOr?s&E(v30H}s=RW_;a@9Yw0!b9U{t1sG zUtHh+l-+i5H4-iiI`1$CdPXRr11*Y-RT`G~Yxi@9$30&pr`P3_LO=8)B+Sbm{X4t+ z2b^tTQy^_K_%!_^@$#Jl?9u;j`O|T1zaH|RW>x+!zr~KRrvS2lgtaAw?JTbG85fGn z>wL-9XG}>qrJ7ymYaFZUc5JOK*>!2Pv&QGKxKIF7ZZ)CU^GOR2s*UGWtAon+%9=zK zR@IbRP?Myg>^`ugt)}x^nTlm)onR!djYiR^mLCb6tYuX)W=YQG@{`S`naLY6cN{Jo z`Hb0YPUdr2xnyo}So5;Ic#zSf*VR; zfZu(^>D*mq-(AJu9d{xpL>kx4jHYEw{WT)|0Yyab!%K>$%Cf2{1L7Gcoq+-ICxeFr zf`hjcQX)R@r|)>@os<$)m>f(|%8&B+6DyboY$Ys;`dH*(rO$2S5uuVywvS97%@M6N znYg_x;sI&^Il|qV_eo_Q`2qg;z|N&Q5T!(#-&Fx@@v-t<=xlurFwp)oxKrM7q zjU=IVhsdze_!k%CNW}Tuv$Vux^|KDH2ws@jA2fH{I6jiR&Bm+|66#20TNhv+rBf0S ztZ!}(@R+mp^*wme3Z$sYbzAUCStUl|E?yG$tuN%7W{*LlRGFdOCpf{Pg;gZ@Ts_8D z;nnnY{oaqmYHMGyxUW^EyuR|tths-*mL;$Q$|$nL*(Wu~m&T_pYkIsyxq0wh$2kTc zCx_kyPkTPZQnDks1z1lLR)Tm$z-bJ!A5kP1eHZ&dr-=PnAb4gqsMc+wK&IT z+HgG54>?lO5EWw@0%9O%f1Y*6m*_C&xqOq~Nhpn~I7Lcz=c%S3D#sTPTWgul^ut7d~dnQ z4YlB4^luf!2+9Z=4A(WR&b3I;o;_5% zy9Q!(X>u<<4o}Jt_GmfiOZv0O0)CqZiT-rxtZ!EkoUl8$g8&Y2fZ9~G;> z_&@W%VtK@EI_x~#fcDu41h{Z=rYY>vLF7Q5(Pp#-oL|-?dzEmF&WZp@*TqRw3_KaJ zUe*#|LqLH}kFI+lGdk{+iHoat2h%?qxTQkh+JxYMbc$NUKClE zzPMk)(N5ti9&GVR?@{-_!|e&qC)y7ma3A$1dG9az=uCTJ(wnVuUYqqMC)zWkuwx4J zm3+b9WpnI7_IdUltUe}Y4StDOX}gV?NgNIG2yt|VYnV71n6s8RJ*PO29@fxFTCnMu z!Z}Hg11{zo|KQ{pl}a^NZq3Y8Dl;>!a;{pb7+RrVYSp=ehikRN2j{AqStw}T=EGj$z-zX@zW#Cg^7uU=17_cDJZ1*B_oHUvYs;X*<(-9voJbM?-ew7j&q zT<7+Z-Qtg^dbV72ish`Xo;f;xef;Q|uT*e~N64@bGDAe4?Oi$7$Olb ztRqH~@Itg>z)Rno7k|CatdsJhd108B7#0ta%>;SG>6#GO0=~2x^7krX1y_0xx0o2nhu!qU^h5~yDOZ^lrx@F z?Z%vK&oyi{H||VT_}hEDWAN6Q;WyEnqZ9z{mw#K&mvgn5{iV|WnOd%#*9GP}Slb9x z13UhBqWNu=+#0yk^nn11PM8Vb9IlN_?m&l}^I@nBh06Qe4vh~LPo)Ur_(fSaRMpVs zG)JJq7n385b+Aotu`s+n+>&}Ewjt3$jTP|CV?X3{5vjw5=-6#+4GX)YjZLCM8{N*G zz`upaoVX8>Km@8Esu3h~N*n074ePT2&+b>CS%@H#o{M>~DTLoabgu2G-cU%#C$HMWkGa_MTBYsHwojTbq?TnSU@iVRgc7ibSf<{ zrLHe7&U%mpUQtqXq9_P3ML-m%j{`}(stitJKGO!M{)Pv@W;88$x;E)gwm3+sEk$N%VJdb)I;W?s=VtgD? zE{Z$C@p62p>x3bwFo?u=i2yCb2sN?eU;vEigK-!v9YcdnLvp(T6Nkjz2ENBof;3_r zLpguT=*33K;LIrXZX4VOy#@M=5G6?OJdWcC5=2oLcJb!qqW4Q%cW6O?U&|t5M7|1b zs5bNkXq9@h=z?zECOXI&S%iNpc5JlP%>l(w8?kFKF)Z z^K;M&9;Ya=xU*&2H&e663SoHQk(G(qj{?Xi<80*MY!tx?&0$Ru%MwBzj)fo1m|1P4e!$+mVIQcE(3ua2!I`wkpeB$rf}DA*oz)VbJ3ZKAk4I<1GhIqN zg334!_Z^z@pg%4J8k<<~%1(oEg2RnWBE}#C3SM?)70_iC=?no!3I*9uonz8U9>iKM z2cHcOMAK{zUryuw^Av`h-ycIX=o{_5h&_Y3Y>@}sk4BKq@`jyS;o2|OmTOBbtC6_$ z!j!dyuS&C@Du{>g*KcC&MhoS7tx%}d%jQ0-s2t&X&dg-3(S3!&zELZiEzt+vQWi0% zH#y5eU-oQ@FFeW%T|KMInPN4Us}?f|e`Ye3a#2ftO1*+*%GIn9gL6mDnnmOO&EP}l zHOxHC!8+!E)~X8RPR+4}<0bvITQMmKsSE9POcjw-718++SVTM|F^{p}0srV8TyTo& z?qC!n;CvUaUYOt+o#B#osgl2S4}Pj{M?3g&iiY3C5b#U#3BN?_>nyNx1lZWbz*}vX zKD9U6u4RL!B!IUpzWETzfv<7Qoxt;A&jV6n{9V8Zlol2u=mv*9FZ8@ZfHu9*kAsNe zJ8Z~&%xAz7EH1)>wqX?~fyOR72n*)nbO~!tXiV5EupT)f8qq1TrS)kY)u)Mv4&YQ= zBEu~fCEP#{{&|23x&m>J#C`jQsbO@s%U}=0n59Yf2>TMv46JnnfxAWpdtl%`jw33q z+xRFh%xS7Ar1=OMFC&UA;?wTX782meZ{IH6a(Mi}p;FIxzE^FG7Od&z@$uzp3+K@C zDST3w(z6%kdLf_JI!Z2|SMXh3)xKM(QN)F|Qj!BX5T58FEZ()v7Ceo#{O~rHcskEzICVnD+r28Cyzxx`mGIZ;KcF?PShp6@ZDtlqSv6SgX9y7 zK27B`ogSj84W;xMOK z{HyW5nQv#$Wq&*S!|XrhjNE+g^SO8O59R+b|M!K}!jpw}3m=>3&B*+|`QOE_7T+qy z#ScpL(pO9WQ+^U}q=`JjkI`>7a6y#2E|dL*Xhm&trtQ;ocKo$IEu((1Pb;9m-ltXk z@N8e7CXf7FpU&b;_Q${^u4GU{JQF(Mna~N(gid%Sbiy;CHT3;rzi-0x{y&Sm_YdIi z+y2#;ufBfe+2;?xa%JQ4 + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.ttf b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.ttf new file mode 100644 index 0000000000000000000000000000000000000000..afc6ec458b5c032f104c12318ff721d31d9dab8e GIT binary patch literal 10128 zcmd5?U2GiJb-s80_iuKWyR$<|i^wk6wXXemexM6rkdH=-X_ zc2g^E>q*c6L0c3`fh4YB6!X$TeJRuwMH9d%#xF%43RKBM;r5}~B0%A`2r3wLP!#U6 z-?_81T#*tDBQKuioqO(`d(WJE@44SO_Y4_ljOAF!WVZDA3yUj8^OygLnsK5`6%C93gUb=Ms#m#4ab`s@~vF5FpU)X$p`_{kyjIpUDJYRbm z74lD|F_d3MdFtiMuf6^X&pZk84^Zx2y87JaFE9S$L&l~rp?vM~=IdMREPnvyF3Qf8 z&C4&mZJoHl*bIvN>ekg)UxS>uT$00Kvc&iersCNX{6*9}+Rr~?W9)aS-O$A$_T85c z5!$@FjUVrV8`umrpfY0;61}mCJ3Xy3g`GuiG6T;v)H&VR?n<}4{eRn-CtOaKb?3XQ zqRh8{?kJAzNd4ZTLI1`XM~~vrJMpg0F(JZ^9Q)TP%z@Bd9z(7%Hp|Xo=E`oPX-ZbP zT9>@W%DU8+J*(BOwAx4IWe>^nTJ6;Z=@3V&3EnDu7FwR*XnB&`7VmEL-ZzRlP0JMx zzC~2*IDQ=aj+)8ov7XDQjvyl<{aHS{MNNA*2A!S?f?gbkAw8!)A@_rn{^F^RX!tVo zA$JV9>+CRl2(-H(>#ix=a$UBkYwJ=+UR#h{9VNH3QkRzPiaJx9sks$#w{=@bX~yP% zep)fjlJ*lVZ)luzC7U()gGM&1pn$h4wj{}1`U>Zote(mD-a~bIy~n@NCto_PKvWc{ zd+!_l?wXO;cv&l%rc#q+Rgw9ZWv-m*{iNUP%_M)5ZwrFPh1J^bLMOWzAFV|j!*V;W zz9291mTqE*x^2ouZrK=^Zg=YPB=wqt>+*x#)mv`6);bs{CDkiydcA zvsc;ov9_eJouzd?<3e$HoiE$^j4A1+RI}@Ronuwqj;+-tyDqJD*7*V!7Ybm?ttJ$E zA!*@3weh@abx_$}U6-iBs+v*@YLYaR-3RV!tLgk!reaxHCm6|Vqfs=fe79MUrL1P%>0hRYj5|>GSDE zP4lc5+5(itQ zP%0UUj#qHVp=ql0IDtnh2jyRvsHLhaijm1c1WlvOjWOwpQ7RP_##DiagexjTZVHX9w%!I>^0udUT0l+D;sK^i-XKwYl3_!}EKt=}90W1; zM;vqJd43Q=>BU1Q71^O?+l)G(Y3MkC6AnS>swm`Jmzd;V;^3$0x7C;-4?u3R*8|=!%M=x^@Uv1>~Tnx zDl@eEBqvz3u!;nqYsdK-yqdnQ-}`Y`Z5=2U545V3*H<5zH4l!~vIKTO8AX;j`=kc> z()hGxO^=r-HxE75agM{s$)PvF)4mU}l)j6O$$c>awpSyYU zsTU{RH8%a^sd?$@&6}6ylh3{ZuNQqI+VjY^QWGie&CH~Pr^l&1@_%W-?Qvb*?Zsv=YzDr$W30YP4W(`&g$BO95!oZ z`8X_=2SZiW=BTXB)=Sh2no5P}S)c)#4@x8Z`p&w;a(Q7#y` zcvE;)7YOq?(rGGQ5G1UH)Rd^b3a6;w{@qW}9+nKMpee)eOzZgbl8jZBaYd4D=#rpd zWS}^gPp7Re7?x!jkb)YLSR~+pgzR@W{81AkqYYBOEs+?9C=EB?8P(3ac4kKEP$wZ) zL~w!-kRUV&tba1ELrG zO5HyL8vUE3(f(kkB@}7&NgDECpn`~~DxCw$fBvg<2Hr|6#O?^OXH=YOSf$*t%Z-Yw zm%TC$u-mK)$Bj%@h$g-71_6J(_t)qqur~2QM%gNz^!TnbcbPnoGTcfW4s>KhHYj&@ zdm>;Qrp^H$P{GDlz{Aiel(X4#!ANr+ktfoN2OWH(dQs%xxWoNkd}p{Zb%LxJ;6f_v z1Zy%EC+=mo#!kRHzPH@uhFWki`nL*V1Z4ybhU*$u=iY+%;=~E*#&M8P+w8{u#P)GI zq(7YXAbeVigT5^zEK^v8!7_HpCr(OJk)>2Djq$?BUwp8i>)Q$-VG7cv60_Ps>4H(w`+3@Y_5{^ru5-eY=9-gx$Fv z1aN>OM`Ys0nJAF{s8|KY|B3$<%Oh^nVNbA4XrGNhfD0#Qn!+9(L=NN`ZAM$f`DItO$^FU7R$^W{Wi0_V1Qh7>=(=;6(Q&6-wA|K2p3fJ{&iH6%EIm z=jYO$)RAEd0XK@YH2cVEo!q4~udlkc?NVKm^Rr{-xK&XWjp~F`xwNQMtZ{R!;!ISH z-rr**a;f!INtY3MQDj~E(m@GFJB6!wu+1mEN8P!H+Y_8mv>%>xAN3}A?=Si2OnYL| zo2_wPoAo9q+B2iDV+!<@e8Jym^Xx(P1@;}RJ|<=zeu-FVyN#Ji91Zdaadd`jm^d1k zvz9nLr#O!u*3d~>u<4k>IZ2NLF6J74;N%#UN;Ow*&CFCPGc&Dnu3D)WTA^TS)%in5 zYPBPW=Bt`nC}`d0sbkBP%JQ*O%^hm@5#dtdz`=3T96xxVkR2H*>3V5oB#SevN+)QZ zx~H5D-Bh{L=Htvrv8ZK>SyjbND;7sGC)8{vqvXqZO~XyeWU}gsGb7E#iHXJLNSX&J zD5UvCBZs51o-po=?n?{yQ3hrNggfCmRhcOO?kH%DL(2<%O4Qx-%22<1hT zOYr1$N)x!`@H+yR3hV$hlg>K4CASb?ZCJ1zKmY{uC_d?k7*=rQ;zJj=xbx(xQK^}3sCIq$s zEgp8}a1aZ})wbT^!T4gc(mHv5Vd4DAR;9T(9yn2D($3p+Ym<{}b08)wz)8Q7n>w;O zk)qGU>XE5jWohebwmyA$v~m3K*x2FYjnTu?_3YKHCCpP2>mhk&VaYDAm)UPaz62u( z1jv~L4ge}hCc=+4km9aLz_PyE8hg7d#EGSkE?~%6WvWp(3sqCs&1%7{H>N6kYiOY9 zfGH1lgTtNxgHxGu#&fFOn78fuhOOqtov8|cd!Kg<-a0eJ(9Z|nJTt~PV9 zR600Q%a!xGz+4Aw8-Z$I$Dc?vzpav619zG}5J1rhGvS-VwUNmk=#XD z@uA|W6hR!nBdkwLR4v3MqP+4;QJWil9?EQHQYQC=lh+#uK}bcLh)r@W1uw+}3T#(Tf~X5HVAZ zkBc)2W5^C24-RL?|9H%oJ2SJGWTuRG==n{(v)dX%5#z*TM z!0)htUIeNhi3RCYT3||DUtFB^APKypr07IZ5MYXcC{7;-l6X}aoW_9KEjGs%n8%K> zlk5~)5LYDf+&VT1Ms>^K+zWBOnm2201#VAGJ? zZotGLakqi*F_a*U7{^e~-!gi!Q8G9)O1;|#_d#!iJ}X2C(mRjiID!OG6oy^AIl1Wl z()Jx%5a8E}h!~NtLK~_LeF0jfo-BDca85kk^#EbQ4qDtv5oV-0Igu|^3c8M4eqxf` z0n}tm`Hb|Ht*!H#d*X?CXa$c`lvujEW!g7Wv&RZyIQPivMC?ZaAtGTFHZ0%jMv+;elwH&Ed;wd~kunkP8Q6hz5P5y%(`(F_$g!VEfSsvRU4+ zQ!8BirP@kuxn(sHmtL5%mhe?+_EQD%@csH*Si8|exn3(2YW1>tz$z+7xt=pKS!?t_ zp>SZ-%4SRSLAR7e%;{U4<)AP7HpLen<;AX^)#XgFn#)y-8H7JGnM%2+r9P!z!7}A) z)`-EmBWKN`asOuUq4OGMp5|Z!b3kiV1#+k6*uwFWe(hFFNbo2ct&TqWL>J{Z{35Rs@u_B{5VC!_b>$fl6=B1 z5&Jp|tQ-M0HZky4+oezKjkasqpeYI9EsJkHL~`J39CIh|yx8-AR2Y93Fao88g$TOA z5zh-fuMnV3FZAOeV)zalG9U99ump>X@Sts2#Yv#C%MQVUc{p9dniCom_6n>=PKZWy zifn0pT1WM1;-LdL6_?0xi$w`H(1Sl7pn|SI+#_+{xnXJ;o$WH%12JZ4l0Cw{Ofv&( z-9X^3QNbPzKXACz^PL}5 z8>0nldS!fkW!l0yw0s($)TQ+7MY&$c=e3TK%jXq*S68*~7HSl6p{m)4vIv*1$+s^7)){XqXdmq&X1!0iQgEtyzV&T!)YG z3EwCi<-MOM$pM2EC9?#pi4u(I{XbShtzsW1o|yaHZd@ukqZ^}6skGlGOAaeaO9|}j z#?V13_>i9`>FTlnn181Dz(*`6p@Ol0*tm_8dXjJ7>Hil5MWvI+q96UQ4Q=4W@(E7V zCB5+7WapySpsR!A6N^4go=7T z5D=Ksru4tn|JhhFe$V(9<9{>X&OVm?o$QaZ|Clp!3%M`k-pN0d|6cy@3TuU@3hx#^ zHlHvf^M~et7r$0~s~8tQDAh|}EB#OTDZG&;@+dz}|FeM$qU^a$_7|cRwZ)mXPt)1) z*ZZ`L`lUXtfPS-2tE`3+y@7n^0=~m0bQWi_KL#doC4(B`na~N(gid%Sbiy;C6P^jJ zq3@UaeG{Iqu~*m?cAZ^j&#@QS5&SR4WwyyK;rB(9uc7=3yNVVLVw?+*`M&L6d*#aY z%g?=V@3u!&YL;Df#cLw_Cja}f0^KJi}_ Kf?+iKUjGk9se#1+ literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.woff b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.woff new file mode 100644 index 0000000000000000000000000000000000000000..fa72c74b45ba3725a6ff7d8d0901c538467c64e2 GIT binary patch literal 7848 zcmeHMdwf$>oU`L(I}xEJxM+1g4pdMw3}~}JN5NL8w5Fw{q_m|E z8k(j}e|@BBTKb?5Yk9_^bt(u>!4KslxpUZCddu|e1 zP#D+!cW-je{hi0}dtSfCIp-EFU%Ys^)w-Oqd-t;G49~skOefx7e-KX0=gW2!}+crC=Dgz5E6r_&ki*&9o8*JaM$oSTu8!*nqyc_egq zOz5uI(D(KCPG@(dP7p=kGj1rgg?u49zXu2xZWi&MZ$Zp%M0DpZx3Y%?zk%Jw?qNS* zKV%8)0hWk?C9}ub6KpA4&a5nrt!3+27RzM?tcaB{2XirE9@fe_SuY!4``7{Y3-%Tp zVaM4?c8dKY`-Gjwp#P2ift|<1|C#-_E>fpQQ##CyhMSQDDV;mUZTKD6nKdOFHztn3OucoNdhlP;3WyXB!QPC@R9^x zlE6z6cu4{(NkAnDs3ZZEB%qQ6)I8C(c>-#lfSM;z=FMj;M(4&_ED%eiXE#97XEML; zLERDE`IuQTKaXjO&DQJm|H3o)=rlfU@wB(5jo%v`12`6eUSD@&L)GD2ltwJ4y)b#7n5WoJu4Vi=r_7OMZ+3fY8f&EwpXBZ830Vb;)@PC^G`0Wem|`SSebHh=$fx{NrqjtS zyr#3d!`UGn3#5)(R`GIgd2?BlRCPL;s*-tGO?h>>Q?eXOO+9AeP9$o|q~t0}K3&C| z%9>GGT4fnc4IJZusP3$hT9Qvw%W2-()Y07Gl>)0qM^^>77m21$>2wQM%`LLUVj)X_ z0(d9@k{kRXqa4DNTP|TL(bXvl#VjksC{c&QC6^P|VG0T+pJ4Jun4*d6Fe&Em(iDN| zn|p2ur6_+T+xv6d@@plVKN!T!2LhIWq?*M~F>{LrqbDh7ve|fkV{WD0o|);g?zj1K zj(diN`up4V)$W%3e!q>^=C|ec+lMlbyZrn2`(4K~ha|P-dD*?Ky29b8tSoa@kc*u4 z)gDJ%!>-=mwzdv$J2jKH&QtBJCI`8s-+m%PL?MIJ-O+)FIv}o8QeF<}Qyx?ea<$7@ z=b{QK^H#PwTC3aLJIF(=-eym;x4xO$sl(Y;*;~}G$x$g8lncr*M2C~l>D^9JGLb*3 z3zkViwj~qaPEIFnhgv}HwtJmEG^U4YK%s&`QmiK8&^@CZ5!nD%OM4`;Sp=xXB$FSN z$tHA6@u_=cI(n2=ujYX>vI#({5!z-~?2v3Dv}y(Vl_ylw4{p^AJ`k!=t94ag9`Pb7 zEu|uKE{9W5S7|RgH-mUDb#+m%M9SO%c;|j&5g2+)yNaN={i;u%L)<}CUh^GAP#2RCO>-QH?1y zRQ-Y+wjp7=6Sh;AO_cdN7Jkd-ZHh&vF&mb_Y>BP_QZ`IyfhCs~;w@HJq_uZ2T$9tl zRfa$@!xCK9ccE#Q6VRY5jD$~C^vS9|`6>iqN-pzU0U$~)>ut!Y_+)ScgBuj1(kH(| z2iH(4rKYc0Nh>M+FpWyo!Aap~zqkm~`ZRx$vdcE*xm>R5nrcryepo^ueJ4Js6UqC| zzpfb7RW3+ltoo>;{YceurJ{LAU8c@b%}~2x~M8bCv|w*+5~ss%XDB1eCP^w znVg+n@8%7cdED+Ohz21*&@H#tl4!A^A=-ST18%9IZg9|D&mC>$9jn*+s5~+9s&wjutO`Fzl_jWe0hy zpqSgLoSGHpwKXoci~fJcFk?!bdQ)W1BujvY=Pf*AQozE)vlf{z)6e9vF_S0&Cm;-3 z*qBLh=CnO*(1bg+TxIoO;IFWH>IJ1p_K?TjSTos(vuYbTTP8cv*yL$|dIjH;uWsb( zPH2lNU){*noq&ditTJ7K;}JhNhmcil6coEUA)A6G6DgkypQC;bk0K22CF7)1Q^%sa zvk-El+d2ig;k_WKFumF%nG|!f1^drgCe?Y_uZf!BV!gw8RlAc9__tE_MbRXS!cK$`WNN3L? zx;X#reeetFzskvCYkQhb2Lg!1_BNT4EtX^qz^{1Z{()V6dv?CH>uASO!ms?TO?$TP z+R|Sj(Yt(W$JQMsZ7cV$=)#Q9iqe%iC6!yZZ7r8*1!VIh><%7DTm9J4$39IvN9X9% zk)yv^{hLQd=Ac>ZlC+)N*LQf5!sf`?MH?KMlt~*}vwJsn+Ix!zdI$P@cXfK3nwz|h zu5GmyR8A`oroTgQdk5(qxVqYQ*A8!ObB(uVS6P2iZ$VLky=YSz7U8$b7jnh0+q0e| z8}W5i=c-62?U5F#&J(mJs7#|hrW3SCaq;+v<(`kYXJ@-x)M#(;Y?X+5mi&amZW_8G zT(ELM?E2yC?J@<#A;kifgcR9ijneWUz))FH5KdxmholLqAjHWe2f-y$9NvC1L4F{H zi?})rk3XfFWwHn>fV8d1_8b~7S3=$EzY8XIasUsO9qE7>ej3Ma!TsSQpQN5CM0pDR{a1C7;&c5RrY zF$@BG0%4FsR$-7r=1ZFE$2|&MHQ`zYyA{-#iUK)^wqWu{DMRQ1>@QkWD=uSN6l)i? z;I!`pY3@QhCoWm#D)_B2s#49RR0Z|-fi#v9Uo_cY3=h4F4D>n_&ID*n=u$+t5)w3B zdYd1iL*1_q4!+ubh>p;al0(_AzBKrJ_jB|dJzw%t_NIcZw(2bD_b>pkJ$l9X8SySf z_xm#n$4(0Z6SlSCWx+arpp?t6^mOhaKb=TBvJ3}bn88a%Wft-GY2*l|;y;R+ju9V~v%uMWArh=Z0WFJJs26CnVO=E{?k@#Jkj4R=%yQVoQ~s?6jq&ti61P zvy-}TmbY3UvZ#>~ct&%}C+JtH7ZHm#)>chO$j_xiwFG(`TAR=YGx zyk?;675mPDp6s?P%A)Mbg5vz5(v6fuxm_D~Z>g`Vr}{bxAY{Wz^S#^qim8xtUo2P) zw`=Qm^h>G4n+iHN_ir629;`e-2WYTupl5e)*IwFBJ6+w5PU(+gEa4;eGD=IMWwdN0 z?S0rqRp^FxrKpZ+6rup8MW`1h>swY%)5bF_lnDi!DmgH&B+~*Gnz_Xr5w)x<+umiF-0{lIQxAI9Z!zT-KKQVZ3b? z7z@4}KH(5`DR$TlKdi`N;;VWxN9bMpkajMVpFGZeot~Yr zsqds8)b1A2alxQ%zPf3rr_(1L$LY4bw{Azf)Y!<|chvQkw@K>X9F(&uZx0R9;GR8* zXipwxQ+8fnws3F%=j*s(u_Pu~C#!G*+9L&Edc%}_%arQuUR@4KYsss z()j#||C*RUK0}&~|7hH-rF9d(i`U1;#>YgswF;3)$8_MhSwjVK_1_)*;`y5&y~u77 zO)~b;ihpR1z9+t#7{^G*kru6nAMl92<7)|<_)5eYQlwCOEtr}RokyK`gvSL$gcj*& zNSQ*5IwC~N#2X)ESl^Vq$|GN9wMKyaj$d zLS^I~&)5p|N*kpCALGOj#Vp`^XM~QyI&F&3vB;krq4l7*MQF}$M=H!a4PTm;M(FA6 ze%2w@O@AYD1ZJ2HV}|K4W|$6RhUqY7n4SjSRT17Wrk!Q8jjRM87T2*%Hk)k*mBDiG zTZwc5(%CEzHRAC}@vf_Uv}>>0prV1;NP1Mt^`V@ptPqt=BC)XHS*(S;Y# U(RlV0x|+w9A&8D)G}nFp2i)urJpcdz literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.dev.svg b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.dev.svg new file mode 100644 index 0000000..c87b8cd --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.dev.svg @@ -0,0 +1,153 @@ + + + + +This is a custom SVG font generated by IcoMoon. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.eot b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.eot new file mode 100644 index 0000000000000000000000000000000000000000..c1085bfd295abcf940871c863165656df8b094c2 GIT binary patch literal 10024 zcmb_idyE~|SwCmqckcT+`@B2%UhmGX?d*DY_WJq}Z^o7FP$zcQ&Z`O}8OL@WPMj=> zX&ludQze2_M97p%L@J=0qE;YOND)O<70MvspZ)=+f~u-oxQHUC5Wzf(3Ke(xeP?Fw z-re;hshE4uobSB8^PO|P^F7X)S%!*Ks2}Pel`qITSm)F=w*|!**HjuWTKXdW?J@r56Aw7#e_OHG0(k0M|XXYH0Gg)H% zDpOH*F9#Lu?l}Gd8)a`$y`hJL?9GqISg*}{>-g~=umR0b1xhoqaMWW3{ZeU#Da=Eh zVFt<+y7?zod=56 zdl-8UV>dw))h;)RZne>Nts)Qmp2WP+^TK{$b9;K6_xg+@9R&S=2i@*? z|FfXartt$;o$Y4#0+%x{JNisc(#u+1>ZmKSQ>L6fwMuPKcWQfTd!~3-JH)W4>38I^Ocn+2W!v|ccEB;-^|uSwD=F3Hld z3YR6h|4VqGMB)nnH<`=)XOX~j%W7x z5~>oW-;K}_!T>?$QvWY8`VH_4X~xs-p1K+Z1;_@qFb& zHrs;Lh_Eo)0W>%sVl{Q_<~%DiR&G=Wzjh3v5;(x?hZG1F>Cm&i!0RFa%}sGxF%D-K zm!BZ>Z-ni`;Sxj?U&q+%>}~ef;Dvd4 z7k4@*UpXO?FO!BA5f{Z;FdW@$Ab;D4AZ z)ykP{kx~fP9(8-D>$uh7>Tot%wN!O?sU6mzGR%u(}L65JdvMI$5GR+;$ zOc;tNuoYzHcT6|4YD$$UVb(@Q(~U-Ybfjid0~rO`=JbyI5n0z%S?oJ5p-WlTbzPP< zO#`&4M3J?me4}8bvwnDvrk@h5g@U3+MT@Z>YY}#Rcusw7gHy%sj0N? z>FJcZCTpMoSyy|$-}5}5vvq7@*Y*4^w28M$K+LRt52Z+eHkng%Qn5?d25=2&`PK zfR#Jjv#jk|b{KLNhVM-TK`^1`Qks^^>2DL@4Il#g-?*ZP)zg##@PwVr#Q^x)pl|^2 zo^9K}9s~lK_g(_=5rQyFn5zUM#l72R49%ayQZT<-Y#-)ONZU3Epy(xIVrYwt zd7+7_-Zo<({)7lLizC_WNYVVDF{$?d)CfOV;6ATGFDS|_c z(JoiX%;*4etKjRlOAx{)`oVLy=Yv-f=;4h1e&E~v{~onJT1R-fi#oQAu4zuU>91Ne zr-{~~snrncNb@7@tJ5?-A%~~UfdF#;W`NGuXSXxpPMS|>wJhpFJgO%!YmNi!| zQCyfmeW>MWnNnI(6^Pkel|fVq`|nlW11~d`^q*dJI@P^(uIc>MYI*#j2g2~&i!gj_ z=aG|3(raOOMLO~Fr}kqGID0*|9nqGzExkRH<27rZuW*ZFpFi->c)8kkS}&gC=dOg| zYtqumN1XkidiewW?B$sJUM7OgFz$~+201yr5lk+MdyG~?)H=+w9ndb~3a>>G{i64l;74s+Jg2hE9) zE^Jjp`E|%&c>_8LmBx{A3VH(CL4%Z9Bo#r*N8~9`ehP1>nM_7A^0};bDw9rU7PV|H zZ|EYOPD@6r@uTfoKOX7;)PPC@#_|S~gD#VyZ$aLvguF!}8EP=f6WY9?K&cVs*VsGk^X#|S7ulECm&M9&EU}|) zT4HIbQ(J=lgf%9gBw`9$wN6d2K(fYh;np>__HJ5Zsj1I2$-*17r$ts_)pe|@t|O=x zIRRCj((nIxi?MxC|KHZR|CV3#+qNA-wf_RZ2chSD{}-`*U_D*cq|=f@W|a)HYDv;m zU50t5D625C$kvjYGVB_%aZL4edUCR!UV;&YA_dWDb9{Wlw0UZK-X{EH3PCV^F#I2R z+&c4d{y2V9{4-~&k5>Tw9bl57KK6eX`(K5}!pg;tRcv5o;K=&jZa?I95Wu>D$J*_} zia&wWFZVB!?T!cbRu@nTK5L8GLOlr=c$?a_8fB}4>hOAceUFEMktLm)HImrx2Y%r3 zZr?`;xZm&c!f-j&yUtm64|SVDum^qT;AM?KOE#IqcE(hcNh=D~C|-gncXM8&8WH3R z#prPx#vF?i{azr*2>M-k>EchOUO!AykzT_b#Cu6*C3cXV!XAQBCOtF>uO(8>PNaj# zY#aD15S;KnAQ9V(!%B%%Ru5f}4e7(G4E^ftbTgl~@`iy|zBxTx-Ja8a^w{j|u}9lU zjA^vV0`)y|wN`J@a)4{kaC^c-OKUS9=MjF)7rNy-9k*raZl@arULb;pl>$T$mIO7& zp@05?e;#KchuCrUFl<`J$$-V+$#bJ&x5_za0x^8j0PxPpKqJ=*%0-u*oUB_baz}-v zA^BiAEirYA@crAI%^q8>*OzI)QT(JiGB%ORO^l70X2H}nyte23Nv+hVkEC|#m67p0 zw|1pQ>Wxw@KR!~?ziQJiU9BAF!7y4v-~aZ_F>dt1?O}9}4)-Mc&_5FQM(+Grv|l{% z>{ZOo99v_bjbbSRRH{;~WwdN2tCOC} zkF_e5)>s~DP0^95ZPeLS*}3};%erIt&PuvgsiaJ6WGq{DX6LHaxml;29UHOCRHaf& zbFb7~n4DZ_mXg>bwoOQ(_><%~LY_pesXX~;`IKHLRnr}#kjtvz_otc1--az|uqCVS`L~^66SCK`PY)vOWvNo(h7lh`C2mKZNWBMCXYJJ>R#iuu$V&l>J3@d!l<+{fCC?vu z?6D(3Al{>~L&E1Cdn^bL2p42f2wDX$cl_KnxWGPSu8eSLvxnsg(SY?){0^~fk)##B{Lho z-GPXU)dp0_B*$9e@CHZg;yi>j3iPO3EpMHOK%CF`eQ|h0ebHt~=n2B`=VjecRRfk- z9FyZp^}19k2nJw3?7|uuu1PIGqS#B=XFaAtW>kdstBMVzllj_q%V0C?Cg>dSR!3q- zFYLW=^v~!O{^)3k)N_E2Uf?}~FB}!Gu>T2BM3s(SV7l-Nd+4Kt{j`%E!HM}v_5fzY zt-8_imY5Z{O~RwyXcIrjlhh_T6V<71%ogck7$>oP1VUkTd(p_nRN0=#yMu{>Jn4$b z6FCxQ0b`d?$Mb?~YjbzM%Y8pgW;LX9hK)J2yLV+B*I#w9L^y zAbEk)@(u_CX&4I5!Dx{YdccZ5q!IIY5EATrA*3OefV|~_4W^3|cZ*H27Hq)<=CTgE z3o~|H%vOtRGurobNCaYc6t;~1B)FvUm`iV@3J1J@yq4tE;38foYZ z`)Qlh&`tdv6IRYHV<**e0%+W;v%Dxw7frcOPFhD>);TtC;T_W!O7ZsqayPVq?NeeL6V> z44{h>7&HmZ3OyB)2gR`*f~VkvK%#WL9s=<}VB6pWR0l)&@fdb6x>3cMZY0&?iv+WKUmN&N1TO@A>7Cp4)G|~5brbKI9%HXV`p3m1O z#?qAI<;R#!`#~=`z7tajOz@2e2W*@hV1fMaZAL`K z+csR`+8WSdU0@O15+AO_g3b82e^_qAKz5aa(V@LTE?k0bdX3uHq4cYB9 z%I=VfIDx}a-GXB#Jlny(fT*;Fj!~V2xe^bLU%OU#*XH5GOs&uCf3Gw~veoIOiHW7@ zD$cqV&*JWD;9?2KCW{lyhm~|DgX=a$)xJ!Y5?M}3%)7R?&U*b&A8pRo2oK>?48u^K zd05N9YfF42;k5zDSq+F}C6h@j_Y7l7Y%q0j50S@xT4Z&QH6JY#G${O|wi6i_LuQDO z4e|Y2;|AAj(4R%l3I%&)ZNx@I7dmPeOf9DTaT0#b6f3f<_JCk_*I;;l{>k8k|u&7wHq3=;>W1@Ur!uc1~ zAA0E2eeh5rHAS%FI7uh*-YsQY>rwi31S@Xu$8pl0%E#lpr?-^lkfxB-O=4=3z=+qc zBkd!2ag02+ieMuY5GWlWcrk1vi~QRPPWO(muksmu)$<}eE#H@I{GOYy+O>lK literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.svg b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.svg new file mode 100644 index 0000000..feb9ba3 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.svg @@ -0,0 +1,63 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.ttf b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.ttf new file mode 100644 index 0000000000000000000000000000000000000000..58103c2b6287fa209bf1e62c7ea107fd65a351f1 GIT binary patch literal 9860 zcmb_idyE~|SwCmqckcT!ch>v3JNI7i&aUn3dUy8v`jKqLmF-X`cGgasRDmSp*v`X= zlO-`tqB>-%R3#M=3Z)W}3h1V&6$lklL=mb&83g>(KfqK_RaFZYQ3Mqtm`72e;x51M z%*@@pUO$qG*?Z=E=k=ZMobx@;EaQx^EDM>;_TGEn;-}#q z#wSs}|A{j%tRpX>Ou6yIGcP}W`M%4Kqx=$M&F?&U{>-_JFaJx2vG)CF-}fXc7}Q+^0z3zgYx&DdG73)tEYc>2~D3x`O?KRFRil=vu`mrW1#Fjd*vuN(cVh#!3?@trA zzQp{<_oG4RaA#(M_Xmul9EO9ChrQm!;B%nQq4fh-gY9AW0GGQUyZUTF(yLlS>Z+@< zTcw)4^;&&Nck6rWd#8C-s};Db&bDS(-0JKqU+&r~^?mh@-9<0WmieFFr59_J%)e#| zIhAv+n(#``FcF-+b^Ho9WO} zyRN<ltkabtL3v!WLc0;yxyW5bbxz}BlyLQ)ImG9)P-gY}(&$cAC#uY`CSN8jA z*34?gnxP?A{rxMlswjNz7R^0hJb&;3hh2l!h_Nt|09qW6aGE-#xyY)FRh!oEuaiLN z1P<^A5ha2}Ir1Gp^m|A^b3tXv~xCBvz@4A%T5ZC4^V@Rwir6$e6 z^-l7KH7aZ$c>e3yuVd^r_7?kV@WO(;o4egrzJOD93%tRnx!!I;3JOvk?BFf0O5g;y zYeOi8W$LYhZ|Enr+PkQ{Aa`e1r4G1;e$ujc5XkI?RI^ED^locG0yBBb4N0#Tq_#aW zkl1l$c4d|jj0}}ApVg2wTdM;B|HDkBUd`p3pUCEUHvdO|EV5Upi>6hp>E)7=%j&se zF_WoRYeqJ2a_+Qb*(heridD<%<$OWSn^L7X_z$qK#uZi96iHWgNzn{I3dxX=B4T7+ zH6%qfRD~NFAQ`dE<870CcPSi6tJ)_(~?9QJgT>+S$rQk;ppf1Da*R9%d)0vfVQ+KvX-_yr02?+OgX2g`KuTwfm#x4S=ELJ zbWO&xuiK)NWl%|f3SB(QI_w}@Wk;byJ1Yy)?&J+7n&QMtR=L)Y4spxtmfP-rdC5b9 z#@0zXdB@YcZL3{wTD*s?lh@TuR`>O6MqQURP=Km8`$5q6{eZI#2(jn+K@Zl%U!!)1 zdeRVwdJZD03(zxkoWOAgU-G>B0`5eNX+s@Ix?&$Y!OpRdLtDUh%plqA4yd5CNibOd z4(?fkc)*=97T3m#7NpL~Di#D*wrXJI?)EBsdzBMKoJG;QlVKQ6>V=G^WeWOR1o%UU zfWbE|E8_GtWe7axq=O1W#YlPomK7uW zr?3nwur}L|JrvruLkcK<$=DbYaj`G7QPwRhhU!nKK(joS&ySVO_nVVhkAFP4c3gDJ z3h=Qul-RjSA(Zh0}MmeJxkXN~!`id$TsED&haV!u#N5rjq^B zEw^j!Yj92HuUOTI2kwuebI-%^aomSaE=#XQ(Pinxi=RG#J>cxM#COD4-m&%0Y=PJ9 z1-{B{4mrR7fr+Zsaof+I~%L^8}^Tqmq~Q-RfoF$Iy6jVVxRkWMtTQ`zy!iENXb+iFJ90tIHgHCn_=EU}X( z*{`y<*%#PvvM;eOv#*Gg-#lVh+j7Lxa<{$={|RSIF-go6bZXtYV1e|Elg4Y$*xtA0 zjHQ-7+aeEdIGzq!g;&?LEnP=aZ3+S`oyzb1c!#n5Q2*b~dGJP14?2z$!LmPr z1;H=i_`rI)s!69Mh1@C`Zq>4+sk#jJPEpq2WRb5WwPg4;Fm^0BfAVI3QY>K z)8@p)r0MX?_PQ6Zo<$#=&Cf2#*5gP65VV_}{|2)xbg+Rdun zMR!C!{ejP;(8!Zb%^PVR48kDvd2bLPg*+Jacxkkq`d#I$x0j~PAUVUi3y8ADU?p43 zWxEn8s$>;~X%sI(l()66X~hHu!Z7;WfiuUF!k`}tGQvR*QM&k%t2cz2w0~)cjG-{N{Wc4ux`H%s;$|$hrW?IFf zT{H~5imjPBYkN)S;bU`i#~$vaIkwRu4>a&8)LOgA$RV!1qvHt=9j(Ix+(!fnU+A{y zcD=T(d);0b`k_cZP6`k`I1==nfc^Og{sr8H+`*2s2jSB)P7W*L)D z3V9X${v`AHTks_fmS^lv?%AH)mc6QHx4UmoeRAqRupS&Zv2*H?DR|T3x`hP+!@VCK zoNFZX;HWOz!2SuP&;6lVc#HHUH7k@cH z)=hC?GZJ0B0;;?&Fs%wTECOs&&Zx0H$O>sC5*?wBEGRf9+A%*>o?JYrkyhjxvnT61jIp|<0PPiJ>7?w^M0n3{ryn%=*-Gy8Ptm-6%b4!0>5pqQe4c;9@U zuE24Rme51`V3pkm{$ty8WjP7%Q+nDm1^AYDCm=(*gR1qVHdD=34MG&ys|!j*E>82qI6dyx@XwjL#MZQFE#ZE zfq)2D_eu1l{+sRNzf8v*%K_;N+?IDi7)ZlXa1Ta@jMN8K{Gg4P&%=n|z>lB}aRd}C z4}CCQ+_>9pnzi8zE;5gG*`3(2<6^hkuC@ z_X6MP$B^R(&UNZwBcP{2G&m%rE0)mlod7vThE5N_)*7rY?T>ZoTh)yE3w8*LV0pDJl*x+z>)6sEbgRQuF{&G%H^whUB@doHBBZSHD)Q7 zkse-OKdrfk?%4(UctkppM(y3&GaZ|$+dJ}MI1il~`Mm)9A~U>s5BAoEX7HfPW1@ER za_V8aZmKSE^;>NZOKtv`o;8$OdvUxMjW4!qnUY=jyk}Mmx>2Z_-o5woHM3SQGKHG? zo>7IrL!Aab4JbD!?aXJ=Tfh*uIE6uzu&l6C5k*iO$02wMF$gqD&+j7-AM{DR1^u88`im@tX72F-(wTnuv|$ZnJ-j>7#D_ow1cNj$<`M}640F`a)mD8Q>@`ih2~|A4rX#IPWE;Gy}Qd0Uz{6`0okq6n#|IUH{Fi{yS?|#9P?) z?@L%a+Nbet@+WEc+_v77y>7GWjkt)DxE$4O1ZE<#9m)k%r9EZZ(muD>8buFF6x36J{B?6l~ZZIEIvbh{Sw<)Uj74nqGb4qjG zbNmg~A4K|&)?A(N5I)5)4CSc@wH%_hG)59p8<3pUfJjzyxvX;cD5lg0Q-|Lniuj%u zdmZG>$HxQ;xk*1A{RPmk*2@f_~@g>+ke2a5-J$`i?wgwp5_}@;XQD8 zSNJ~~7B`DA^#3R%m}uXSaQ{X9M;^L$A3oGbLy?>$Ps?e(@0zx2`%(EdBs&=&BzZcX z+9#5_C$DKMpiC+4o8~kog^_PuML9t7lN@zy4aq?&AyGL*@)OuW6~(tT-0mG=U*)s- zub$@-A%9K!o_xFf9pxvKPbt5v{Ed1r!+68^VrIouOvk)nzGVJ} z`RC?;W^d1aJ=e&s<)U0ae^37P{I?3N!okAF3O_847e7?IQ2c!He@bTQjnaE!rw_1i zLZ{F}q+I(H*l#E2!O8neV2Ty*N?;lA&IDEfe;qqaEvpCHH}S|B>T J6}@lx{2vuDq_zM6 literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.woff b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.woff new file mode 100644 index 0000000000000000000000000000000000000000..ad1ae396a88239278653cf63ac3630b6b8360102 GIT binary patch literal 7664 zcmd^EeRNbsmah&e@&s&y^qUz5ok?6)9a_|cMi+4QpfEvgMU=(><57@+KF#`x8}ikUk8}tz0ZB*)RLsFoKnEOk8;=~ek7wPC4(je%+1AzZBv$Wvy@&nP>uv}t zjywLjue<8qx^?UK>f_#9x85szASdSmhvNapuKkLQW4NyEVCP#89(-W&E!m9yvIYDVGAY-66IoTTvKYLtPxvOOUUlWnDE09h0U(IIA_6oa-O=OeU&)5_^ z>hIY!b_=tyS?nL#Ja#v`pFPBK*&}QvTf>~Jn7P@L>?!7BTUitHvt6u{^{`$xz@BGE z*sJVy_9pu$_8tqf57di=o$JP2)}JCe`#y)2|c#Pu$$My0hHbx4M6K z>#atXC8=zg&5)T*W;11Wo6K&P*+0l^mdx&y*AgG@v5MIAP*lS5LUwef7|!S(AQ0sn3#SdDPNw39GZz zu=<}r+w${UVwySr*EMt05p}6C2T@FmYD7_oJ;Zf~T@4ZG7CVu!aN&qq)R+a8mLRw` zF$lKpIoe-L`hRnCbZInQo%heYGLXN^O^WU#?xyl`aw`;@&&l0c-c3q0m3TLGc2c)O z;v}c;&Ha@D#pPDFZEf7TZL2bi=tI73>$V2aXXf)g`qwJe;UXo5mUUFuOw9^Kf!B*j+f>Pd3keXD}S1_svi+JYTV?BCGi>U(NGbyHVcAaL+t&D)Q^py*F8Q0qK3UZ2nF_11doymj6N zFL`N8qu1}%8n%<4+8VWHf3w!&_qVmR`CGMS#owfD1D|#@_&t8_wra@xwtDKl%D?`* zT0&)Aw2$_6bs?j!GAf~xva%8=;#_@_>h*3h;JuCBW>2%X#q0OA)%feQdjD1pfc|aU z{eHi;qY)%&TmAKlR_Cv2^Z9)(hJ2%keB^DY_Iea^)F#4ET~3;>%>!#nB?@xttZFYO z#ZJ7Os;a15Atx$0n)%2Bl@D|BwD~mjW-5_YxF`}Kp;?LRE@4s0xRel7E>4ltE>W#k zm4X7Q>C~Z`BCP+1O2>}T(xp7~k!l5yZiAr@N(tS;%|SQ{;gHe}NNd4Sg+)-lfwS|SqsIZR?Vd##(u@c<~UFZeJqF$z8ji{J- zCs70`$b))^N+pqn{4l65(b6eN*42W6S7%x_{}ig}5y{O7AEQ9hj2zFTaE$DDbr_ zXw{Pi1vNFb__a2+QY%(_kp8xY=IBJHdh%;cWa*`~SinirNy#7S>0ETR9nkCa4E-j> z3)G7nX{gjZ$_MRgQ(a>%)e@YK&!^0u&1-7l!=UEgW?!qa{54+FRtHZ)@L#R1 z%Afwk;lY|TYN3{f=6bkBUbW-N7T6q>`6?=8`}}-b-k-0$ww!lVc6qx9KYt(~TlV%g zy;OQYS-+l(X0b;Fc157fkCs&Ct*n%7i;C(W-CH10>zfnQ{xfW{r?(rOu1XN zM!LHrR{pxULJh*%!f)vgs~RzEmPdcB|3-~i-EM1y-?lL+0HbgvCCm}{V?=GxEBxT9 zqneB=#9(ZJs$+vS+;H>;>Ahn&NOQD7+9pjkYLlTz)Fq=j2R!v~6uCak(Q2Pc`=5S# zKepPZH&QVbZ`_ECHa<=Jm5AQy1f(2I>qM+QqLNHiv z9a0xlt~(ExJC_#I;_lqTd580kyHC&wI^KO4SNCy{C)~%uKAhXV81Cd%?3-L_zPtN z>$_Gd`obn`mSp8ryREhvkuwe1yY}As7JVxF2k(0w-Ms9<-@f_V&z23-FnxCP%?}>@ z;O3*(k>a!`rkl#Es>%s5Njr5?XM1}m9PaJ9s+Lu6^tx-^wXS*>;n(DDakp&rmu=7Q zDC{YHX74k7J^dXW{@rbzE!CAZn`o0l4HT*d@msLy&5F;W--lvNL(B>pehTb>1XI`v_zk>NVU9EMUm zq*BAL52{dmiwuY?Qrn!WK^Z(_OCD8(&W)~>3ZW*OQUpO3jV@AfG_oGnZKG>N*gCq} zEO&p|FXJR(Mq7Chv%@NQB#O9TSQdtfAAuGAC3?*}6~Bp1;9{3mz4z3;_vZJXI(6@< z{(fYq`t$Dv3#TLt%>Da=1U*F@RTt3o>C?|GxS+i6(YbTyroU(Cwrm}}^773cf2Fk; zM)xf;^uQE3h`!U6$JBgPA5YUhCovxX z&p$VA^!YS|O88HkhMQs+r_}GNd&29$$y~k?1Dvg%p||>a2dZZ-xMw!arUma-f84wN zt->?Xaad%WsmaBY+BWQzPWeKduiH44w^zZiA|xjsa`1n|@nF~-qG!~{4+nTmST$zK zCZlvT6jP)>-&|e2nKo1PcG^X|wr@v9+pB3aP8yorKy*jW>CDU}Z;XuOoaXwn9Cajf z$&$>GoE#a)p(CO>Hd#G=8gjrseL8dGjW@W?mZ+JTr*n*_IZo${jBs-Z@oxww5<~|b z$v(k3Cl4&T12qv&k%ZSqL>-m3610wz89i83V00L&Zu`ATuO=bE)m@_|KvvY@aMVf7 zazbz}8nu-~F4FM84pq<7U3#jRI(X>JonpQ~lqy`pA|_U`Wmn zoB)P|I^7br$mvHb2i!L}PDn+9NlMs)khh>U)Eb9d+;IT2CaW(B>b8iA!>-ZZSWa>x zVz+%)@FyW+cO8ts*>T7XKI*`cTb>1Dnj8^UAL<65;u`hXNIdv}t^FX=3t+#F_<{Vw z)j@vj$zhNVt`EmF)hlO*yt<=;ya-IfAZ?hkL8<2H^rc~{dio7Fz+$n>@>l4^&Vhpm z2RdJ*SLl`U7uOA}KloVZBlHM8R=$4ShLR_pHEWg6NKb`=rwYr5#5;uPvyTLaNyuZB z-8gO9LRd3A*qkcN`(8>8YIodE{LzBnq~_tfL`IOXju=yCRxes$lc$|*Yi#Tc0p~w1iFOi@_ zori)w2YL?g9Hc=y{L}%L5{FcvyK(VcddwK4gh`0RQksmd#tBt1)IH&%Fv^%5sxe-J z5-uJ;jL|zskG>=QnM*D-G)%@}e??e26>J0XwZ(HRKfb9Lj@e|K3zZP5m@6Cnj}>cR zjmSlbSqvYDGb9#r5HU18svcX4^*x3l8>4LYp6^;C}N|F;$-`e8OiB z>GSpZbB562JVgC^9#sVO`OsUq0bYdI`+4dXF05=&4~tsjxqDV0r9aa9Z@>LMy-#m1 zq`9=EVM~3r^4fLkjh}EW(6Sru_4O4;9;SzB#R_CbwAM+xTLPN$$&GwRRae8#T}o3E z-?g)$t7?a$-}An@j*5EeARX-OMMk|vw2syl6|IvRqQU8qy@NV}m^j^1iWwF1Jr@YL z9_ny*zyrK!?*ciO6Z($tYSne~e z!8eu#iTenfjL#*PUZ(U*%Z$xs?Cea_+4K0B&Kh5QOru0H3_1llz5+1|a#?G^$AP)H zPrxUf6woG?arVZuGtd9e`Saj1l-Sv6M#*&k(~Q)NF^P6YrIDGK39?riXh3{viEq+=B_THlR??~Rye|7$BiV1y_-@)S5@`DtUeZ~h1hWhgU&!AxFeb|^6iCeX$VAx{ClAi*C4dTN4B1-&Feb9{g^ zC+M;G=#!nG$FUpPD!Fp0SAZii<8&M|PRB9hbR08I$1&sdShSs$XdB0Lv30DFm9qli zuVxP;m9SFqionfaS?p$ZE4xG{`PuOjCcY1@W>4U|U_QPPmR#BZgI*0V3A_?Dt63g^ ZAIBpz*gbe?5xy=K8ILnYh3xXz{{ll7??M0o literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/anchor.gif b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/anchor.gif new file mode 100644 index 0000000000000000000000000000000000000000..606348c7f53dba169a9aca7279a2a973f4b07bdb GIT binary patch literal 53 zcmZ?wbhEHbWM^P!XkcUjg8%>jEB<5wG8q|kKzxu40~1eAV&{y5e`l1KFoiKNSOWkz C+YCGa literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/loader.gif b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..c69e937232b24ea30f01c68bbd2ebc798dcecfcb GIT binary patch literal 2608 zcmdVcdr(tX9tZGC9yiG~=H_*Q-0%n(kWqP*D#hw{AQu8;1%gl-Hrf&{2?48KX;hHy z3Ze*zEz4t3XdUFyLbNPUYlA`|B}P=N1fqtL1*}S;87#|-W9v<#G;ul(e%d3)N(^9c$d2Dz{7}?ErjNd;{EMKkCsk21~b9Gvg zDo<7L=3Z5HNbVlZUcm1eg#o#CZCJU`3IYHwM->zCd?uYrF3vKFeM}v?f+%s?E>ly|3W25ry9#NNbTx-}0ON58dTrs^ix{_1O0Wh~SVSBlH)Ajn zPn^Gbjz}PCtN@#keR&hK&Dhl-b$kZ8^S)x#dh0{7X=X%CCJk7P1PSO>T&S8I4{#Lg zb5#)o=;!ZP*1nM{cI4@(x7o27*SA()NHmrn67aN@Pmi~(i_SnrjYnwh36aG%!@i0d zqbvfa44f|?OG4ntP|nbjhEl1)Yp6ZN@yjy zy4==QmLy%t;ps3R?~f2KfTTI|2?q8dFd6^z5GF+Xa&Y)sjG)hxit80pPcOP zJ z*LW{SyGHD%hUotV+W%I}fBLAIx!8|7#}$;clKQ+{&FjDqGQ2ZNx(lYM3*%~}ILnao zM`aui55~ZFJlu^!5rdA9Q_7H68H_;##u{x(Yn-vSfIRCb^Nqsg zGRS!Egm>h+o<}LeV4&CLReo9FrDjDvs}8?JwC)#Qs|ie=r?~xUh)&*d`Fx>FG}%X# zNdtDHBKhLPC0wpooFDAQKL%*6T|ULH$=wX!NhcasgD3d;-d$I6yRK3yN+E~C1335_iLOt+*9uvSZ`>*KA}vm}08wRq=>5l|t*Na&jR z-C1&C`nkEk#sB|@yyt-#fXngP04My zm7u$Q%EJbHp`>~`5W&L{W!6`y&}LMS;jfUpgO~7TLVMRZ9IC)IZp0A${`yp0{&wco z#1nx@XMkhqeK%7?RE7JdLr1^nwFfaJ0Q&Lv?WNJ%9}VSJsNY2+UYs2%EU0J~ayFXv zi*?7KCXQHkD)O6!0Q%4N+HTODHxJ{kQSuQX$l-rSwkwh(zMkdfzxyGwl@yHC)C4p< z&n2%8#M?)Q@mgHL1ot8`SFdSEj9ye|jHy+U8#@HoUExG=@AVkRAe_qYm4EpzK6L*& zh`)26?V#f4#_h^P9G^%>h2-H3)$QP zQovu6J9qDvsxqweDdNNa!Lb?L4_UF{tLX_nN7r0U_vF14YKcGR-*Gl} zx3oG)bzf|65dBxD-;2ZCp??K;+TuQ9onnK?==5hzbkb^r_g>z4#D8mcv8(+XdoszA zCx-qhdgxMNMotj}SiL_6V(tLcsK7(M(r(%u<}QrVfOvyK6_;~NOTlPGfX@M7S5YQF z&*$(ylJMHJt^_aQeu{C6NaTE$G3HNN@_SnN8YcaKn%`)F@~L1x+ah7-gEJPpc6w%3 zyX}r+Qk$4RHZzfH){e~F*qJ{d*L8a6n4;U?+{de0-t)mal#TVxe)3F}^UBh+zd T)6_**#cgp_+?JL9(ew3BlNF>u literal 0 HcmV?d00001 diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/object.gif b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/object.gif new file mode 100644 index 0000000000000000000000000000000000000000..cccd7f023fb80908cb33bb7d9604236cd21b7ae7 GIT binary patch literal 152 zcmV;J0B8S4Nk%w1VG#fg0J9GO<>lo+KR<78Z?v?uS65g4{r%Y3*xlXT%F4>`@9+2b z_ww@cot>Tk|Nk>HGXMYpA^8LW000jFEC2ui01*HU000C<(8)=wd#<&tyXIMjHBV`d zBSi|xsj3(;nD0kQ0aJq8eLH~x02P|t2!_J&Wqb%0io?#xD.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#9e9e9e;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#fff;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#fff;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #c5c5c5;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#858585;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#adadad}.mce-window-head .mce-title{line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:#fff;border-top:1px solid #c5c5c5;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-rtl .mce-window-head .mce-close{position:absolute;right:auto;left:15px}.mce-rtl .mce-window-head .mce-dragh{left:auto;right:0}.mce-rtl .mce-window-head .mce-title{direction:rtl;text-align:right}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000000;-moz-box-shadow:0 0 5px #000000;box-shadow:0 0 5px #000000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-n .mce-tooltip-arrow{top:0px;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #b1b1b1;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25) rgba(0,0,0,0.25);position:relative;text-shadow:0 1px 1px rgba(255,255,255,0.75);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fff, #d9d9d9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9d9d9));background-image:-webkit-linear-gradient(top, #fff, #d9d9d9);background-image:-o-linear-gradient(top, #fff, #d9d9d9);background-image:linear-gradient(to bottom, #fff, #d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9d9d9', GradientType=0);zoom:1}.mce-btn:hover,.mce-btn:focus{color:#333;background-color:#e3e3e3;background-image:-moz-linear-gradient(top, #f2f2f2, #ccc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#ccc));background-image:-webkit-linear-gradient(top, #f2f2f2, #ccc);background-image:-o-linear-gradient(top, #f2f2f2, #ccc);background-image:linear-gradient(to bottom, #f2f2f2, #ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffcccccc', GradientType=0);zoom:1}.mce-btn.mce-disabled button,.mce-btn.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{background-color:#d6d6d6;background-image:-moz-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#c0c0c0));background-image:-webkit-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-o-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:linear-gradient(to bottom, #e6e6e6, #c0c0c0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6', endColorstr='#ffc0c0c0', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-btn:not(.mce-disabled):active{background-color:#d6d6d6;background-image:-moz-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#c0c0c0));background-image:-webkit-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-o-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:linear-gradient(to bottom, #e6e6e6, #c0c0c0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6', endColorstr='#ffc0c0c0', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{min-width:50px;color:#fff;border:1px solid #b1b1b1;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25) rgba(0,0,0,0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #08c, #04c);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#04c));background-image:-webkit-linear-gradient(top, #08c, #04c);background-image:-o-linear-gradient(top, #08c, #04c);background-image:linear-gradient(to bottom, #08c, #04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);zoom:1}.mce-primary:hover,.mce-primary:focus{background-color:#005fb3;background-image:-moz-linear-gradient(top, #0077b3, #003cb3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0077b3), to(#003cb3));background-image:-webkit-linear-gradient(top, #0077b3, #003cb3);background-image:-o-linear-gradient(top, #0077b3, #003cb3);background-image:linear-gradient(to bottom, #0077b3, #003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3', endColorstr='#ff003cb3', GradientType=0);zoom:1}.mce-primary.mce-disabled button,.mce-primary.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-primary.mce-active,.mce-primary.mce-active:hover,.mce-primary:not(.mce-disabled):active{background-color:#005299;background-image:-moz-linear-gradient(top, #069, #039);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#069), to(#039));background-image:-webkit-linear-gradient(top, #069, #039);background-image:-o-linear-gradient(top, #069, #039);background-image:linear-gradient(to bottom, #069, #039);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff006699', endColorstr='#ff003399', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-primary button,.mce-primary button i{color:#fff;text-shadow:1px 1px #333}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:1px 5px;font-size:12px;*padding-bottom:2px}.mce-btn-small i{line-height:20px;vertical-align:top;*line-height:18px}.mce-btn .mce-caret{margin-top:8px;margin-left:0}.mce-btn-small .mce-caret{margin-top:8px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #333;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#aaa}.mce-caret.mce-up{border-bottom:4px solid #333;border-top:0}.mce-rtl .mce-btn button{direction:rtl}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-first{border-left:1px solid #b1b1b1;border-left:1px solid rgba(0,0,0,0.25);-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #b1b1b1;border-right:1px solid rgba(0,0,0,0.1);-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fff, #d9d9d9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9d9d9));background-image:-webkit-linear-gradient(top, #fff, #d9d9d9);background-image:-o-linear-gradient(top, #fff, #d9d9d9);background-image:linear-gradient(to bottom, #fff, #d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9d9d9', GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0;overflow:hidden}.mce-checked i.mce-i-checkbox{color:#333;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox,.mce-checkbox.mce-focus i.mce-i-checkbox{border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-checkbox.mce-disabled .mce-label,.mce-checkbox.mce-disabled i.mce-i-checkbox{color:#acacac}.mce-rtl .mce-checkbox{direction:rtl;text-align:right}.mce-rtl i.mce-i-checkbox{margin:0 0 0 3px}.mce-colorbutton .mce-ico{position:relative}.mce-colorbutton-grid{margin:4px}.mce-colorbutton button{padding-right:4px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-14px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-16px;padding-right:0;width:16px}.mce-colorbutton .mce-open{padding-left:4px;border-left:1px solid transparent;border-right:1px solid transparent}.mce-colorbutton:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-colorbutton.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-colorbutton{direction:rtl}.mce-rtl .mce-colorbutton .mce-preview{margin-left:0;padding-right:0;padding-left:4px;margin-right:-14px}.mce-rtl .mce-colorbutton.mce-btn-small .mce-preview{margin-left:0;padding-right:0;margin-right:-17px;padding-left:0}.mce-rtl .mce-colorbutton button{padding-right:10px;padding-left:10px}.mce-rtl .mce-colorbutton .mce-open{padding-left:4px;padding-right:4px}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);*height:32px}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:#c5c5c5;height:28px}.mce-combobox.mce-disabled input{color:#adadad}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox.mce-disabled .mce-btn button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#333}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:#666;color:#fff}.mce-path .mce-divider{display:inline}.mce-disabled .mce-path-item{color:#aaa}.mce-rtl .mce-path{direction:rtl}.mce-fieldset{border:0 solid #9E9E9E;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-rtl .mce-flow-layout{text-align:right;direction:rtl}.mce-rtl .mce-flow-layout-item{margin:2px 2px 2px 0}.mce-rtl .mce-flow-layout-item.mce-last{margin-left:2px}.mce-iframe{border:0 solid #9e9e9e;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label.mce-disabled{color:#aaa}.mce-label.mce-multiline{white-space:pre-wrap}.mce-label.mce-error{color:#a00}.mce-rtl .mce-label{text-align:right;direction:rtl}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #c4c4c4}.mce-menubar .mce-menubtn button span{color:#333}.mce-menubar .mce-caret{border-top-color:#333}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:transparent;background:#e6e6e6;filter:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-menubtn span{color:#333;margin-right:2px;line-height:20px;*line-height:16px}.mce-menubtn.mce-btn-small span{font-size:12px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-menubtn .mce-caret{*margin-top:6px}.mce-rtl .mce-menubtn button{direction:rtl;text-align:right}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-rtl .mce-listbox .mce-caret{right:auto;left:8px}.mce-rtl .mce-listbox button{padding-right:10px;padding-left:20px}.mce-menu-item{display:block;padding:6px 15px 6px 12px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item .mce-ico,.mce-menu-item .mce-text{color:#333}.mce-menu-item.mce-disabled .mce-text,.mce-menu-item.mce-disabled .mce-ico{color:#adadad}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text,.mce-menu-item:focus .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:#fff}.mce-menu-item.mce-disabled:hover{background:#ccc}.mce-menu-shortcut{display:inline-block;color:#adadad}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 15px 0 20px}.mce-menu-item:hover .mce-menu-shortcut,.mce-menu-item.mce-selected .mce-menu-shortcut,.mce-menu-item:focus .mce-menu-shortcut{color:#fff}.mce-menu-item .mce-caret{margin-top:4px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #333}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret,.mce-menu-item:hover .mce-caret{border-left-color:#fff}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item-normal.mce-active{background-color:#c8def4}.mce-menu-item-preview.mce-active{border-left:5px solid #aaa}.mce-menu-item-normal.mce-active .mce-text{color:#333}.mce-menu-item-normal.mce-active:hover .mce-text,.mce-menu-item-normal.mce-active:hover .mce-ico{color:#fff}.mce-menu-item-normal.mce-active:focus .mce-text,.mce-menu-item-normal.mce-active:focus .mce-ico{color:#fff}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #08c, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);zoom:1}div.mce-menu .mce-menu-item-sep,.mce-menu-item-sep:hover{border:0;padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#cbcbcb;border-bottom:1px solid #fff;cursor:default;filter:none}.mce-menu.mce-rtl{direction:rtl}.mce-rtl .mce-menu-item{text-align:right;direction:rtl;padding:6px 12px 6px 15px}.mce-menu-align.mce-rtl .mce-menu-shortcut,.mce-menu-align.mce-rtl .mce-caret{right:auto;left:0}.mce-rtl .mce-menu-item .mce-caret{margin-left:6px;margin-right:0;border-right:4px solid #333;border-left:0}.mce-rtl .mce-menu-item.mce-selected .mce-caret,.mce-rtl .mce-menu-item:focus .mce-caret,.mce-rtl .mce-menu-item:hover .mce-caret{border-left-color:transparent;border-right-color:#fff}.mce-menu{position:absolute;left:0;top:0;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#fff;border:1px solid #989898;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);max-height:400px;overflow:auto;overflow-x:hidden}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#333}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-splitbtn.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-splitbtn{direction:rtl;text-align:right}.mce-rtl .mce-splitbtn button{padding-right:10px;padding-left:10px}.mce-rtl .mce-splitbtn .mce-open{padding-left:4px;padding-right:4px}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #c5c5c5}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #c5c5c5;border-width:0 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-rtl .mce-tabs{text-align:right;direction:rtl}.mce-rtl .mce-tab{border-width:0 0 0 1px}.mce-textbox{background:#fff;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);display:inline-block;-webkit-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;*white-space:pre;color:#333}.mce-textbox:focus,.mce-textbox.mce-focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-textbox.mce-disabled{color:#adadad}.mce-rtl .mce-textbox{text-align:right;direction:rtl}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}.mce-throbber-inline{position:static;height:50px}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype'),url('fonts/tinymce.svg#tinymce') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/tinymce-small.eot');src:url('fonts/tinymce-small.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce-small.woff') format('woff'),url('fonts/tinymce-small.ttf') format('truetype'),url('fonts/tinymce-small.svg#tinymce') format('svg');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce';font-style:normal;font-weight:normal;font-size:16px;line-height:16px;vertical-align:text-top;-webkit-font-smoothing:antialiased;display:inline-block;background:transparent center center;width:16px;height:16px;color:#333;-ie7-icon:' '}.mce-btn-small .mce-ico{font-family:'tinymce-small'}.mce-ico,i.mce-i-checkbox{zoom:expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = this.currentStyle['-ie7-icon'].substr(1, 1) + ' ')}.mce-i-save{-ie7-icon:"\e000"}.mce-i-newdocument{-ie7-icon:"\e001"}.mce-i-fullpage{-ie7-icon:"\e002"}.mce-i-alignleft{-ie7-icon:"\e003"}.mce-i-aligncenter{-ie7-icon:"\e004"}.mce-i-alignright{-ie7-icon:"\e005"}.mce-i-alignjustify{-ie7-icon:"\e006"}.mce-i-cut{-ie7-icon:"\e007"}.mce-i-paste{-ie7-icon:"\e008"}.mce-i-searchreplace{-ie7-icon:"\e009"}.mce-i-bullist{-ie7-icon:"\e00a"}.mce-i-numlist{-ie7-icon:"\e00b"}.mce-i-indent{-ie7-icon:"\e00c"}.mce-i-outdent{-ie7-icon:"\e00d"}.mce-i-blockquote{-ie7-icon:"\e00e"}.mce-i-undo{-ie7-icon:"\e00f"}.mce-i-redo{-ie7-icon:"\e010"}.mce-i-link{-ie7-icon:"\e011"}.mce-i-unlink{-ie7-icon:"\e012"}.mce-i-anchor{-ie7-icon:"\e013"}.mce-i-image{-ie7-icon:"\e014"}.mce-i-media{-ie7-icon:"\e015"}.mce-i-help{-ie7-icon:"\e016"}.mce-i-code{-ie7-icon:"\e017"}.mce-i-insertdatetime{-ie7-icon:"\e018"}.mce-i-preview{-ie7-icon:"\e019"}.mce-i-forecolor{-ie7-icon:"\e01a"}.mce-i-backcolor{-ie7-icon:"\e01a"}.mce-i-table{-ie7-icon:"\e01b"}.mce-i-hr{-ie7-icon:"\e01c"}.mce-i-removeformat{-ie7-icon:"\e01d"}.mce-i-subscript{-ie7-icon:"\e01e"}.mce-i-superscript{-ie7-icon:"\e01f"}.mce-i-charmap{-ie7-icon:"\e020"}.mce-i-emoticons{-ie7-icon:"\e021"}.mce-i-print{-ie7-icon:"\e022"}.mce-i-fullscreen{-ie7-icon:"\e023"}.mce-i-spellchecker{-ie7-icon:"\e024"}.mce-i-nonbreaking{-ie7-icon:"\e025"}.mce-i-template{-ie7-icon:"\e026"}.mce-i-pagebreak{-ie7-icon:"\e027"}.mce-i-restoredraft{-ie7-icon:"\e028"}.mce-i-untitled{-ie7-icon:"\e029"}.mce-i-bold{-ie7-icon:"\e02a"}.mce-i-italic{-ie7-icon:"\e02b"}.mce-i-underline{-ie7-icon:"\e02c"}.mce-i-strikethrough{-ie7-icon:"\e02d"}.mce-i-visualchars{-ie7-icon:"\e02e"}.mce-i-ltr{-ie7-icon:"\e02f"}.mce-i-rtl{-ie7-icon:"\e030"}.mce-i-copy{-ie7-icon:"\e031"}.mce-i-resize{-ie7-icon:"\e032"}.mce-i-browse{-ie7-icon:"\e034"}.mce-i-pastetext{-ie7-icon:"\e035"}.mce-i-checkbox,.mce-i-selected{-ie7-icon:"\e033"}.mce-i-selected{visibility:hidden}.mce-i-backcolor{background:#BBB} \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.min.css b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.min.css new file mode 100644 index 0000000..284ac1d --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.min.css @@ -0,0 +1 @@ +.mce-container,.mce-container *,.mce-widget,.mce-widget *,.mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#333;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:normal;text-align:left;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr}.mce-widget button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible !important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.mce-wordcount{position:absolute;top:0;right:0;padding:8px}div.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #9e9e9e;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:middle;padding:2px}.mce-charmap td div{text-align:center}.mce-charmap td:hover{background:#d9d9d9}.mce-grid td div{border:1px solid #d6d6d6;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid td div:focus{border-color:#a1a1a1}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover,.mce-grid a:focus{border-color:#a1a1a1}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#d6d6d6;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#a1a1a1;background:#c8def4}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-toolbar-grp{padding-bottom:2px}.mce-toolbar-grp .mce-flow-layout-item{margin-bottom:0}.mce-rtl .mce-wordcount{left:0;right:auto}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-panel{border:0 solid #9e9e9e;background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fdfdfd, #ddd);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fdfdfd), to(#ddd));background-image:-webkit-linear-gradient(top, #fdfdfd, #ddd);background-image:-o-linear-gradient(top, #fdfdfd, #ddd);background-image:linear-gradient(to bottom, #fdfdfd, #ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd', endColorstr='#ffdddddd', GradientType=0);zoom:1}.mce-floatpanel{position:absolute;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2)}.mce-floatpanel.mce-fixed{position:fixed}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);top:0;left:0;background:#fff;border:1px solid #9e9e9e;border:1px solid rgba(0,0,0,0.25)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px;*margin-top:0}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#9e9e9e;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#fff;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#fff;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #c5c5c5;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#858585;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#adadad}.mce-window-head .mce-title{line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:#fff;border-top:1px solid #c5c5c5;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-rtl .mce-window-head .mce-close{position:absolute;right:auto;left:15px}.mce-rtl .mce-window-head .mce-dragh{left:auto;right:0}.mce-rtl .mce-window-head .mce-title{direction:rtl;text-align:right}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000000;-moz-box-shadow:0 0 5px #000000;box-shadow:0 0 5px #000000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-n .mce-tooltip-arrow{top:0px;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #b1b1b1;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25) rgba(0,0,0,0.25);position:relative;text-shadow:0 1px 1px rgba(255,255,255,0.75);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fff, #d9d9d9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9d9d9));background-image:-webkit-linear-gradient(top, #fff, #d9d9d9);background-image:-o-linear-gradient(top, #fff, #d9d9d9);background-image:linear-gradient(to bottom, #fff, #d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9d9d9', GradientType=0);zoom:1}.mce-btn:hover,.mce-btn:focus{color:#333;background-color:#e3e3e3;background-image:-moz-linear-gradient(top, #f2f2f2, #ccc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#ccc));background-image:-webkit-linear-gradient(top, #f2f2f2, #ccc);background-image:-o-linear-gradient(top, #f2f2f2, #ccc);background-image:linear-gradient(to bottom, #f2f2f2, #ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffcccccc', GradientType=0);zoom:1}.mce-btn.mce-disabled button,.mce-btn.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{background-color:#d6d6d6;background-image:-moz-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#c0c0c0));background-image:-webkit-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-o-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:linear-gradient(to bottom, #e6e6e6, #c0c0c0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6', endColorstr='#ffc0c0c0', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-btn:not(.mce-disabled):active{background-color:#d6d6d6;background-image:-moz-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#c0c0c0));background-image:-webkit-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-o-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:linear-gradient(to bottom, #e6e6e6, #c0c0c0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6', endColorstr='#ffc0c0c0', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{min-width:50px;color:#fff;border:1px solid #b1b1b1;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25) rgba(0,0,0,0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #08c, #04c);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#04c));background-image:-webkit-linear-gradient(top, #08c, #04c);background-image:-o-linear-gradient(top, #08c, #04c);background-image:linear-gradient(to bottom, #08c, #04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);zoom:1}.mce-primary:hover,.mce-primary:focus{background-color:#005fb3;background-image:-moz-linear-gradient(top, #0077b3, #003cb3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0077b3), to(#003cb3));background-image:-webkit-linear-gradient(top, #0077b3, #003cb3);background-image:-o-linear-gradient(top, #0077b3, #003cb3);background-image:linear-gradient(to bottom, #0077b3, #003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3', endColorstr='#ff003cb3', GradientType=0);zoom:1}.mce-primary.mce-disabled button,.mce-primary.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-primary.mce-active,.mce-primary.mce-active:hover,.mce-primary:not(.mce-disabled):active{background-color:#005299;background-image:-moz-linear-gradient(top, #069, #039);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#069), to(#039));background-image:-webkit-linear-gradient(top, #069, #039);background-image:-o-linear-gradient(top, #069, #039);background-image:linear-gradient(to bottom, #069, #039);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff006699', endColorstr='#ff003399', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-primary button,.mce-primary button i{color:#fff;text-shadow:1px 1px #333}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:1px 5px;font-size:12px;*padding-bottom:2px}.mce-btn-small i{line-height:20px;vertical-align:top;*line-height:18px}.mce-btn .mce-caret{margin-top:8px;margin-left:0}.mce-btn-small .mce-caret{margin-top:8px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #333;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#aaa}.mce-caret.mce-up{border-bottom:4px solid #333;border-top:0}.mce-rtl .mce-btn button{direction:rtl}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-first{border-left:1px solid #b1b1b1;border-left:1px solid rgba(0,0,0,0.25);-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #b1b1b1;border-right:1px solid rgba(0,0,0,0.1);-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fff, #d9d9d9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9d9d9));background-image:-webkit-linear-gradient(top, #fff, #d9d9d9);background-image:-o-linear-gradient(top, #fff, #d9d9d9);background-image:linear-gradient(to bottom, #fff, #d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9d9d9', GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0;overflow:hidden}.mce-checked i.mce-i-checkbox{color:#333;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox,.mce-checkbox.mce-focus i.mce-i-checkbox{border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-checkbox.mce-disabled .mce-label,.mce-checkbox.mce-disabled i.mce-i-checkbox{color:#acacac}.mce-rtl .mce-checkbox{direction:rtl;text-align:right}.mce-rtl i.mce-i-checkbox{margin:0 0 0 3px}.mce-colorbutton .mce-ico{position:relative}.mce-colorbutton-grid{margin:4px}.mce-colorbutton button{padding-right:4px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-14px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-16px;padding-right:0;width:16px}.mce-colorbutton .mce-open{padding-left:4px;border-left:1px solid transparent;border-right:1px solid transparent}.mce-colorbutton:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-colorbutton.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-colorbutton{direction:rtl}.mce-rtl .mce-colorbutton .mce-preview{margin-left:0;padding-right:0;padding-left:4px;margin-right:-14px}.mce-rtl .mce-colorbutton.mce-btn-small .mce-preview{margin-left:0;padding-right:0;margin-right:-17px;padding-left:0}.mce-rtl .mce-colorbutton button{padding-right:10px;padding-left:10px}.mce-rtl .mce-colorbutton .mce-open{padding-left:4px;padding-right:4px}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);*height:32px}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:#c5c5c5;height:28px}.mce-combobox.mce-disabled input{color:#adadad}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox.mce-disabled .mce-btn button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#333}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:#666;color:#fff}.mce-path .mce-divider{display:inline}.mce-disabled .mce-path-item{color:#aaa}.mce-rtl .mce-path{direction:rtl}.mce-fieldset{border:0 solid #9E9E9E;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-rtl .mce-flow-layout{text-align:right;direction:rtl}.mce-rtl .mce-flow-layout-item{margin:2px 2px 2px 0}.mce-rtl .mce-flow-layout-item.mce-last{margin-left:2px}.mce-iframe{border:0 solid #9e9e9e;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label.mce-disabled{color:#aaa}.mce-label.mce-multiline{white-space:pre-wrap}.mce-label.mce-error{color:#a00}.mce-rtl .mce-label{text-align:right;direction:rtl}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #c4c4c4}.mce-menubar .mce-menubtn button span{color:#333}.mce-menubar .mce-caret{border-top-color:#333}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:transparent;background:#e6e6e6;filter:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-menubtn span{color:#333;margin-right:2px;line-height:20px;*line-height:16px}.mce-menubtn.mce-btn-small span{font-size:12px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-menubtn .mce-caret{*margin-top:6px}.mce-rtl .mce-menubtn button{direction:rtl;text-align:right}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-rtl .mce-listbox .mce-caret{right:auto;left:8px}.mce-rtl .mce-listbox button{padding-right:10px;padding-left:20px}.mce-menu-item{display:block;padding:6px 15px 6px 12px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item .mce-ico,.mce-menu-item .mce-text{color:#333}.mce-menu-item.mce-disabled .mce-text,.mce-menu-item.mce-disabled .mce-ico{color:#adadad}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text,.mce-menu-item:focus .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:#fff}.mce-menu-item.mce-disabled:hover{background:#ccc}.mce-menu-shortcut{display:inline-block;color:#adadad}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 15px 0 20px}.mce-menu-item:hover .mce-menu-shortcut,.mce-menu-item.mce-selected .mce-menu-shortcut,.mce-menu-item:focus .mce-menu-shortcut{color:#fff}.mce-menu-item .mce-caret{margin-top:4px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #333}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret,.mce-menu-item:hover .mce-caret{border-left-color:#fff}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item-normal.mce-active{background-color:#c8def4}.mce-menu-item-preview.mce-active{border-left:5px solid #aaa}.mce-menu-item-normal.mce-active .mce-text{color:#333}.mce-menu-item-normal.mce-active:hover .mce-text,.mce-menu-item-normal.mce-active:hover .mce-ico{color:#fff}.mce-menu-item-normal.mce-active:focus .mce-text,.mce-menu-item-normal.mce-active:focus .mce-ico{color:#fff}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #08c, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);zoom:1}div.mce-menu .mce-menu-item-sep,.mce-menu-item-sep:hover{border:0;padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#cbcbcb;border-bottom:1px solid #fff;cursor:default;filter:none}.mce-menu.mce-rtl{direction:rtl}.mce-rtl .mce-menu-item{text-align:right;direction:rtl;padding:6px 12px 6px 15px}.mce-menu-align.mce-rtl .mce-menu-shortcut,.mce-menu-align.mce-rtl .mce-caret{right:auto;left:0}.mce-rtl .mce-menu-item .mce-caret{margin-left:6px;margin-right:0;border-right:4px solid #333;border-left:0}.mce-rtl .mce-menu-item.mce-selected .mce-caret,.mce-rtl .mce-menu-item:focus .mce-caret,.mce-rtl .mce-menu-item:hover .mce-caret{border-left-color:transparent;border-right-color:#fff}.mce-menu{position:absolute;left:0;top:0;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#fff;border:1px solid #989898;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);max-height:400px;overflow:auto;overflow-x:hidden}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#333}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-splitbtn.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-splitbtn{direction:rtl;text-align:right}.mce-rtl .mce-splitbtn button{padding-right:10px;padding-left:10px}.mce-rtl .mce-splitbtn .mce-open{padding-left:4px;padding-right:4px}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #c5c5c5}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #c5c5c5;border-width:0 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-rtl .mce-tabs{text-align:right;direction:rtl}.mce-rtl .mce-tab{border-width:0 0 0 1px}.mce-textbox{background:#fff;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);display:inline-block;-webkit-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;*white-space:pre;color:#333}.mce-textbox:focus,.mce-textbox.mce-focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-textbox.mce-disabled{color:#adadad}.mce-rtl .mce-textbox{text-align:right;direction:rtl}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}.mce-throbber-inline{position:static;height:50px}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype'),url('fonts/tinymce.svg#tinymce') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/tinymce-small.eot');src:url('fonts/tinymce-small.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce-small.woff') format('woff'),url('fonts/tinymce-small.ttf') format('truetype'),url('fonts/tinymce-small.svg#tinymce') format('svg');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce',Arial;font-style:normal;font-weight:normal;font-variant:normal;font-size:16px;line-height:16px;speak:none;vertical-align:text-top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;background:transparent center center;background-size:cover;width:16px;height:16px;color:#333}.mce-btn-small .mce-ico{font-family:'tinymce-small',Arial}.mce-i-save:before{content:"\e000"}.mce-i-newdocument:before{content:"\e001"}.mce-i-fullpage:before{content:"\e002"}.mce-i-alignleft:before{content:"\e003"}.mce-i-aligncenter:before{content:"\e004"}.mce-i-alignright:before{content:"\e005"}.mce-i-alignjustify:before{content:"\e006"}.mce-i-cut:before{content:"\e007"}.mce-i-paste:before{content:"\e008"}.mce-i-searchreplace:before{content:"\e009"}.mce-i-bullist:before{content:"\e00a"}.mce-i-numlist:before{content:"\e00b"}.mce-i-indent:before{content:"\e00c"}.mce-i-outdent:before{content:"\e00d"}.mce-i-blockquote:before{content:"\e00e"}.mce-i-undo:before{content:"\e00f"}.mce-i-redo:before{content:"\e010"}.mce-i-link:before{content:"\e011"}.mce-i-unlink:before{content:"\e012"}.mce-i-anchor:before{content:"\e013"}.mce-i-image:before{content:"\e014"}.mce-i-media:before{content:"\e015"}.mce-i-help:before{content:"\e016"}.mce-i-code:before{content:"\e017"}.mce-i-insertdatetime:before{content:"\e018"}.mce-i-preview:before{content:"\e019"}.mce-i-forecolor:before{content:"\e01a"}.mce-i-backcolor:before{content:"\e01a"}.mce-i-table:before{content:"\e01b"}.mce-i-hr:before{content:"\e01c"}.mce-i-removeformat:before{content:"\e01d"}.mce-i-subscript:before{content:"\e01e"}.mce-i-superscript:before{content:"\e01f"}.mce-i-charmap:before{content:"\e020"}.mce-i-emoticons:before{content:"\e021"}.mce-i-print:before{content:"\e022"}.mce-i-fullscreen:before{content:"\e023"}.mce-i-spellchecker:before{content:"\e024"}.mce-i-nonbreaking:before{content:"\e025"}.mce-i-template:before{content:"\e026"}.mce-i-pagebreak:before{content:"\e027"}.mce-i-restoredraft:before{content:"\e028"}.mce-i-untitled:before{content:"\e029"}.mce-i-bold:before{content:"\e02a"}.mce-i-italic:before{content:"\e02b"}.mce-i-underline:before{content:"\e02c"}.mce-i-strikethrough:before{content:"\e02d"}.mce-i-visualchars:before{content:"\e02e"}.mce-i-visualblocks:before{content:"\e02e"}.mce-i-ltr:before{content:"\e02f"}.mce-i-rtl:before{content:"\e030"}.mce-i-copy:before{content:"\e031"}.mce-i-resize:before{content:"\e032"}.mce-i-browse:before{content:"\e034"}.mce-i-pastetext:before{content:"\e035"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#bbb} \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/js/themes/modern/theme.min.js b/node_modules/selenium-webdriver/lib/test/data/js/themes/modern/theme.min.js new file mode 100644 index 0000000..e25849d --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/js/themes/modern/theme.min.js @@ -0,0 +1 @@ +tinymce.ThemeManager.add("modern",function(e){function t(){function t(t){var n,o=[];if(t)return d(t.split(/[ ,]/),function(t){function i(){var i=e.selection;"bullist"==r&&i.selectorChanged("ul > li",function(e,i){for(var n,o=i.parents.length;o--&&(n=i.parents[o].nodeName,"OL"!=n&&"UL"!=n););t.active(e&&"UL"==n)}),"numlist"==r&&i.selectorChanged("ol > li",function(e,i){for(var n,o=i.parents.length;o--&&(n=i.parents[o].nodeName,"OL"!=n&&"UL"!=n););t.active(e&&"OL"==n)}),t.settings.stateSelector&&i.selectorChanged(t.settings.stateSelector,function(e){t.active(e)},!0),t.settings.disabledStateSelector&&i.selectorChanged(t.settings.disabledStateSelector,function(e){t.disabled(e)})}var r;"|"==t?n=null:c.has(t)?(t={type:t},u.toolbar_items_size&&(t.size=u.toolbar_items_size),o.push(t),n=null):(n||(n={type:"buttongroup",items:[]},o.push(n)),e.buttons[t]&&(r=t,t=e.buttons[r],"function"==typeof t&&(t=t()),t.type=t.type||"button",u.toolbar_items_size&&(t.size=u.toolbar_items_size),t=c.create(t),n.items.push(t),e.initialized?i():e.on("init",i)))}),i.push({type:"toolbar",layout:"flow",items:o}),!0}var i=[];if(tinymce.isArray(u.toolbar)){if(0===u.toolbar.length)return;tinymce.each(u.toolbar,function(e,t){u["toolbar"+(t+1)]=e}),delete u.toolbar}for(var n=1;10>n&&t(u["toolbar"+n]);n++);return i.length||u.toolbar===!1||t(u.toolbar||f),i.length?{type:"panel",layout:"stack",classes:"toolbar-grp",ariaRoot:!0,ariaRemember:!0,items:i}:void 0}function i(){function t(t){var i;return"|"==t?{text:"|"}:i=e.menuItems[t]}function i(i){var n,o,r,a,s;if(s=tinymce.makeMap((u.removed_menuitems||"").split(/[ ,]/)),u.menu?(o=u.menu[i],a=!0):o=h[i],o){n={text:o.title},r=[],d((o.items||"").split(/[ ,]/),function(e){var i=t(e);i&&!s[e]&&r.push(t(e))}),a||d(e.menuItems,function(e){e.context==i&&("before"==e.separator&&r.push({text:"|"}),e.prependToContext?r.unshift(e):r.push(e),"after"==e.separator&&r.push({text:"|"}))});for(var l=0;lr;r++)if(o=n[r],o&&o.func.call(o.scope,e)===!1&&e.preventDefault(),e.isImmediatePropagationStopped())return}var a=this,s={},l,c,u,d,f;c=o+(+new Date).toString(32),d="onmouseenter"in document.documentElement,u="onfocusin"in document.documentElement,f={mouseenter:"mouseover",mouseleave:"mouseout"},l=1,a.domLoaded=!1,a.events=s,a.bind=function(t,o,p,h){function m(e){i(n(e||_.event),g)}var g,v,y,b,C,x,w,_=window;if(t&&3!==t.nodeType&&8!==t.nodeType){for(t[c]?g=t[c]:(g=l++,t[c]=g,s[g]={}),h=h||t,o=o.split(" "),y=o.length;y--;)b=o[y],x=m,C=w=!1,"DOMContentLoaded"===b&&(b="ready"),a.domLoaded&&"ready"===b&&"complete"==t.readyState?p.call(h,n({type:b})):(d||(C=f[b],C&&(x=function(e){var t,r;if(t=e.currentTarget,r=e.relatedTarget,r&&t.contains)r=t.contains(r);else for(;r&&r!==t;)r=r.parentNode;r||(e=n(e||_.event),e.type="mouseout"===e.type?"mouseleave":"mouseenter",e.target=t,i(e,g))})),u||"focusin"!==b&&"focusout"!==b||(w=!0,C="focusin"===b?"focus":"blur",x=function(e){e=n(e||_.event),e.type="focus"===e.type?"focusin":"focusout",i(e,g)}),v=s[g][b],v?"ready"===b&&a.domLoaded?p({type:b}):v.push({func:p,scope:h}):(s[g][b]=v=[{func:p,scope:h}],v.fakeName=C,v.capture=w,v.nativeHandler=x,"ready"===b?r(t,x,a):e(t,C||b,x,w)));return t=v=0,p}},a.unbind=function(e,n,r){var i,o,l,u,d,f;if(!e||3===e.nodeType||8===e.nodeType)return a;if(i=e[c]){if(f=s[i],n){for(n=n.split(" "),l=n.length;l--;)if(d=n[l],o=f[d]){if(r)for(u=o.length;u--;)if(o[u].func===r){var p=o.nativeHandler,h=o.fakeName,m=o.capture;o=o.slice(0,u).concat(o.slice(u+1)),o.nativeHandler=p,o.fakeName=h,o.capture=m,f[d]=o}r&&0!==o.length||(delete f[d],t(e,o.fakeName||d,o.nativeHandler,o.capture))}}else{for(d in f)o=f[d],t(e,o.fakeName||d,o.nativeHandler,o.capture);f={}}for(d in f)return a;delete s[i];try{delete e[c]}catch(g){e[c]=null}}return a},a.fire=function(e,t,r){var o;if(!e||3===e.nodeType||8===e.nodeType)return a;r=n(null,r),r.type=t,r.target=e;do o=e[c],o&&i(r,o),e=e.parentNode||e.ownerDocument||e.defaultView||e.parentWindow;while(e&&!r.isPropagationStopped());return a},a.clean=function(e){var t,n,r=a.unbind;if(!e||3===e.nodeType||8===e.nodeType)return a;if(e[c]&&r(e),e.getElementsByTagName||(e=e.document),e&&e.getElementsByTagName)for(r(e),n=e.getElementsByTagName("*"),t=n.length;t--;)e=n[t],e[c]&&r(e);return a},a.destroy=function(){s={}},a.cancel=function(e){return e&&(e.preventDefault(),e.stopImmediatePropagation()),!1}}var o="mce-data-",a=/^(?:mouse|contextmenu)|click/,s={keyLocation:1,layerX:1,layerY:1,returnValue:1};return i.Event=new i,i.Event.bind(window,"ready",function(){}),i}),r(c,[],function(){function e(e){return mt.test(e+"")}function n(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>_.cacheLength&&delete e[t.shift()],e[n]=r,r}}function r(e){return e[I]=!0,e}function i(e){var t=B.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t=null}}function o(e,t,n,r){var i,o,a,s,l,c,f,p,h,m;if((t?t.ownerDocument||t:F)!==B&&A(t),t=t||B,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(L&&!r){if(i=gt.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&O(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return Z.apply(n,t.getElementsByTagName(e)),n;if((a=i[3])&&z.getElementsByClassName&&t.getElementsByClassName)return Z.apply(n,t.getElementsByClassName(a)),n}if(z.qsa&&!M.test(e)){if(f=!0,p=I,h=t,m=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){for(c=u(e),(f=t.getAttribute("id"))?p=f.replace(bt,"\\$&"):t.setAttribute("id",p),p="[id='"+p+"'] ",l=c.length;l--;)c[l]=p+d(c[l]);h=ht.test(e)&&t.parentNode||t,m=c.join(",")}if(m)try{return Z.apply(n,h.querySelectorAll(m)),n}catch(g){}finally{f||t.removeAttribute("id")}}}return b(e.replace(lt,"$1"),t,n,r)}function a(e,t){var n=t&&e,r=n&&(~t.sourceIndex||Y)-(~e.sourceIndex||Y);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function l(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function c(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function u(e,t){var n,r,i,a,s,l,c,u=q[e+" "];if(u)return t?0:u.slice(0);for(s=e,l=[],c=_.preFilter;s;){(!n||(r=ct.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=ut.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(lt," ")}),s=s.slice(n.length));for(a in _.filter)!(r=pt[a].exec(s))||c[a]&&!(r=c[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?o.error(e):q(e,l).slice(0)}function d(e){for(var t=0,n=e.length,r="";n>t;t++)r+=e[t].value;return r}function f(e,t,n){var r=t.dir,i=n&&"parentNode"===r,o=V++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,a){var s,l,c,u=W+" "+o;if(a){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,a))return!0}else for(;t=t[r];)if(1===t.nodeType||i)if(c=t[I]||(t[I]={}),(l=c[r])&&l[0]===u){if((s=l[1])===!0||s===w)return s===!0}else if(l=c[r]=[u],l[1]=e(t,n,a)||w,l[1]===!0)return!0}}function p(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function h(e,t,n,r,i){for(var o,a=[],s=0,l=e.length,c=null!=t;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),c&&t.push(s));return a}function m(e,t,n,i,o,a){return i&&!i[I]&&(i=m(i)),o&&!o[I]&&(o=m(o,a)),r(function(r,a,s,l){var c,u,d,f=[],p=[],m=a.length,g=r||y(t||"*",s.nodeType?[s]:s,[]),v=!e||!r&&t?g:h(g,f,e,s,l),b=n?o||(r?e:m||i)?[]:a:v;if(n&&n(v,b,s,l),i)for(c=h(b,p),i(c,[],s,l),u=c.length;u--;)(d=c[u])&&(b[p[u]]=!(v[p[u]]=d));if(r){if(o||e){if(o){for(c=[],u=b.length;u--;)(d=b[u])&&c.push(v[u]=d);o(null,b=[],c,l)}for(u=b.length;u--;)(d=b[u])&&(c=o?tt.call(r,d):f[u])>-1&&(r[c]=!(a[c]=d))}}else b=h(b===a?b.splice(m,b.length):b),o?o(null,a,b,l):Z.apply(a,b)})}function g(e){for(var t,n,r,i=e.length,o=_.relative[e[0].type],a=o||_.relative[" "],s=o?1:0,l=f(function(e){return e===t},a,!0),c=f(function(e){return tt.call(t,e)>-1},a,!0),u=[function(e,n,r){return!o&&(r||n!==k)||((t=n).nodeType?l(e,n,r):c(e,n,r))}];i>s;s++)if(n=_.relative[e[s].type])u=[f(p(u),n)];else{if(n=_.filter[e[s].type].apply(null,e[s].matches),n[I]){for(r=++s;i>r&&!_.relative[e[r].type];r++);return m(s>1&&p(u),s>1&&d(e.slice(0,s-1)).replace(lt,"$1"),n,r>s&&g(e.slice(s,r)),i>r&&g(e=e.slice(r)),i>r&&d(e))}u.push(n)}return p(u)}function v(e,t){var n=0,i=t.length>0,a=e.length>0,s=function(r,s,l,c,u){var d,f,p,m=[],g=0,v="0",y=r&&[],b=null!=u,C=k,x=r||a&&_.find.TAG("*",u&&s.parentNode||s),N=W+=null==C?1:Math.random()||.1;for(b&&(k=s!==B&&s,w=n);null!=(d=x[v]);v++){if(a&&d){for(f=0;p=e[f++];)if(p(d,s,l)){c.push(d);break}b&&(W=N,w=++n)}i&&((d=!p&&d)&&g--,r&&y.push(d))}if(g+=v,i&&v!==g){for(f=0;p=t[f++];)p(y,m,s,l);if(r){if(g>0)for(;v--;)y[v]||m[v]||(m[v]=J.call(c));m=h(m)}Z.apply(c,m),b&&!r&&m.length>0&&g+t.length>1&&o.uniqueSort(c)}return b&&(W=N,k=C),y};return i?r(s):s}function y(e,t,n){for(var r=0,i=t.length;i>r;r++)o(e,t[r],n);return n}function b(e,t,n,r){var i,o,a,s,l,c=u(e);if(!r&&1===c.length){if(o=c[0]=c[0].slice(0),o.length>2&&"ID"===(a=o[0]).type&&9===t.nodeType&&L&&_.relative[o[1].type]){if(t=(_.find.ID(a.matches[0].replace(xt,wt),t)||[])[0],!t)return n;e=e.slice(o.shift().value.length)}for(i=pt.needsContext.test(e)?0:o.length;i--&&(a=o[i],!_.relative[s=a.type]);)if((l=_.find[s])&&(r=l(a.matches[0].replace(xt,wt),ht.test(o[0].type)&&t.parentNode||t))){if(o.splice(i,1),e=r.length&&d(o),!e)return Z.apply(n,r),n;break}}return S(e,c)(r,t,!L,n,ht.test(e)),n}function C(){}var x,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O,I="sizzle"+-new Date,F=window.document,z={},W=0,V=0,U=n(),q=n(),$=n(),j=!1,K=function(){return 0},G=typeof t,Y=1<<31,X=[],J=X.pop,Q=X.push,Z=X.push,et=X.slice,tt=X.indexOf||function(e){for(var t=0,n=this.length;n>t;t++)if(this[t]===e)return t;return-1},nt="[\\x20\\t\\r\\n\\f]",rt="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",it=rt.replace("w","w#"),ot="([*^$|!~]?=)",at="\\["+nt+"*("+rt+")"+nt+"*(?:"+ot+nt+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+it+")|)|)"+nt+"*\\]",st=":("+rt+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+at.replace(3,8)+")*)|.*)\\)|)",lt=new RegExp("^"+nt+"+|((?:^|[^\\\\])(?:\\\\.)*)"+nt+"+$","g"),ct=new RegExp("^"+nt+"*,"+nt+"*"),ut=new RegExp("^"+nt+"*([\\x20\\t\\r\\n\\f>+~])"+nt+"*"),dt=new RegExp(st),ft=new RegExp("^"+it+"$"),pt={ID:new RegExp("^#("+rt+")"),CLASS:new RegExp("^\\.("+rt+")"),NAME:new RegExp("^\\[name=['\"]?("+rt+")['\"]?\\]"),TAG:new RegExp("^("+rt.replace("w","w*")+")"),ATTR:new RegExp("^"+at),PSEUDO:new RegExp("^"+st),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+nt+"*(even|odd|(([+-]|)(\\d*)n|)"+nt+"*(?:([+-]|)"+nt+"*(\\d+)|))"+nt+"*\\)|)","i"),needsContext:new RegExp("^"+nt+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+nt+"*((?:-\\d)?\\d*)"+nt+"*\\)|)(?=[^-]|$)","i")},ht=/[\x20\t\r\n\f]*[+~]/,mt=/^[^{]+\{\s*\[native code/,gt=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,vt=/^(?:input|select|textarea|button)$/i,yt=/^h\d$/i,bt=/'|\\/g,Ct=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,xt=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,wt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320)};try{Z.apply(X=et.call(F.childNodes),F.childNodes),X[F.childNodes.length].nodeType}catch(_t){Z={apply:X.length?function(e,t){Q.apply(e,et.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}E=o.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},A=o.setDocument=function(n){var r=n?n.ownerDocument||n:F;return r!==B&&9===r.nodeType&&r.documentElement?(B=r,D=r.documentElement,L=!E(r),z.getElementsByTagName=i(function(e){return e.appendChild(r.createComment("")),!e.getElementsByTagName("*").length}),z.attributes=i(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),z.getElementsByClassName=i(function(e){return e.innerHTML="",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),z.getByName=i(function(e){e.id=I+0,e.appendChild(B.createElement("a")).setAttribute("name",I),e.appendChild(B.createElement("i")).setAttribute("name",I),D.appendChild(e);var t=r.getElementsByName&&r.getElementsByName(I).length===2+r.getElementsByName(I+0).length;return D.removeChild(e),t}),z.sortDetached=i(function(e){return e.compareDocumentPosition&&1&e.compareDocumentPosition(B.createElement("div"))}),_.attrHandle=i(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==G&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},z.getByName?(_.find.ID=function(e,t){if(typeof t.getElementById!==G&&L){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},_.filter.ID=function(e){var t=e.replace(xt,wt);return function(e){return e.getAttribute("id")===t}}):(_.find.ID=function(e,n){if(typeof n.getElementById!==G&&L){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==G&&r.getAttributeNode("id").value===e?[r]:t:[]}},_.filter.ID=function(e){var t=e.replace(xt,wt);return function(e){var n=typeof e.getAttributeNode!==G&&e.getAttributeNode("id");return n&&n.value===t}}),_.find.TAG=z.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==G?t.getElementsByTagName(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},_.find.NAME=z.getByName&&function(e,t){return typeof t.getElementsByName!==G?t.getElementsByName(name):void 0},_.find.CLASS=z.getElementsByClassName&&function(e,t){return typeof t.getElementsByClassName!==G&&L?t.getElementsByClassName(e):void 0},H=[],M=[":focus"],(z.qsa=e(r.querySelectorAll))&&(i(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||M.push("\\["+nt+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||M.push(":checked")}),i(function(e){e.innerHTML="",e.querySelectorAll("[i^='']").length&&M.push("[*^$]="+nt+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||M.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),M.push(",.*:")})),(z.matchesSelector=e(P=D.matchesSelector||D.mozMatchesSelector||D.webkitMatchesSelector||D.oMatchesSelector||D.msMatchesSelector))&&i(function(e){z.disconnectedMatch=P.call(e,"div"),P.call(e,"[s!='']:x"),H.push("!=",st)}),M=new RegExp(M.join("|")),H=H.length&&new RegExp(H.join("|")),O=e(D.contains)||D.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},K=D.compareDocumentPosition?function(e,t){if(e===t)return j=!0,0;var n=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return n?1&n||T&&t.compareDocumentPosition(e)===n?e===r||O(F,e)?-1:t===r||O(F,t)?1:R?tt.call(R,e)-tt.call(R,t):0:4&n?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var n,i=0,o=e.parentNode,s=t.parentNode,l=[e],c=[t];if(e===t)return j=!0,0;if(!o||!s)return e===r?-1:t===r?1:o?-1:s?1:0;if(o===s)return a(e,t);for(n=e;n=n.parentNode;)l.unshift(n);for(n=t;n=n.parentNode;)c.unshift(n);for(;l[i]===c[i];)i++;return i?a(l[i],c[i]):l[i]===F?-1:c[i]===F?1:0},B):B},o.matches=function(e,t){return o(e,null,null,t)},o.matchesSelector=function(e,t){if((e.ownerDocument||e)!==B&&A(e),t=t.replace(Ct,"='$1']"),z.matchesSelector&&L&&(!H||!H.test(t))&&!M.test(t))try{var n=P.call(e,t);if(n||z.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return o(t,B,null,[e]).length>0},o.contains=function(e,t){return(e.ownerDocument||e)!==B&&A(e),O(e,t)},o.attr=function(e,t){var n;return(e.ownerDocument||e)!==B&&A(e),L&&(t=t.toLowerCase()),(n=_.attrHandle[t])?n(e):!L||z.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},o.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},o.uniqueSort=function(e){var t,n=[],r=0,i=0;if(j=!z.detectDuplicates,T=!z.sortDetached,R=!z.sortStable&&e.slice(0),e.sort(K),j){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return e},N=o.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=N(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=N(t);return n},_=o.selectors={cacheLength:50,createPseudo:r,match:pt,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(xt,wt),e[3]=(e[4]||e[5]||"").replace(xt,wt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||o.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&o.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return pt.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&dt.test(n)&&(t=u(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(xt,wt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=U[e+" "];return t||(t=new RegExp("(^|"+nt+")"+e+"("+nt+"|$)"))&&U(e,function(e){return t.test(e.className||typeof e.getAttribute!==G&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=o.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var c,u,d,f,p,h,m=o!==a?"nextSibling":"previousSibling",g=t.parentNode,v=s&&t.nodeName.toLowerCase(),y=!l&&!s;if(g){if(o){for(;m;){for(d=t;d=d[m];)if(s?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;h=m="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?g.firstChild:g.lastChild],a&&y){for(u=g[I]||(g[I]={}),c=u[e]||[],p=c[0]===W&&c[1],f=c[0]===W&&c[2],d=p&&g.childNodes[p];d=++p&&d&&d[m]||(f=p=0)||h.pop();)if(1===d.nodeType&&++f&&d===t){u[e]=[W,p,f];break}}else if(y&&(c=(t[I]||(t[I]={}))[e])&&c[0]===W)f=c[1];else for(;(d=++p&&d&&d[m]||(f=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++f||(y&&((d[I]||(d[I]={}))[e]=[W,f]),d!==t)););return f-=i,f===r||f%r===0&&f/r>=0}}},PSEUDO:function(e,t){var n,i=_.pseudos[e]||_.setFilters[e.toLowerCase()]||o.error("unsupported pseudo: "+e);return i[I]?i(t):i.length>1?(n=[e,e,"",t],_.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,n){for(var r,o=i(e,t),a=o.length;a--;)r=tt.call(e,o[a]),e[r]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:r(function(e){var t=[],n=[],i=S(e.replace(lt,"$1"));return i[I]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),!n.pop()}}),has:r(function(e){return function(t){return o(e,t).length>0}}),contains:r(function(e){return function(t){return(t.textContent||t.innerText||N(t)).indexOf(e)>-1}}),lang:r(function(e){return ft.test(e||"")||o.error("unsupported lang: "+e),e=e.replace(xt,wt).toLowerCase(),function(t){var n;do if(n=L?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(e){var t=window.location&&window.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===D},focus:function(e){return e===B.activeElement&&(!B.hasFocus||B.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!_.pseudos.empty(e)},header:function(e){return yt.test(e.nodeName)},input:function(e){return vt.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:c(function(){return[0]}),last:c(function(e,t){return[t-1]}),eq:c(function(e,t,n){return[0>n?n+t:n]}),even:c(function(e,t){for(var n=0;t>n;n+=2)e.push(n);return e}),odd:c(function(e,t){for(var n=1;t>n;n+=2)e.push(n);return e}),lt:c(function(e,t,n){for(var r=0>n?n+t:n;--r>=0;)e.push(r);return e}),gt:c(function(e,t,n){for(var r=0>n?n+t:n;++rn;n++)t[n]=e[n];return t}function f(e,t){var n;if(t.indexOf)return t.indexOf(e);for(n=t.length;n--;)if(t[n]===e)return n;return-1}function p(e){return null===e||e===t?"":(""+e).replace(N,"")}function h(e,t){var n,r,i,o,a;if(e)if(n=e.length,n===o){for(r in e)if(e.hasOwnProperty(r)&&(a=e[r],t.call(a,a,r)===!1))break}else for(i=0;n>i&&(a=e[i],t.call(a,a,r)!==!1);i++);return e}function m(e,n,r){for(var i=[],o=e[n];o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!c(o).is(r));)1===o.nodeType&&i.push(o),o=o[n];return i}function g(e,t,n,r){for(var i=[];e;e=e[n])r&&e.nodeType!==r||e===t||i.push(e);return i}var v=document,y=Array.prototype.push,b=Array.prototype.slice,C=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,x=e.Event,w=l("fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom"),_=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)},N=/^\s*|\s*$/g;return c.fn=c.prototype={constructor:c,selector:"",length:0,init:function(e,t){var n=this,r,a;if(!e)return n;if(e.nodeType)return n.context=n[0]=e,n.length=1,n;if(i(e)){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:C.exec(e),!r)return c(t||document).find(e);if(r[1])for(a=o(e).firstChild;a;)this.add(a),a=a.nextSibling;else{if(a=v.getElementById(r[2]),a.id!==r[2])return n.find(e);n.length=1,n[0]=a}}else this.add(e);return n},toArray:function(){return d(this)},add:function(e){var t=this;return _(e)?y.apply(t,e):e instanceof c?t.add(e.toArray()):y.call(t,e),t},attr:function(e,n){var i=this;if("object"==typeof e)h(e,function(e,t){i.attr(t,e)});else{if(!r(n))return i[0]&&1===i[0].nodeType?i[0].getAttribute(e):t;this.each(function(){1===this.nodeType&&this.setAttribute(e,n)})}return i},css:function(e,n){var i=this;if("object"==typeof e)h(e,function(e,t){i.css(t,e)});else{if(e=e.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),!r(n))return i[0]?i[0].style[e]:t;"number"!=typeof n||w[e]||(n+="px"),i.each(function(){var t=this.style;"opacity"===e&&this.runtimeStyle&&"undefined"==typeof this.runtimeStyle.opacity&&(t.filter=""===n?"":"alpha(opacity="+100*n+")");try{t[e]=n}catch(r){}})}return i},remove:function(){for(var e=this,t,n=this.length;n--;)t=e[n],x.clean(t),t.parentNode&&t.parentNode.removeChild(t);return this},empty:function(){for(var e=this,t,n=this.length;n--;)for(t=e[n];t.firstChild;)t.removeChild(t.firstChild);return this},html:function(e){var t=this,n;if(r(e)){for(n=t.length;n--;)t[n].innerHTML=e;return t}return t[0]?t[0].innerHTML:""},text:function(e){var t=this,n;if(r(e)){for(n=t.length;n--;)t[n].innerText=t[0].textContent=e;return t}return t[0]?t[0].innerText||t[0].textContent:""},append:function(){return a(this,arguments,function(e){1===this.nodeType&&this.appendChild(e)})},prepend:function(){return a(this,arguments,function(e){1===this.nodeType&&this.insertBefore(e,this.firstChild)})},before:function(){var e=this;return e[0]&&e[0].parentNode?a(e,arguments,function(e){this.parentNode.insertBefore(e,this.nextSibling)}):e},after:function(){var e=this;return e[0]&&e[0].parentNode?a(e,arguments,function(e){this.parentNode.insertBefore(e,this)}):e},appendTo:function(e){return c(e).append(this),this},addClass:function(e){return this.toggleClass(e,!0)},removeClass:function(e){return this.toggleClass(e,!1)},toggleClass:function(e,t){var n=this;return-1!==e.indexOf(" ")?h(e.split(" "),function(){n.toggleClass(this,t)}):n.each(function(n){var r;s(n,e)!==t&&(r=n.className,t?n.className+=r?" "+e:e:n.className=p((" "+r+" ").replace(" "+e+" "," ")))}),n},hasClass:function(e){return s(this[0],e)},each:function(e){return h(this,e)},on:function(e,t){return this.each(function(){x.bind(this,e,t)})},off:function(e,t){return this.each(function(){x.unbind(this,e,t)})},show:function(){return this.css("display","")},hide:function(){return this.css("display","none")},slice:function(){return new c(b.apply(this,arguments))},eq:function(e){return-1===e?this.slice(e):this.slice(e,+e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},replaceWith:function(e){var t=this;return t[0]&&t[0].parentNode.replaceChild(c(e)[0],t[0]),t},wrap:function(e){return e=c(e)[0],this.each(function(){var t=this,n=e.cloneNode(!1);t.parentNode.insertBefore(n,t),n.appendChild(t)})},unwrap:function(){return this.each(function(){for(var e=this,t=e.firstChild,n;t;)n=t,t=t.nextSibling,e.parentNode.insertBefore(n,e)})},clone:function(){var e=[];return this.each(function(){e.push(this.cloneNode(!0))}),c(e)},find:function(e){var t,n,r=[];for(t=0,n=this.length;n>t;t++)c.find(e,this[t],r);return c(r)},push:y,sort:[].sort,splice:[].splice},u(c,{extend:u,toArray:d,inArray:f,isArray:_,each:h,trim:p,makeMap:l,find:n,expr:n.selectors,unique:n.uniqueSort,text:n.getText,isXMLDoc:n.isXML,contains:n.contains,filter:function(e,t,n){return n&&(e=":not("+e+")"),t=1===t.length?c.find.matchesSelector(t[0],e)?[t[0]]:[]:c.find.matches(e,t)}}),h({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return m(e,"parentNode")},parentsUntil:function(e,t){return m(e,"parentNode",t)},next:function(e){return g(e,"nextSibling",1)},prev:function(e){return g(e,"previousSibling",1)},nextNodes:function(e){return g(e,"nextSibling")},prevNodes:function(e){return g(e,"previousSibling")},children:function(e){return g(e.firstChild,"nextSibling",1)},contents:function(e){return d(("iframe"===e.nodeName?e.contentDocument||e.contentWindow.document:e).childNodes)}},function(e,t){c.fn[e]=function(n){var r=this,i;if(r.length>1)throw new Error("DomQuery only supports traverse functions on a single node.");return r[0]&&(i=t(r[0],n)),i=c(i),n&&"parentsUntil"!==e?i.filter(n):i}}),c.fn.filter=function(e){return c.filter(e)},c.fn.is=function(e){return!!e&&this.filter(e).length>0},c.fn.init.prototype=c.fn,c}),r(d,[],function(){return function(e,t){function n(e,t,n,r){function i(e){return e=parseInt(e,10).toString(16),e.length>1?e:"0"+e +}return"#"+i(t)+i(n)+i(r)}var r=/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,i=/(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,o=/\s*([^:]+):\s*([^;]+);?/g,a=/\s+$/,s,l,c={},u,d="\ufeff";for(e=e||{},u=("\\\" \\' \\; \\: ; : "+d).split(" "),l=0;l-1&&n||(m[e+t]=-1==l?s[0]:s.join(" "),delete m[e+"-top"+t],delete m[e+"-right"+t],delete m[e+"-bottom"+t],delete m[e+"-left"+t])}}function u(e){var t=m[e],n;if(t){for(t=t.split(" "),n=t.length;n--;)if(t[n]!==t[0])return!1;return m[e]=t[0],!0}}function d(e,t,n,r){u(t)&&u(n)&&u(r)&&(m[e]=m[t]+" "+m[n]+" "+m[r],delete m[t],delete m[n],delete m[r])}function f(e){return b=!0,c[e]}function p(e,t){return b&&(e=e.replace(/\uFEFF[0-9]/g,function(e){return c[e]})),t||(e=e.replace(/\\([\'\";:])/g,"$1")),e}function h(t,n,r,i,o,a){if(o=o||a)return o=p(o),"'"+o.replace(/\'/g,"\\'")+"'";if(n=p(n||r||i),!e.allow_script_urls){var s=n.replace(/[\s\r\n]+/,"");if(/(java|vb)script:/i.test(s))return"";if(!e.allow_svg_data_urls&&/^data:image\/svg/i.test(s))return""}return C&&(n=C.call(x,n,"style")),"url('"+n.replace(/\'/g,"\\'")+"')"}var m={},g,v,y,b,C=e.url_converter,x=e.url_converter_scope||this;if(t){for(t=t.replace(/[\u0000-\u001F]/g,""),t=t.replace(/\\[\"\';:\uFEFF]/g,f).replace(/\"[^\"]+\"|\'[^\']+\'/g,function(e){return e.replace(/[;:]/g,f)});g=o.exec(t);){if(v=g[1].replace(a,"").toLowerCase(),y=g[2].replace(a,""),y=y.replace(/\\[0-9a-f]+/g,function(e){return String.fromCharCode(parseInt(e.substr(1),16))}),v&&y.length>0){if(!e.allow_script_urls&&("behavior"==v||/expression\s*\(|\/\*|\*\//.test(y)))continue;"font-weight"===v&&"700"===y?y="bold":("color"===v||"background-color"===v)&&(y=y.toLowerCase()),y=y.replace(r,n),y=y.replace(i,h),m[v]=b?p(y,!0):y}o.lastIndex=g.index+g[0].length}s("border","",!0),s("border","-width"),s("border","-color"),s("border","-style"),s("padding",""),s("margin",""),d("border","border-width","border-style","border-color"),"medium none"===m.border&&delete m.border,"none"===m["border-image"]&&delete m["border-image"]}return m},serialize:function(e,n){function r(n){var r,o,a,l;if(r=t.styles[n])for(o=0,a=r.length;a>o;o++)n=r[o],l=e[n],l!==s&&l.length>0&&(i+=(i.length>0?" ":"")+n+": "+l+";")}var i="",o,a;if(n&&t&&t.styles)r("*"),r(n);else for(o in e)a=e[o],a!==s&&a.length>0&&(i+=(i.length>0?" ":"")+o+": "+a+";");return i}}}}),r(f,[],function(){return function(e,t){function n(e,n,r,i){var o,a;if(e){if(!i&&e[n])return e[n];if(e!=t){if(o=e[r])return o;for(a=e.parentNode;a&&a!=t;a=a.parentNode)if(o=a[r])return o}}}var r=e;this.current=function(){return r},this.next=function(e){return r=n(r,"firstChild","nextSibling",e)},this.prev=function(e){return r=n(r,"lastChild","previousSibling",e)}}}),r(p,[],function(){function e(e){return null===e||e===t?"":(""+e).replace(m,"")}function n(e,n){return n?"array"==n&&g(e)?!0:typeof e==n:e!==t}function r(e){var t=[],n,r;for(n=0,r=e.length;r>n;n++)t[n]=e[n];return t}function i(e,t,n){var r;for(e=e||[],t=t||",","string"==typeof e&&(e=e.split(t)),n=n||{},r=e.length;r--;)n[e[r]]={};return n}function o(e,n,r){var i,o;if(!e)return 0;if(r=r||e,e.length!==t){for(i=0,o=e.length;o>i;i++)if(n.call(r,e[i],i,e)===!1)return 0}else for(i in e)if(e.hasOwnProperty(i)&&n.call(r,e[i],i,e)===!1)return 0;return 1}function a(e,t){var n=[];return o(e,function(e){n.push(t(e))}),n}function s(e,t){var n=[];return o(e,function(e){(!t||t(e))&&n.push(e)}),n}function l(e,t,n){var r=this,i,o,a,s,l,c=0;if(e=/^((static) )?([\w.]+)(:([\w.]+))?/.exec(e),a=e[3].match(/(^|\.)(\w+)$/i)[2],o=r.createNS(e[3].replace(/\.\w+$/,""),n),!o[a]){if("static"==e[2])return o[a]=t,void(this.onCreate&&this.onCreate(e[2],e[3],o[a]));t[a]||(t[a]=function(){},c=1),o[a]=t[a],r.extend(o[a].prototype,t),e[5]&&(i=r.resolve(e[5]).prototype,s=e[5].match(/\.(\w+)$/i)[1],l=o[a],o[a]=c?function(){return i[s].apply(this,arguments)}:function(){return this.parent=i[s],l.apply(this,arguments)},o[a].prototype[a]=o[a],r.each(i,function(e,t){o[a].prototype[t]=i[t]}),r.each(t,function(e,t){i[t]?o[a].prototype[t]=function(){return this.parent=i[t],e.apply(this,arguments)}:t!=a&&(o[a].prototype[t]=e)})),r.each(t["static"],function(e,t){o[a][t]=e})}}function c(e,t){var n,r;if(e)for(n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}function u(e,n){var r,i,o,a=arguments,s;for(r=1,i=a.length;i>r;r++){n=a[r];for(o in n)n.hasOwnProperty(o)&&(s=n[o],s!==t&&(e[o]=s))}return e}function d(e,t,n,r){r=r||this,e&&(n&&(e=e[n]),o(e,function(e,i){return t.call(r,e,i,n)===!1?!1:void d(e,t,n,r)}))}function f(e,t){var n,r;for(t=t||window,e=e.split("."),n=0;nn&&(t=t[e[n]],t);n++);return t}function h(t,r){return!t||n(t,"array")?t:a(t.split(r||","),e)}var m=/^\s*|\s*$/g,g=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)};return{trim:e,isArray:g,is:n,toArray:r,makeMap:i,each:o,map:a,grep:s,inArray:c,extend:u,create:l,walk:d,createNS:f,resolve:p,explode:h}}),r(h,[p],function(e){function t(n){function r(){return H.createDocumentFragment()}function i(e,t){_(F,e,t)}function o(e,t){_(z,e,t)}function a(e){i(e.parentNode,j(e))}function s(e){i(e.parentNode,j(e)+1)}function l(e){o(e.parentNode,j(e))}function c(e){o(e.parentNode,j(e)+1)}function u(e){e?(M[U]=M[V],M[q]=M[W]):(M[V]=M[U],M[W]=M[q]),M.collapsed=F}function d(e){a(e),c(e)}function f(e){i(e,0),o(e,1===e.nodeType?e.childNodes.length:e.nodeValue.length)}function p(e,t){var n=M[V],r=M[W],i=M[U],o=M[q],a=t.startContainer,s=t.startOffset,l=t.endContainer,c=t.endOffset;return 0===e?w(n,r,a,s):1===e?w(i,o,a,s):2===e?w(i,o,l,c):3===e?w(n,r,l,c):void 0}function h(){N(I)}function m(){return N(P)}function g(){return N(O)}function v(e){var t=this[V],r=this[W],i,o;3!==t.nodeType&&4!==t.nodeType||!t.nodeValue?(t.childNodes.length>0&&(o=t.childNodes[r]),o?t.insertBefore(e,o):3==t.nodeType?n.insertAfter(e,t):t.appendChild(e)):r?r>=t.nodeValue.length?n.insertAfter(e,t):(i=t.splitText(r),t.parentNode.insertBefore(e,i)):t.parentNode.insertBefore(e,t)}function y(e){var t=M.extractContents();M.insertNode(e),e.appendChild(t),M.selectNode(e)}function b(){return $(new t(n),{startContainer:M[V],startOffset:M[W],endContainer:M[U],endOffset:M[q],collapsed:M.collapsed,commonAncestorContainer:M.commonAncestorContainer})}function C(e,t){var n;if(3==e.nodeType)return e;if(0>t)return e;for(n=e.firstChild;n&&t>0;)--t,n=n.nextSibling;return n?n:e}function x(){return M[V]==M[U]&&M[W]==M[q]}function w(e,t,r,i){var o,a,s,l,c,u;if(e==r)return t==i?0:i>t?-1:1;for(o=r;o&&o.parentNode!=e;)o=o.parentNode;if(o){for(a=0,s=e.firstChild;s!=o&&t>a;)a++,s=s.nextSibling;return a>=t?-1:1}for(o=e;o&&o.parentNode!=r;)o=o.parentNode;if(o){for(a=0,s=r.firstChild;s!=o&&i>a;)a++,s=s.nextSibling;return i>a?-1:1}for(l=n.findCommonAncestor(e,r),c=e;c&&c.parentNode!=l;)c=c.parentNode;for(c||(c=l),u=r;u&&u.parentNode!=l;)u=u.parentNode;if(u||(u=l),c==u)return 0;for(s=l.firstChild;s;){if(s==c)return-1;if(s==u)return 1;s=s.nextSibling}}function _(e,t,r){var i,o;for(e?(M[V]=t,M[W]=r):(M[U]=t,M[q]=r),i=M[U];i.parentNode;)i=i.parentNode;for(o=M[V];o.parentNode;)o=o.parentNode;o==i?w(M[V],M[W],M[U],M[q])>0&&M.collapse(e):M.collapse(e),M.collapsed=x(),M.commonAncestorContainer=n.findCommonAncestor(M[V],M[U])}function N(e){var t,n=0,r=0,i,o,a,s,l,c;if(M[V]==M[U])return E(e);for(t=M[U],i=t.parentNode;i;t=i,i=i.parentNode){if(i==M[V])return S(t,e);++n}for(t=M[V],i=t.parentNode;i;t=i,i=i.parentNode){if(i==M[U])return k(t,e);++r}for(o=r-n,a=M[V];o>0;)a=a.parentNode,o--;for(s=M[U];0>o;)s=s.parentNode,o++;for(l=a.parentNode,c=s.parentNode;l!=c;l=l.parentNode,c=c.parentNode)a=l,s=c;return T(a,s,e)}function E(e){var t,n,i,o,a,s,l,c,u;if(e!=I&&(t=r()),M[W]==M[q])return t;if(3==M[V].nodeType){if(n=M[V].nodeValue,i=n.substring(M[W],M[q]),e!=O&&(o=M[V],c=M[W],u=M[q]-M[W],0===c&&u>=o.nodeValue.length-1?o.parentNode.removeChild(o):o.deleteData(c,u),M.collapse(F)),e==I)return;return i.length>0&&t.appendChild(H.createTextNode(i)),t}for(o=C(M[V],M[W]),a=M[q]-M[W];o&&a>0;)s=o.nextSibling,l=D(o,e),t&&t.appendChild(l),--a,o=s;return e!=O&&M.collapse(F),t}function S(e,t){var n,i,o,a,s,l;if(t!=I&&(n=r()),i=R(e,t),n&&n.appendChild(i),o=j(e),a=o-M[W],0>=a)return t!=O&&(M.setEndBefore(e),M.collapse(z)),n;for(i=e.previousSibling;a>0;)s=i.previousSibling,l=D(i,t),n&&n.insertBefore(l,n.firstChild),--a,i=s;return t!=O&&(M.setEndBefore(e),M.collapse(z)),n}function k(e,t){var n,i,o,a,s,l;for(t!=I&&(n=r()),o=A(e,t),n&&n.appendChild(o),i=j(e),++i,a=M[q]-i,o=e.nextSibling;o&&a>0;)s=o.nextSibling,l=D(o,t),n&&n.appendChild(l),--a,o=s;return t!=O&&(M.setStartAfter(e),M.collapse(F)),n}function T(e,t,n){var i,o,a,s,l,c,u;for(n!=I&&(o=r()),i=A(e,n),o&&o.appendChild(i),a=j(e),s=j(t),++a,l=s-a,c=e.nextSibling;l>0;)u=c.nextSibling,i=D(c,n),o&&o.appendChild(i),c=u,--l;return i=R(t,n),o&&o.appendChild(i),n!=O&&(M.setStartAfter(e),M.collapse(F)),o}function R(e,t){var n=C(M[U],M[q]-1),r,i,o,a,s,l=n!=M[U];if(n==e)return B(n,l,z,t);for(r=n.parentNode,i=B(r,z,z,t);r;){for(;n;)o=n.previousSibling,a=B(n,l,z,t),t!=I&&i.insertBefore(a,i.firstChild),l=F,n=o;if(r==e)return i;n=r.previousSibling,r=r.parentNode,s=B(r,z,z,t),t!=I&&s.appendChild(i),i=s}}function A(e,t){var n=C(M[V],M[W]),r=n!=M[V],i,o,a,s,l;if(n==e)return B(n,r,F,t);for(i=n.parentNode,o=B(i,z,F,t);i;){for(;n;)a=n.nextSibling,s=B(n,r,F,t),t!=I&&o.appendChild(s),r=F,n=a;if(i==e)return o;n=i.nextSibling,i=i.parentNode,l=B(i,z,F,t),t!=I&&l.appendChild(o),o=l}}function B(e,t,r,i){var o,a,s,l,c;if(t)return D(e,i);if(3==e.nodeType){if(o=e.nodeValue,r?(l=M[W],a=o.substring(l),s=o.substring(0,l)):(l=M[q],a=o.substring(0,l),s=o.substring(l)),i!=O&&(e.nodeValue=s),i==I)return;return c=n.clone(e,z),c.nodeValue=a,c}if(i!=I)return n.clone(e,z)}function D(e,t){return t!=I?t==O?n.clone(e,F):e:void e.parentNode.removeChild(e)}function L(){return n.create("body",null,g()).outerText}var M=this,H=n.doc,P=0,O=1,I=2,F=!0,z=!1,W="startOffset",V="startContainer",U="endContainer",q="endOffset",$=e.extend,j=n.nodeIndex;return $(M,{startContainer:H,startOffset:0,endContainer:H,endOffset:0,collapsed:F,commonAncestorContainer:H,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3,setStart:i,setEnd:o,setStartBefore:a,setStartAfter:s,setEndBefore:l,setEndAfter:c,collapse:u,selectNode:d,selectNodeContents:f,compareBoundaryPoints:p,deleteContents:h,extractContents:m,cloneContents:g,insertNode:v,surroundContents:y,cloneRange:b,toStringIE:L}),M}return t.prototype.toString=function(){return this.toStringIE()},t}),r(m,[p],function(e){function t(e){var t;return t=document.createElement("div"),t.innerHTML=e,t.textContent||t.innerText||e}function n(e,t){var n,r,i,a={};if(e){for(e=e.split(","),t=t||10,n=0;n\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,l=/[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,c=/[<>&\"\']/g,u=/&(#x|#)?([\w]+);/g,d={128:"\u20ac",130:"\u201a",131:"\u0192",132:"\u201e",133:"\u2026",134:"\u2020",135:"\u2021",136:"\u02c6",137:"\u2030",138:"\u0160",139:"\u2039",140:"\u0152",142:"\u017d",145:"\u2018",146:"\u2019",147:"\u201c",148:"\u201d",149:"\u2022",150:"\u2013",151:"\u2014",152:"\u02dc",153:"\u2122",154:"\u0161",155:"\u203a",156:"\u0153",158:"\u017e",159:"\u0178"};o={'"':""","'":"'","<":"<",">":">","&":"&","`":"`"},a={"<":"<",">":">","&":"&",""":'"',"'":"'"},i=n("50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,t9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro",32);var f={encodeRaw:function(e,t){return e.replace(t?s:l,function(e){return o[e]||e})},encodeAllRaw:function(e){return(""+e).replace(c,function(e){return o[e]||e})},encodeNumeric:function(e,t){return e.replace(t?s:l,function(e){return e.length>1?"&#"+(1024*(e.charCodeAt(0)-55296)+(e.charCodeAt(1)-56320)+65536)+";":o[e]||"&#"+e.charCodeAt(0)+";"})},encodeNamed:function(e,t,n){return n=n||i,e.replace(t?s:l,function(e){return o[e]||n[e]||e})},getEncodeFunc:function(e,t){function a(e,n){return e.replace(n?s:l,function(e){return o[e]||t[e]||"&#"+e.charCodeAt(0)+";"||e})}function c(e,n){return f.encodeNamed(e,n,t)}return t=n(t)||i,e=r(e.replace(/\+/g,",")),e.named&&e.numeric?a:e.named?t?c:f.encodeNamed:e.numeric?f.encodeNumeric:f.encodeRaw},decode:function(e){return e.replace(u,function(e,n,r){return n?(r=parseInt(r,2===n.length?16:10),r>65535?(r-=65536,String.fromCharCode(55296+(r>>10),56320+(1023&r))):d[r]||String.fromCharCode(r)):a[e]||i[e]||t(e)})}};return f}),r(g,[],function(){var e=navigator,t=e.userAgent,n,r,i,o,a,s,l;n=window.opera&&window.opera.buildNumber,r=/WebKit/.test(t),i=!r&&!n&&/MSIE/gi.test(t)&&/Explorer/gi.test(e.appName),i=i&&/MSIE (\w+)\./.exec(t)[1],o=-1==t.indexOf("Trident/")||-1==t.indexOf("rv:")&&-1==e.appName.indexOf("Netscape")?!1:11,i=i||o,a=!r&&!o&&/Gecko/.test(t),s=-1!=t.indexOf("Mac"),l=/(iPad|iPhone)/.test(t);var c=!l||t.match(/AppleWebKit\/(\d*)/)[1]>=534;return{opera:n,webkit:r,ie:i,gecko:a,mac:s,iOS:l,contentEditable:c,transparentSrc:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",caretAfter:8!=i,range:window.getSelection&&"Range"in window,documentMode:i?document.documentMode||7:10}}),r(v,[],function(){return function(e,t){function n(t){e.getElementsByTagName("head")[0].appendChild(t)}function r(t,r,s){function l(){for(var e=v.passed,t=e.length;t--;)e[t]();v.status=2,v.passed=[],v.failed=[]}function c(){for(var e=v.failed,t=e.length;t--;)e[t]();v.status=3,v.passed=[],v.failed=[]}function u(){var e=navigator.userAgent.match(/WebKit\/(\d*)/);return!!(e&&e[1]<536)}function d(e,t){e()||((new Date).getTime()-g0)return m=e.createElement("style"),m.textContent='@import "'+t+'"',p(),void n(m);f()}n(h),h.href=t}}var i=0,o={},a;t=t||{},a=t.maxLoadTime||5e3,this.load=r}}),r(y,[c,d,l,f,h,m,g,p,v],function(e,n,r,i,o,a,s,l,c){function u(e,t){var i=this,o;i.doc=e,i.win=window,i.files={},i.counter=0,i.stdMode=!v||e.documentMode>=8,i.boxModel=!v||"CSS1Compat"==e.compatMode||i.stdMode,i.hasOuterHTML="outerHTML"in e.createElement("a"),i.styleSheetLoader=new c(e),this.boundEvents=[],i.settings=t=m({keep_values:!1,hex_colors:1},t),i.schema=t.schema,i.styles=new n({url_converter:t.url_converter,url_converter_scope:t.url_converter_scope},t.schema),i.fixDoc(e),i.events=t.ownEvents?new r(t.proxy):r.Event,o=t.schema?t.schema.getBlockElements():{},i.isBlock=function(e){if(!e)return!1;var t=e.nodeType;return t?!(1!==t||!o[e.nodeName]):!!o[e]}}var d=l.each,f=l.is,p=l.grep,h=l.trim,m=l.extend,g=s.webkit,v=s.ie,y=/^([a-z0-9],?)+$/i,b=/^[ \t\r\n]*$/,C=l.makeMap("fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom"," ");return u.prototype={root:null,props:{"for":"htmlFor","class":"className",className:"className",checked:"checked",disabled:"disabled",maxlength:"maxLength",readonly:"readOnly",selected:"selected",value:"value",id:"id",name:"name",type:"type"},fixDoc:function(e){var t=this.settings,n;if(v&&t.schema){"abbr article aside audio canvas details figcaption figure footer header hgroup mark menu meter nav output progress section summary time video".replace(/\w+/g,function(t){e.createElement(t)});for(n in t.schema.getCustomElements())e.createElement(n)}},clone:function(e,t){var n=this,r,i;return!v||1!==e.nodeType||t?e.cloneNode(t):(i=n.doc,t?r.firstChild:(r=i.createElement(e.nodeName),d(n.getAttribs(e),function(t){n.setAttrib(r,t.nodeName,n.getAttrib(e,t.nodeName))}),r))},getRoot:function(){var e=this;return e.get(e.settings.root_element)||e.doc.body},getViewPort:function(e){var t,n;return e=e?e:this.win,t=e.document,n=this.boxModel?t.documentElement:t.body,{x:e.pageXOffset||n.scrollLeft,y:e.pageYOffset||n.scrollTop,w:e.innerWidth||n.clientWidth,h:e.innerHeight||n.clientHeight}},getRect:function(e){var t=this,n,r;return e=t.get(e),n=t.getPos(e),r=t.getSize(e),{x:n.x,y:n.y,w:r.w,h:r.h}},getSize:function(e){var t=this,n,r;return e=t.get(e),n=t.getStyle(e,"width"),r=t.getStyle(e,"height"),-1===n.indexOf("px")&&(n=0),-1===r.indexOf("px")&&(r=0),{w:parseInt(n,10)||e.offsetWidth||e.clientWidth,h:parseInt(r,10)||e.offsetHeight||e.clientHeight}},getParent:function(e,t,n){return this.getParents(e,t,n,!1)},getParents:function(e,n,r,i){var o=this,a,s=[];for(e=o.get(e),i=i===t,r=r||("BODY"!=o.getRoot().nodeName?o.getRoot().parentNode:null),f(n,"string")&&(a=n,n="*"===n?function(e){return 1==e.nodeType}:function(e){return o.is(e,a)});e&&e!=r&&e.nodeType&&9!==e.nodeType;){if(!n||n(e)){if(!i)return e;s.push(e)}e=e.parentNode}return i?s:null},get:function(e){var t;return e&&this.doc&&"string"==typeof e&&(t=e,e=this.doc.getElementById(e),e&&e.id!==t)?this.doc.getElementsByName(t)[1]:e},getNext:function(e,t){return this._findSib(e,t,"nextSibling")},getPrev:function(e,t){return this._findSib(e,t,"previousSibling")},select:function(t,n){var r=this;return e(t,r.get(n)||r.get(r.settings.root_element)||r.doc,[])},is:function(n,r){var i;if(n.length===t){if("*"===r)return 1==n.nodeType;if(y.test(r)){for(r=r.toLowerCase().split(/,/),n=n.nodeName.toLowerCase(),i=r.length-1;i>=0;i--)if(r[i]==n)return!0;return!1}}if(n.nodeType&&1!=n.nodeType)return!1;var o=n.nodeType?[n]:n;return e(r,o[0].ownerDocument||o[0],null,o).length>0},add:function(e,t,n,r,i){var o=this;return this.run(e,function(e){var a;return a=f(t,"string")?o.doc.createElement(t):t,o.setAttribs(a,n),r&&(r.nodeType?a.appendChild(r):o.setHTML(a,r)),i?a:e.appendChild(a)})},create:function(e,t,n){return this.add(this.doc.createElement(e),e,t,n,1)},createHTML:function(e,t,n){var r="",i;r+="<"+e;for(i in t)t.hasOwnProperty(i)&&null!==t[i]&&(r+=" "+i+'="'+this.encode(t[i])+'"');return"undefined"!=typeof n?r+">"+n+"":r+" />"},createFragment:function(e){var t,n,r=this.doc,i;for(i=r.createElement("div"),t=r.createDocumentFragment(),e&&(i.innerHTML=e);n=i.firstChild;)t.appendChild(n);return t},remove:function(e,t){return this.run(e,function(e){var n,r=e.parentNode;if(!r)return null;if(t)for(;n=e.firstChild;)!v||3!==n.nodeType||n.nodeValue?r.insertBefore(n,e):e.removeChild(n);return r.removeChild(e)})},setStyle:function(e,t,n){return this.run(e,function(e){var r=this,i,o;if(t)if("string"==typeof t){i=e.style,t=t.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),"number"!=typeof n||C[t]||(n+="px"),"opacity"===t&&e.runtimeStyle&&"undefined"==typeof e.runtimeStyle.opacity&&(i.filter=""===n?"":"alpha(opacity="+100*n+")"),"float"==t&&(t="cssFloat"in e.style?"cssFloat":"styleFloat");try{i[t]=n}catch(a){}r.settings.update_styles&&e.removeAttribute("data-mce-style")}else for(o in t)r.setStyle(e,o,t[o])})},getStyle:function(e,n,r){if(e=this.get(e)){if(this.doc.defaultView&&r){n=n.replace(/[A-Z]/g,function(e){return"-"+e});try{return this.doc.defaultView.getComputedStyle(e,null).getPropertyValue(n)}catch(i){return null}}return n=n.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),"float"==n&&(n=v?"styleFloat":"cssFloat"),e.currentStyle&&r?e.currentStyle[n]:e.style?e.style[n]:t}},setStyles:function(e,t){this.setStyle(e,t)},css:function(e,t,n){this.setStyle(e,t,n)},removeAllAttribs:function(e){return this.run(e,function(e){var t,n=e.attributes;for(t=n.length-1;t>=0;t--)e.removeAttributeNode(n.item(t))})},setAttrib:function(e,t,n){var r=this;if(e&&t)return this.run(e,function(e){var i=r.settings,o=e.getAttribute(t);if(null!==n)switch(t){case"style":if(!f(n,"string"))return void d(n,function(t,n){r.setStyle(e,n,t)});i.keep_values&&(n?e.setAttribute("data-mce-style",n,2):e.removeAttribute("data-mce-style",2)),e.style.cssText=n;break;case"class":e.className=n||"";break;case"src":case"href":i.keep_values&&(i.url_converter&&(n=i.url_converter.call(i.url_converter_scope||r,n,t,e)),r.setAttrib(e,"data-mce-"+t,n,2));break;case"shape":e.setAttribute("data-mce-style",n)}f(n)&&null!==n&&0!==n.length?e.setAttribute(t,""+n,2):e.removeAttribute(t,2),o!=n&&i.onSetAttrib&&i.onSetAttrib({attrElm:e,attrName:t,attrValue:n})})},setAttribs:function(e,t){var n=this;return this.run(e,function(e){d(t,function(t,r){n.setAttrib(e,r,t)})})},getAttrib:function(e,t,n){var r,i=this,o;if(e=i.get(e),!e||1!==e.nodeType)return n===o?!1:n;if(f(n)||(n=""),/^(src|href|style|coords|shape)$/.test(t)&&(r=e.getAttribute("data-mce-"+t)))return r;if(v&&i.props[t]&&(r=e[i.props[t]],r=r&&r.nodeValue?r.nodeValue:r),r||(r=e.getAttribute(t,2)),/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(t))return e[i.props[t]]===!0&&""===r?t:r?t:"";if("FORM"===e.nodeName&&e.getAttributeNode(t))return e.getAttributeNode(t).nodeValue;if("style"===t&&(r=r||e.style.cssText,r&&(r=i.serializeStyle(i.parseStyle(r),e.nodeName),i.settings.keep_values&&e.setAttribute("data-mce-style",r))),g&&"class"===t&&r&&(r=r.replace(/(apple|webkit)\-[a-z\-]+/gi,"")),v)switch(t){case"rowspan":case"colspan":1===r&&(r="");break;case"size":("+0"===r||20===r||0===r)&&(r="");break;case"width":case"height":case"vspace":case"checked":case"disabled":case"readonly":0===r&&(r="");break;case"hspace":-1===r&&(r="");break;case"maxlength":case"tabindex":(32768===r||2147483647===r||"32768"===r)&&(r="");break;case"multiple":case"compact":case"noshade":case"nowrap":return 65535===r?t:n;case"shape":r=r.toLowerCase();break;default:0===t.indexOf("on")&&r&&(r=(""+r).replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/,"$1"))}return r!==o&&null!==r&&""!==r?""+r:n},getPos:function(e,t){var n=this,r=0,i=0,o,a=n.doc,s;if(e=n.get(e),t=t||a.body,e){if(t===a.body&&e.getBoundingClientRect)return s=e.getBoundingClientRect(),t=n.boxModel?a.documentElement:a.body,r=s.left+(a.documentElement.scrollLeft||a.body.scrollLeft)-t.clientLeft,i=s.top+(a.documentElement.scrollTop||a.body.scrollTop)-t.clientTop,{x:r,y:i};for(o=e;o&&o!=t&&o.nodeType;)r+=o.offsetLeft||0,i+=o.offsetTop||0,o=o.offsetParent;for(o=e.parentNode;o&&o!=t&&o.nodeType;)r-=o.scrollLeft||0,i-=o.scrollTop||0,o=o.parentNode}return{x:r,y:i}},parseStyle:function(e){return this.styles.parse(e)},serializeStyle:function(e,t){return this.styles.serialize(e,t)},addStyle:function(e){var t=this,n=t.doc,r,i;if(t!==u.DOM&&n===document){var o=u.DOM.addedStyles;if(o=o||[],o[e])return;o[e]=!0,u.DOM.addedStyles=o}i=n.getElementById("mceDefaultStyles"),i||(i=n.createElement("style"),i.id="mceDefaultStyles",i.type="text/css",r=n.getElementsByTagName("head")[0],r.firstChild?r.insertBefore(i,r.firstChild):r.appendChild(i)),i.styleSheet?i.styleSheet.cssText+=e:i.appendChild(n.createTextNode(e))},loadCSS:function(e){var t=this,n=t.doc,r;return t!==u.DOM&&n===document?void u.DOM.loadCSS(e):(e||(e=""),r=n.getElementsByTagName("head")[0],void d(e.split(","),function(e){var i;t.files[e]||(t.files[e]=!0,i=t.create("link",{rel:"stylesheet",href:e}),v&&n.documentMode&&n.recalc&&(i.onload=function(){n.recalc&&n.recalc(),i.onload=null}),r.appendChild(i))}))},addClass:function(e,t){return this.run(e,function(e){var n;return t?this.hasClass(e,t)?e.className:(n=this.removeClass(e,t),e.className=n=(""!==n?n+" ":"")+t,n):0})},removeClass:function(e,t){var n=this,r;return n.run(e,function(e){var i;return n.hasClass(e,t)?(r||(r=new RegExp("(^|\\s+)"+t+"(\\s+|$)","g")),i=e.className.replace(r," "),i=h(" "!=i?i:""),e.className=i,i||(e.removeAttribute("class"),e.removeAttribute("className")),i):e.className})},hasClass:function(e,t){return e=this.get(e),e&&t?-1!==(" "+e.className+" ").indexOf(" "+t+" "):!1},toggleClass:function(e,n,r){r=r===t?!this.hasClass(e,n):r,this.hasClass(e,n)!==r&&(r?this.addClass(e,n):this.removeClass(e,n))},show:function(e){return this.setStyle(e,"display","block")},hide:function(e){return this.setStyle(e,"display","none")},isHidden:function(e){return e=this.get(e),!e||"none"==e.style.display||"none"==this.getStyle(e,"display")},uniqueId:function(e){return(e?e:"mce_")+this.counter++},setHTML:function(e,t){var n=this;return n.run(e,function(e){if(v){for(;e.firstChild;)e.removeChild(e.firstChild);try{e.innerHTML="
    "+t,e.removeChild(e.firstChild)}catch(r){var i=n.create("div");i.innerHTML="
    "+t,d(p(i.childNodes),function(t,n){n&&e.canHaveHTML&&e.appendChild(t)})}}else e.innerHTML=t;return t})},getOuterHTML:function(e){var t,n=this;return(e=n.get(e))?1===e.nodeType&&n.hasOuterHTML?e.outerHTML:(t=(e.ownerDocument||n.doc).createElement("body"),t.appendChild(e.cloneNode(!0)),t.innerHTML):null},setOuterHTML:function(e,t,n){var r=this;return r.run(e,function(e){function i(){var i,o;for(o=n.createElement("body"),o.innerHTML=t,i=o.lastChild;i;)r.insertAfter(i.cloneNode(!0),e),i=i.previousSibling;r.remove(e)}if(1==e.nodeType)if(n=n||e.ownerDocument||r.doc,v)try{1==e.nodeType&&r.hasOuterHTML?e.outerHTML=t:i()}catch(o){i()}else i()})},decode:a.decode,encode:a.encodeAllRaw,insertAfter:function(e,t){return t=this.get(t),this.run(e,function(e){var n,r;return n=t.parentNode,r=t.nextSibling,r?n.insertBefore(e,r):n.appendChild(e),e})},replace:function(e,t,n){var r=this;return r.run(t,function(t){return f(t,"array")&&(e=e.cloneNode(!0)),n&&d(p(t.childNodes),function(t){e.appendChild(t)}),t.parentNode.replaceChild(e,t)})},rename:function(e,t){var n=this,r;return e.nodeName!=t.toUpperCase()&&(r=n.create(t),d(n.getAttribs(e),function(t){n.setAttrib(r,t.nodeName,n.getAttrib(e,t.nodeName))}),n.replace(r,e,1)),r||e},findCommonAncestor:function(e,t){for(var n=e,r;n;){for(r=t;r&&n!=r;)r=r.parentNode;if(n==r)break;n=n.parentNode}return!n&&e.ownerDocument?e.ownerDocument.documentElement:n},toHex:function(e){return this.styles.toHex(l.trim(e))},run:function(e,t,n){var r=this,i;return"string"==typeof e&&(e=r.get(e)),e?(n=n||this,e.nodeType||!e.length&&0!==e.length?t.call(n,e):(i=[],d(e,function(e,o){e&&("string"==typeof e&&(e=r.get(e)),i.push(t.call(n,e,o)))}),i)):!1},getAttribs:function(e){var t;if(e=this.get(e),!e)return[];if(v){if(t=[],"OBJECT"==e.nodeName)return e.attributes;"OPTION"===e.nodeName&&this.getAttrib(e,"selected")&&t.push({specified:1,nodeName:"selected"});var n=/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi;return e.cloneNode(!1).outerHTML.replace(n,"").replace(/[\w:\-]+/gi,function(e){t.push({specified:1,nodeName:e})}),t}return e.attributes},isEmpty:function(e,t){var n=this,r,o,a,s,l,c=0;if(e=e.firstChild){s=new i(e,e.parentNode),t=t||n.schema?n.schema.getNonEmptyElements():null;do{if(a=e.nodeType,1===a){if(e.getAttribute("data-mce-bogus"))continue;if(l=e.nodeName.toLowerCase(),t&&t[l]){if("br"===l){c++;continue}return!1}for(o=n.getAttribs(e),r=o.length;r--;)if(l=o[r].nodeName,"name"===l||"data-mce-bookmark"===l)return!1}if(8==a)return!1;if(3===a&&!b.test(e.nodeValue))return!1}while(e=s.next())}return 1>=c},createRng:function(){var e=this.doc;return e.createRange?e.createRange():new o(this)},nodeIndex:function(e,t){var n=0,r,i;if(e)for(r=e.nodeType,e=e.previousSibling;e;e=e.previousSibling)i=e.nodeType,(!t||3!=i||i!=r&&e.nodeValue.length)&&(n++,r=i);return n},split:function(e,t,n){function r(e){function t(e){var t=e.previousSibling&&"SPAN"==e.previousSibling.nodeName,n=e.nextSibling&&"SPAN"==e.nextSibling.nodeName;return t&&n}var n,o=e.childNodes,a=e.nodeType;if(1!=a||"bookmark"!=e.getAttribute("data-mce-type")){for(n=o.length-1;n>=0;n--)r(o[n]);if(9!=a){if(3==a&&e.nodeValue.length>0){var s=h(e.nodeValue).length;if(!i.isBlock(e.parentNode)||s>0||0===s&&t(e))return}else if(1==a&&(o=e.childNodes,1==o.length&&o[0]&&1==o[0].nodeType&&"bookmark"==o[0].getAttribute("data-mce-type")&&e.parentNode.insertBefore(o[0],e),o.length||/^(br|hr|input|img)$/i.test(e.nodeName)))return;i.remove(e)}return e}}var i=this,o=i.createRng(),a,s,l;return e&&t?(o.setStart(e.parentNode,i.nodeIndex(e)),o.setEnd(t.parentNode,i.nodeIndex(t)),a=o.extractContents(),o=i.createRng(),o.setStart(t.parentNode,i.nodeIndex(t)+1),o.setEnd(e.parentNode,i.nodeIndex(e)+1),s=o.extractContents(),l=e.parentNode,l.insertBefore(r(a),e),n?l.replaceChild(n,t):l.insertBefore(t,e),l.insertBefore(r(s),e),i.remove(e),n||t):void 0},bind:function(e,t,n,r){var i=this;if(l.isArray(e)){for(var o=e.length;o--;)e[o]=i.bind(e[o],t,n,r);return e}return!i.settings.collect||e!==i.doc&&e!==i.win||i.boundEvents.push([e,t,n,r]),i.events.bind(e,t,n,r||i)},unbind:function(e,t,n){var r=this,i;if(l.isArray(e)){for(i=e.length;i--;)e[i]=r.unbind(e[i],t,n);return e}if(r.boundEvents&&(e===r.doc||e===r.win))for(i=r.boundEvents.length;i--;){var o=r.boundEvents[i];e!=o[0]||t&&t!=o[1]||n&&n!=o[2]||this.events.unbind(o[0],o[1],o[2])}return this.events.unbind(e,t,n)},fire:function(e,t,n){return this.events.fire(e,t,n)},getContentEditable:function(e){var t;return e&&1==e.nodeType?(t=e.getAttribute("data-mce-contenteditable"),t&&"inherit"!==t?t:"inherit"!==e.contentEditable?e.contentEditable:null):null},getContentEditableParent:function(e){for(var t=this.getRoot(),n=null;e&&e!==t&&(n=this.getContentEditable(e),null===n);e=e.parentNode);return n},destroy:function(){var t=this;if(t.boundEvents){for(var n=t.boundEvents.length;n--;){var r=t.boundEvents[n]; +this.events.unbind(r[0],r[1],r[2])}t.boundEvents=null}e.setDocument&&e.setDocument(),t.win=t.doc=t.root=t.events=t.frag=null},isChildOf:function(e,t){for(;e;){if(t===e)return!0;e=e.parentNode}return!1},dumpRng:function(e){return"startContainer: "+e.startContainer.nodeName+", startOffset: "+e.startOffset+", endContainer: "+e.endContainer.nodeName+", endOffset: "+e.endOffset},_findSib:function(e,t,n){var r=this,i=t;if(e)for("string"==typeof i&&(i=function(e){return r.is(e,t)}),e=e[n];e;e=e[n])if(i(e))return e;return null}},u.DOM=new u(document),u}),r(b,[y,p],function(e,t){function n(){function e(e,t){function n(){o.remove(s),a&&(a.onreadystatechange=a.onload=a=null),t()}function i(){"undefined"!=typeof console&&console.log&&console.log("Failed to load: "+e)}var o=r,a,s;s=o.uniqueId(),a=document.createElement("script"),a.id=s,a.type="text/javascript",a.src=e,"onreadystatechange"in a?a.onreadystatechange=function(){/loaded|complete/.test(a.readyState)&&n()}:a.onload=n,a.onerror=i,(document.getElementsByTagName("head")[0]||document.body).appendChild(a)}var t=0,n=1,a=2,s={},l=[],c={},u=[],d=0,f;this.isDone=function(e){return s[e]==a},this.markDone=function(e){s[e]=a},this.add=this.load=function(e,n,r){var i=s[e];i==f&&(l.push(e),s[e]=t),n&&(c[e]||(c[e]=[]),c[e].push({func:n,scope:r||this}))},this.loadQueue=function(e,t){this.loadScripts(l,e,t)},this.loadScripts=function(t,r,l){function p(e){i(c[e],function(e){e.func.call(e.scope)}),c[e]=f}var h;u.push({func:r,scope:l||this}),(h=function(){var r=o(t);t.length=0,i(r,function(t){return s[t]==a?void p(t):void(s[t]!=n&&(s[t]=n,d++,e(t,function(){s[t]=a,d--,p(t),h()})))}),d||(i(u,function(e){e.func.call(e.scope)}),u.length=0)})()}}var r=e.DOM,i=t.each,o=t.grep;return n.ScriptLoader=new n,n}),r(C,[b,p],function(e,n){function r(){var e=this;e.items=[],e.urls={},e.lookup={}}var i=n.each;return r.prototype={get:function(e){return this.lookup[e]?this.lookup[e].instance:t},dependencies:function(e){var t;return this.lookup[e]&&(t=this.lookup[e].dependencies),t||[]},requireLangPack:function(t,n){var i=r.language;if(i&&r.languageLoad!==!1){if(n)if(n=","+n+",",-1!=n.indexOf(","+i.substr(0,2)+","))i=i.substr(0,2);else if(-1==n.indexOf(","+i+","))return;e.ScriptLoader.add(this.urls[t]+"/langs/"+i+".js")}},add:function(e,t,n){return this.items.push(t),this.lookup[e]={instance:t,dependencies:n},t},createUrl:function(e,t){return"object"==typeof t?t:{prefix:e.prefix,resource:t,suffix:e.suffix}},addComponents:function(t,n){var r=this.urls[t];i(n,function(t){e.ScriptLoader.add(r+"/"+t)})},load:function(n,o,a,s){function l(){var r=c.dependencies(n);i(r,function(e){var n=c.createUrl(o,e);c.load(n.resource,n,t,t)}),a&&a.call(s?s:e)}var c=this,u=o;c.urls[n]||("object"==typeof o&&(u=o.prefix+o.resource+o.suffix),0!==u.indexOf("/")&&-1==u.indexOf("://")&&(u=r.baseURL+"/"+u),c.urls[n]=u.substring(0,u.lastIndexOf("/")),c.lookup[n]?l():e.ScriptLoader.add(u,l,s))}},r.PluginManager=new r,r.ThemeManager=new r,r}),r(x,[],function(){function e(e,t,n){var r,i,o=n?"lastChild":"firstChild",a=n?"prev":"next";if(e[o])return e[o];if(e!==t){if(r=e[a])return r;for(i=e.parent;i&&i!==t;i=i.parent)if(r=i[a])return r}}function t(e,t){this.name=e,this.type=t,1===t&&(this.attributes=[],this.attributes.map={})}var n=/^[ \t\r\n]*$/,r={"#text":3,"#comment":8,"#cdata":4,"#pi":7,"#doctype":10,"#document-fragment":11};return t.prototype={replace:function(e){var t=this;return e.parent&&e.remove(),t.insert(e,t),t.remove(),t},attr:function(e,t){var n=this,r,i,o;if("string"!=typeof e){for(i in e)n.attr(i,e[i]);return n}if(r=n.attributes){if(t!==o){if(null===t){if(e in r.map)for(delete r.map[e],i=r.length;i--;)if(r[i].name===e)return r=r.splice(i,1),n;return n}if(e in r.map){for(i=r.length;i--;)if(r[i].name===e){r[i].value=t;break}}else r.push({name:e,value:t});return r.map[e]=t,n}return r.map[e]}},clone:function(){var e=this,n=new t(e.name,e.type),r,i,o,a,s;if(o=e.attributes){for(s=[],s.map={},r=0,i=o.length;i>r;r++)a=o[r],"id"!==a.name&&(s[s.length]={name:a.name,value:a.value},s.map[a.name]=a.value);n.attributes=s}return n.value=e.value,n.shortEnded=e.shortEnded,n},wrap:function(e){var t=this;return t.parent.insert(e,t),e.append(t),t},unwrap:function(){var e=this,t,n;for(t=e.firstChild;t;)n=t.next,e.insert(t,e,!0),t=n;e.remove()},remove:function(){var e=this,t=e.parent,n=e.next,r=e.prev;return t&&(t.firstChild===e?(t.firstChild=n,n&&(n.prev=null)):r.next=n,t.lastChild===e?(t.lastChild=r,r&&(r.next=null)):n.prev=r,e.parent=e.next=e.prev=null),e},append:function(e){var t=this,n;return e.parent&&e.remove(),n=t.lastChild,n?(n.next=e,e.prev=n,t.lastChild=e):t.lastChild=t.firstChild=e,e.parent=t,e},insert:function(e,t,n){var r;return e.parent&&e.remove(),r=t.parent||this,n?(t===r.firstChild?r.firstChild=e:t.prev.next=e,e.prev=t.prev,e.next=t,t.prev=e):(t===r.lastChild?r.lastChild=e:t.next.prev=e,e.next=t.next,e.prev=t,t.next=e),e.parent=r,e},getAll:function(t){var n=this,r,i=[];for(r=n.firstChild;r;r=e(r,n))r.name===t&&i.push(r);return i},empty:function(){var t=this,n,r,i;if(t.firstChild){for(n=[],i=t.firstChild;i;i=e(i,t))n.push(i);for(r=n.length;r--;)i=n[r],i.parent=i.firstChild=i.lastChild=i.next=i.prev=null}return t.firstChild=t.lastChild=null,t},isEmpty:function(t){var r=this,i=r.firstChild,o,a;if(i)do{if(1===i.type){if(i.attributes.map["data-mce-bogus"])continue;if(t[i.name])return!1;for(o=i.attributes.length;o--;)if(a=i.attributes[o].name,"name"===a||0===a.indexOf("data-mce-"))return!1}if(8===i.type)return!1;if(3===i.type&&!n.test(i.value))return!1}while(i=e(i,r));return!0},walk:function(t){return e(this,null,t)}},t.create=function(e,n){var i,o;if(i=new t(e,r[e]||1),n)for(o in n)i.attr(o,n[o]);return i},t}),r(w,[p],function(e){function t(e,t){return e?e.split(t||" "):[]}function n(e){function n(e,n,r){function i(e){var t={},n,r;for(n=0,r=e.length;r>n;n++)t[e[n]]={};return t}var o,l,c,u=arguments;for(r=r||[],n=n||"","string"==typeof r&&(r=t(r)),l=3;lo;o++)i.attributes[n[o]]={},i.attributesOrder.push(n[o])}var a={},s,l,c,u,d,f;return r[e]?r[e]:(s=t("id accesskey class dir lang style tabindex title"),l=t("address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul"),c=t("a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd label map noscript object q s samp script select small span strong sub sup textarea u var #text #comment"),"html4"!=e&&(s.push.apply(s,t("contenteditable contextmenu draggable dropzone hidden spellcheck translate")),l.push.apply(l,t("article aside details dialog figure header footer hgroup section nav")),c.push.apply(c,t("audio canvas command datalist mark meter output progress time wbr video ruby bdi keygen"))),"html5-strict"!=e&&(s.push("xml:lang"),f=t("acronym applet basefont big font strike tt"),c.push.apply(c,f),o(f,function(e){n(e,"",c)}),d=t("center dir isindex noframes"),l.push.apply(l,d),u=[].concat(l,c),o(d,function(e){n(e,"",u)})),u=u||[].concat(l,c),n("html","manifest","head body"),n("head","","base command link meta noscript script style title"),n("title hr noscript br"),n("base","href target"),n("link","href rel media hreflang type sizes hreflang"),n("meta","name http-equiv content charset"),n("style","media type scoped"),n("script","src async defer type charset"),n("body","onafterprint onbeforeprint onbeforeunload onblur onerror onfocus onhashchange onload onmessage onoffline ononline onpagehide onpageshow onpopstate onresize onscroll onstorage onunload",u),n("address dt dd div caption","",u),n("h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn","",c),n("blockquote","cite",u),n("ol","reversed start type","li"),n("ul","","li"),n("li","value",u),n("dl","","dt dd"),n("a","href target rel media hreflang type",c),n("q","cite",c),n("ins del","cite datetime",u),n("img","src alt usemap ismap width height"),n("iframe","src name width height",u),n("embed","src type width height"),n("object","data type typemustmatch name usemap form width height",u,"param"),n("param","name value"),n("map","name",u,"area"),n("area","alt coords shape href target rel media hreflang type"),n("table","border","caption colgroup thead tfoot tbody tr"+("html4"==e?" col":"")),n("colgroup","span","col"),n("col","span"),n("tbody thead tfoot","","tr"),n("tr","","td th"),n("td","colspan rowspan headers",u),n("th","colspan rowspan headers scope abbr",u),n("form","accept-charset action autocomplete enctype method name novalidate target",u),n("fieldset","disabled form name",u,"legend"),n("label","form for",c),n("input","accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate formtarget height list max maxlength min multiple name pattern readonly required size src step type value width"),n("button","disabled form formaction formenctype formmethod formnovalidate formtarget name type value","html4"==e?u:c),n("select","disabled form multiple name required size","option optgroup"),n("optgroup","disabled label","option"),n("option","disabled label selected value"),n("textarea","cols dirname disabled form maxlength name readonly required rows wrap"),n("menu","type label",u,"li"),n("noscript","",u),"html4"!=e&&(n("wbr"),n("ruby","",c,"rt rp"),n("figcaption","",u),n("mark rt rp summary bdi","",c),n("canvas","width height",u),n("video","src crossorigin poster preload autoplay mediagroup loop muted controls width height buffered",u,"track source"),n("audio","src crossorigin preload autoplay mediagroup loop muted controls buffered volume",u,"track source"),n("source","src type media"),n("track","kind src srclang label default"),n("datalist","",c,"option"),n("article section nav aside header footer","",u),n("hgroup","","h1 h2 h3 h4 h5 h6"),n("figure","",u,"figcaption"),n("time","datetime",c),n("dialog","open",u),n("command","type label icon disabled checked radiogroup command"),n("output","for form name",c),n("progress","value max",c),n("meter","value min max low high optimum",c),n("details","open",u,"summary"),n("keygen","autofocus challenge disabled form keytype name")),"html5-strict"!=e&&(i("script","language xml:space"),i("style","xml:space"),i("object","declare classid codebase codetype archive standby align border hspace vspace"),i("param","valuetype type"),i("a","charset name rev shape coords"),i("br","clear"),i("applet","codebase archive code object alt name width height align hspace vspace"),i("img","name longdesc align border hspace vspace"),i("iframe","longdesc frameborder marginwidth marginheight scrolling align"),i("font basefont","size color face"),i("input","usemap align"),i("select","onchange"),i("textarea"),i("h1 h2 h3 h4 h5 h6 div p legend caption","align"),i("ul","type compact"),i("li","type"),i("ol dl menu dir","compact"),i("pre","width xml:space"),i("hr","align noshade size width"),i("isindex","prompt"),i("table","summary width frame rules cellspacing cellpadding align bgcolor"),i("col","width align char charoff valign"),i("colgroup","width align char charoff valign"),i("thead","align char charoff valign"),i("tr","align char charoff valign bgcolor"),i("th","axis align char charoff valign nowrap bgcolor width height"),i("form","accept"),i("td","abbr axis scope align char charoff valign nowrap bgcolor width height"),i("tfoot","align char charoff valign"),i("tbody","align char charoff valign"),i("area","nohref"),i("body","background bgcolor text link vlink alink")),"html4"!=e&&(i("input button select textarea","autofocus"),i("input textarea","placeholder"),i("a","download"),i("link script img","crossorigin"),i("iframe","sandbox seamless allowfullscreen")),o(t("a form meter progress dfn"),function(e){a[e]&&delete a[e].children[e]}),delete a.caption.children.table,r[e]=a,a)}var r={},i=e.makeMap,o=e.each,a=e.extend,s=e.explode,l=e.inArray;return function(e){function c(t,n,o){var s=e[t];return s?s=i(s,/[, ]/,i(s.toUpperCase(),/[, ]/)):(s=r[t],s||(s=i(n," ",i(n.toUpperCase()," ")),s=a(s,o),r[t]=s)),s}function u(e){return new RegExp("^"+e.replace(/([?+*])/g,".$1")+"$")}function d(e){var n,r,o,a,s,c,d,f,p,h,m,g,y,C,x,w,_,N,E,S=/^([#+\-])?([^\[!\/]+)(?:\/([^\[!]+))?(?:(!?)\[([^\]]+)\])?$/,k=/^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,T=/[*?+]/;if(e)for(e=t(e,","),v["@"]&&(w=v["@"].attributes,_=v["@"].attributesOrder),n=0,r=e.length;r>n;n++)if(s=S.exec(e[n])){if(C=s[1],p=s[2],x=s[3],f=s[5],g={},y=[],c={attributes:g,attributesOrder:y},"#"===C&&(c.paddEmpty=!0),"-"===C&&(c.removeEmpty=!0),"!"===s[4]&&(c.removeEmptyAttrs=!0),w){for(N in w)g[N]=w[N];y.push.apply(y,_)}if(f)for(f=t(f,"|"),o=0,a=f.length;a>o;o++)if(s=k.exec(f[o])){if(d={},m=s[1],h=s[2].replace(/::/g,":"),C=s[3],E=s[4],"!"===m&&(c.attributesRequired=c.attributesRequired||[],c.attributesRequired.push(h),d.required=!0),"-"===m){delete g[h],y.splice(l(y,h),1);continue}C&&("="===C&&(c.attributesDefault=c.attributesDefault||[],c.attributesDefault.push({name:h,value:E}),d.defaultValue=E),":"===C&&(c.attributesForced=c.attributesForced||[],c.attributesForced.push({name:h,value:E}),d.forcedValue=E),"<"===C&&(d.validValues=i(E,"?"))),T.test(h)?(c.attributePatterns=c.attributePatterns||[],d.pattern=u(h),c.attributePatterns.push(d)):(g[h]||y.push(h),g[h]=d)}w||"@"!=p||(w=g,_=y),x&&(c.outputName=p,v[x]=c),T.test(p)?(c.pattern=u(p),b.push(c)):v[p]=c}}function f(e){v={},b=[],d(e),o(x,function(e,t){y[t]=e.children})}function p(e){var n=/^(~)?(.+)$/;e&&(r.text_block_elements=r.block_elements=null,o(t(e,","),function(e){var t=n.exec(e),r="~"===t[1],i=r?"span":"div",s=t[2];if(y[s]=y[i],R[s]=i,r||(S[s.toUpperCase()]={},S[s]={}),!v[s]){var l=v[i];l=a({},l),delete l.removeEmptyAttrs,delete l.removeEmpty,v[s]=l}o(y,function(e,t){e[i]&&(y[t]=e=a({},y[t]),e[s]=e[i])})}))}function h(e){var n=/^([+\-]?)(\w+)\[([^\]]+)\]$/;e&&o(t(e,","),function(e){var r=n.exec(e),i,s;r&&(s=r[1],i=s?y[r[2]]:y[r[2]]={"#comment":{}},i=y[r[2]],o(t(r[3],"|"),function(e){"-"===s?(y[r[2]]=i=a({},y[r[2]]),delete i[e]):i[e]={}}))})}function m(e){var t=v[e],n;if(t)return t;for(n=b.length;n--;)if(t=b[n],t.pattern.test(e))return t}var g=this,v={},y={},b=[],C,x,w,_,N,E,S,k,T,R={},A={};e=e||{},x=n(e.schema),e.verify_html===!1&&(e.valid_elements="*[*]"),e.valid_styles&&(C={},o(e.valid_styles,function(e,t){C[t]=s(e)})),w=c("whitespace_elements","pre script noscript style textarea video audio iframe object"),_=c("self_closing_elements","colgroup dd dt li option p td tfoot th thead tr"),N=c("short_ended_elements","area base basefont br col frame hr img input isindex link meta param embed source wbr track"),E=c("boolean_attributes","checked compact declare defer disabled ismap multiple nohref noresize noshade nowrap readonly selected autoplay loop controls"),k=c("non_empty_elements","td th iframe video audio object script",N),T=c("text_block_elements","h1 h2 h3 h4 h5 h6 p div address pre form blockquote center dir fieldset header footer article section hgroup aside nav figure"),S=c("block_elements","hr table tbody thead tfoot th tr td li ol ul caption dl dt dd noscript menu isindex option datalist select optgroup",T),o((e.special||"script noscript style textarea").split(" "),function(e){A[e]=new RegExp("]*>","gi")}),e.valid_elements?f(e.valid_elements):(o(x,function(e,t){v[t]={attributes:e.attributes,attributesOrder:e.attributesOrder},y[t]=e.children}),"html5"!=e.schema&&o(t("strong/b em/i"),function(e){e=t(e,"/"),v[e[1]].outputName=e[0]}),v.img.attributesDefault=[{name:"alt",value:""}],o(t("ol ul sub sup blockquote span font a table tbody tr strong em b i"),function(e){v[e]&&(v[e].removeEmpty=!0)}),o(t("p h1 h2 h3 h4 h5 h6 th td pre div address caption"),function(e){v[e].paddEmpty=!0}),o(t("span"),function(e){v[e].removeEmptyAttrs=!0})),p(e.custom_elements),h(e.valid_children),d(e.extended_valid_elements),h("+ol[ul|ol],+ul[ul|ol]"),e.invalid_elements&&o(s(e.invalid_elements),function(e){v[e]&&delete v[e]}),m("span")||d("span[!data-mce-type|*]"),g.children=y,g.styles=C,g.getBoolAttrs=function(){return E},g.getBlockElements=function(){return S},g.getTextBlockElements=function(){return T},g.getShortEndedElements=function(){return N},g.getSelfClosingElements=function(){return _},g.getNonEmptyElements=function(){return k},g.getWhiteSpaceElements=function(){return w},g.getSpecialElements=function(){return A},g.isValidChild=function(e,t){var n=y[e];return!(!n||!n[t])},g.isValid=function(e,t){var n,r,i=m(e);if(i){if(!t)return!0;if(i.attributes[t])return!0;if(n=i.attributePatterns)for(r=n.length;r--;)if(n[r].pattern.test(e))return!0}return!1},g.getElementRule=m,g.getCustomElements=function(){return R},g.addValidElements=d,g.setValidElements=f,g.addCustomElements=p,g.addValidChildren=h,g.elements=v}}),r(_,[w,m,p],function(e,t,n){var r=n.each;return function(i,o){function a(){}var s=this;i=i||{},s.schema=o=o||new e,i.fix_self_closing!==!1&&(i.fix_self_closing=!0),r("comment cdata text start end pi doctype".split(" "),function(e){e&&(s[e]=i[e]||a)}),s.parse=function(e){function r(e){var t,n;for(t=f.length;t--&&f[t].name!==e;);if(t>=0){for(n=f.length-1;n>=t;n--)e=f[n],e.valid&&s.end(e.name);f.length=t}}function a(e,t,n,r,o){var a,s,l=/[\s\u0000-\u001F]+/g;if(t=t.toLowerCase(),n=t in C?t:F(n||r||o||""),w&&!v&&0!==t.indexOf("data-")){if(a=k[t],!a&&T){for(s=T.length;s--&&(a=T[s],!a.pattern.test(t)););-1===s&&(a=null)}if(!a)return;if(a.validValues&&!(n in a.validValues))return}if(W[t]&&!i.allow_script_urls){var c=n.replace(l,"");try{c=decodeURIComponent(c)}catch(u){c=unescape(c)}if(V.test(c))return;if(!i.allow_html_data_urls&&U.test(c)&&!/^data:image\//i.test(c))return}p.map[t]=n,p.push({name:t,value:n})}var s=this,l,c=0,u,d,f=[],p,h,m,g,v,y,b,C,x,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O,I=0,F=t.decode,z,W=n.makeMap("src,href,data,background,formaction,poster"),V=/((java|vb)script|mhtml):/i,U=/^data:/i;for(M=new RegExp("<(?:(?:!--([\\w\\W]*?)-->)|(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|(?:!DOCTYPE([\\w\\W]*?)>)|(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|(?:\\/([^>]+)>)|(?:([A-Za-z0-9\\-\\:\\.]+)((?:\\s+[^\"'>]+(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>]*))*|\\/|\\s+)>))","g"),H=/([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g,b=o.getShortEndedElements(),L=i.self_closing_elements||o.getSelfClosingElements(),C=o.getBoolAttrs(),w=i.validate,y=i.remove_internals,z=i.fix_self_closing,P=o.getSpecialElements();l=M.exec(e);){if(c0&&f[f.length-1].name===u&&r(u),!w||(_=o.getElementRule(u))){if(N=!0,w&&(k=_.attributes,T=_.attributePatterns),(S=l[8])?(v=-1!==S.indexOf("data-mce-type"),v&&y&&(N=!1),p=[],p.map={},S.replace(H,a)):(p=[],p.map={}),w&&!v){if(R=_.attributesRequired,A=_.attributesDefault,B=_.attributesForced,D=_.removeEmptyAttrs,D&&!p.length&&(N=!1),B)for(h=B.length;h--;)E=B[h],g=E.name,O=E.value,"{$uid}"===O&&(O="mce_"+I++),p.map[g]=O,p.push({name:g,value:O});if(A)for(h=A.length;h--;)E=A[h],g=E.name,g in p.map||(O=E.value,"{$uid}"===O&&(O="mce_"+I++),p.map[g]=O,p.push({name:g,value:O}));if(R){for(h=R.length;h--&&!(R[h]in p.map););-1===h&&(N=!1)}p.map["data-mce-bogus"]&&(N=!1)}N&&s.start(u,p,x)}else N=!1;if(d=P[u]){d.lastIndex=c=l.index+l[0].length,(l=d.exec(e))?(N&&(m=e.substr(c,l.index-c)),c=l.index+l[0].length):(m=e.substr(c),c=e.length),N&&(m.length>0&&s.text(m,!0),s.end(u)),M.lastIndex=c;continue}x||(S&&S.indexOf("/")==S.length-1?N&&s.end(u):f.push({name:u,valid:N}))}else(u=l[1])?(">"===u.charAt(0)&&(u=" "+u),i.allow_conditional_comments||"[if"!==u.substr(0,3)||(u=" "+u),s.comment(u)):(u=l[2])?s.cdata(u):(u=l[3])?s.doctype(u):(u=l[4])&&s.pi(u,l[5]);c=l.index+l[0].length}for(c=0;h--)u=f[h],u.valid&&s.end(u.name)}}}),r(N,[x,w,_,p],function(e,t,n,r){var i=r.makeMap,o=r.each,a=r.explode,s=r.extend;return function(r,l){function c(t){var n,r,o,a,s,c,d,f,p,h,m,g,v,y;for(m=i("tr,td,th,tbody,thead,tfoot,table"),h=l.getNonEmptyElements(),g=l.getTextBlockElements(),n=0;n1){for(a.reverse(),s=c=u.filterNode(a[0].clone()),p=0;p0?(t.value=n,t=t.prev):(r=t.prev,t.remove(),t=r)}function g(e){var t,n={};for(t in e)"li"!==t&&"p"!=t&&(n[t]=e[t]);return n}var v,y,b,C,x,w,_,N,E,S,k,T,R,A=[],B,D,L,M,H,P,O,I;if(o=o||{},p={},h={},T=s(i("script,style,head,html,body,title,meta,param"),l.getBlockElements()),O=l.getNonEmptyElements(),P=l.children,k=r.validate,I="forced_root_block"in o?o.forced_root_block:r.forced_root_block,H=l.getWhiteSpaceElements(),R=/^[ \t\r\n]+/,D=/[ \t\r\n]+$/,L=/[ \t\r\n]+/g,M=/^[ \t\r\n]+$/,v=new n({validate:k,allow_script_urls:r.allow_script_urls,allow_conditional_comments:r.allow_conditional_comments,self_closing_elements:g(l.getSelfClosingElements()),cdata:function(e){b.append(u("#cdata",4)).value=e},text:function(e,t){var n;B||(e=e.replace(L," "),b.lastChild&&T[b.lastChild.name]&&(e=e.replace(R,""))),0!==e.length&&(n=u("#text",3),n.raw=!!t,b.append(n).value=e)},comment:function(e){b.append(u("#comment",8)).value=e},pi:function(e,t){b.append(u(e,7)).value=t,m(b)},doctype:function(e){var t;t=b.append(u("#doctype",10)),t.value=e,m(b)},start:function(e,t,n){var r,i,o,a,s;if(o=k?l.getElementRule(e):{}){for(r=u(o.outputName||e,1),r.attributes=t,r.shortEnded=n,b.append(r),s=P[b.name],s&&P[r.name]&&!s[r.name]&&A.push(r),i=f.length;i--;)a=f[i].name,a in t.map&&(E=h[a],E?E.push(r):h[a]=[r]);T[e]&&m(r),n||(b=r),!B&&H[e]&&(B=!0)}},end:function(t){var n,r,i,o,a;if(r=k?l.getElementRule(t):{}){if(T[t]&&!B){if(n=b.firstChild,n&&3===n.type)if(i=n.value.replace(R,""),i.length>0)n.value=i,n=n.next;else for(o=n.next,n.remove(),n=o;n&&3===n.type;)i=n.value,o=n.next,(0===i.length||M.test(i))&&(n.remove(),n=o),n=o;if(n=b.lastChild,n&&3===n.type)if(i=n.value.replace(D,""),i.length>0)n.value=i,n=n.prev;else for(o=n.prev,n.remove(),n=o;n&&3===n.type;)i=n.value,o=n.prev,(0===i.length||M.test(i))&&(n.remove(),n=o),n=o}if(B&&H[t]&&(B=!1),(r.removeEmpty||r.paddEmpty)&&b.isEmpty(O))if(r.paddEmpty)b.empty().append(new e("#text","3")).value="\xa0";else if(!b.attributes.map.name&&!b.attributes.map.id)return a=b.parent,b.empty().remove(),void(b=a);b=b.parent}}},l),y=b=new e(o.context||r.root_name,11),v.parse(t),k&&A.length&&(o.context?o.invalid=!0:c(A)),I&&("body"==y.name||o.isRootContent)&&a(),!o.invalid){for(S in p){for(E=d[S],C=p[S],_=C.length;_--;)C[_].parent||C.splice(_,1);for(x=0,w=E.length;w>x;x++)E[x](C,S,o)}for(x=0,w=f.length;w>x;x++)if(E=f[x],E.name in h){for(C=h[E.name],_=C.length;_--;)C[_].parent||C.splice(_,1);for(_=0,N=E.callbacks.length;N>_;_++)E.callbacks[_](C,E.name,o)}}return y},r.remove_trailing_brs&&u.addNodeFilter("br",function(t){var n,r=t.length,i,o=s({},l.getBlockElements()),a=l.getNonEmptyElements(),c,u,d,f,p,h;for(o.body=1,n=0;r>n;n++)if(i=t[n],c=i.parent,o[i.parent.name]&&i===c.lastChild){for(d=i.prev;d;){if(f=d.name,"span"!==f||"bookmark"!==d.attr("data-mce-type")){if("br"!==f)break;if("br"===f){i=null;break}}d=d.prev}i&&(i.remove(),c.isEmpty(a)&&(p=l.getElementRule(c.name),p&&(p.removeEmpty?c.remove():p.paddEmpty&&(c.empty().append(new e("#text",3)).value="\xa0"))))}else{for(u=i;c&&c.firstChild===u&&c.lastChild===u&&(u=c,!o[c.name]);)c=c.parent;u===c&&(h=new e("#text",3),h.value="\xa0",i.replace(h))}}),r.allow_html_in_named_anchor||u.addAttributeFilter("id,name",function(e){for(var t=e.length,n,r,i,o;t--;)if(o=e[t],"a"===o.name&&o.firstChild&&!o.attr("href")){i=o.parent,n=o.lastChild;do r=n.prev,i.insert(n,o),n=r;while(n)}})}}),r(E,[m,p],function(e,t){var n=t.makeMap;return function(t){var r=[],i,o,a,s,l;return t=t||{},i=t.indent,o=n(t.indent_before||""),a=n(t.indent_after||""),s=e.getEncodeFunc(t.entity_encoding||"raw",t.entities),l="html"==t.element_format,{start:function(e,t,n){var c,u,d,f;if(i&&o[e]&&r.length>0&&(f=r[r.length-1],f.length>0&&"\n"!==f&&r.push("\n")),r.push("<",e),t)for(c=0,u=t.length;u>c;c++)d=t[c],r.push(" ",d.name,'="',s(d.value,!0),'"');r[r.length]=!n||l?">":" />",n&&i&&a[e]&&r.length>0&&(f=r[r.length-1],f.length>0&&"\n"!==f&&r.push("\n"))},end:function(e){var t;r.push(""),i&&a[e]&&r.length>0&&(t=r[r.length-1],t.length>0&&"\n"!==t&&r.push("\n"))},text:function(e,t){e.length>0&&(r[r.length]=t?e:s(e))},cdata:function(e){r.push("")},comment:function(e){r.push("")},pi:function(e,t){t?r.push(""):r.push(""),i&&r.push("\n")},doctype:function(e){r.push("",i?"\n":"")},reset:function(){r.length=0},getContent:function(){return r.join("").replace(/\n$/,"")}}}}),r(S,[E,w],function(e,t){return function(n,r){var i=this,o=new e(n);n=n||{},n.validate="validate"in n?n.validate:!0,i.schema=r=r||new t,i.writer=o,i.serialize=function(e){function t(e){var n=i[e.type],s,l,c,u,d,f,p,h,m;if(n)n(e);else{if(s=e.name,l=e.shortEnded,c=e.attributes,a&&c&&c.length>1){for(f=[],f.map={},m=r.getElementRule(e.name),p=0,h=m.attributesOrder.length;h>p;p++)u=m.attributesOrder[p],u in c.map&&(d=c.map[u],f.map[u]=d,f.push({name:u,value:d}));for(p=0,h=c.length;h>p;p++)u=c[p].name,u in f.map||(d=c.map[u],f.map[u]=d,f.push({name:u,value:d}));c=f}if(o.start(e.name,c,l),!l){if(e=e.firstChild)do t(e);while(e=e.next);o.end(s)}}}var i,a;return a=n.validate,i={3:function(e){o.text(e.value,e.raw)},8:function(e){o.comment(e.value)},7:function(e){o.pi(e.name,e.value)},10:function(e){o.doctype(e.value)},4:function(e){o.cdata(e.value)},11:function(e){if(e=e.firstChild)do t(e);while(e=e.next)}},o.reset(),1!=e.type||n.inner?i[11](e):t(e),o.getContent()}}}),r(k,[y,N,m,S,x,w,g,p],function(e,t,n,r,i,o,a,s){var l=s.each,c=s.trim,u=e.DOM;return function(e,i){var s,d,f;return i&&(s=i.dom,d=i.schema),s=s||u,d=d||new o(e),e.entity_encoding=e.entity_encoding||"named",e.remove_trailing_brs="remove_trailing_brs"in e?e.remove_trailing_brs:!0,f=new t(e,d),f.addAttributeFilter("data-mce-tabindex",function(e,t){for(var n=e.length,r;n--;)r=e[n],r.attr("tabindex",r.attributes.map["data-mce-tabindex"]),r.attr(t,null)}),f.addAttributeFilter("src,href,style",function(t,n){for(var r=t.length,i,o,a="data-mce-"+n,l=e.url_converter,c=e.url_converter_scope,u;r--;)i=t[r],o=i.attributes.map[a],o!==u?(i.attr(n,o.length>0?o:null),i.attr(a,null)):(o=i.attributes.map[n],"style"===n?o=s.serializeStyle(s.parseStyle(o),i.name):l&&(o=l.call(c,o,n,i.name)),i.attr(n,o.length>0?o:null))}),f.addAttributeFilter("class",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.attr("class").replace(/(?:^|\s)mce-item-\w+(?!\S)/g,""),n.attr("class",r.length>0?r:null)}),f.addAttributeFilter("data-mce-type",function(e,t,n){for(var r=e.length,i;r--;)i=e[r],"bookmark"!==i.attributes.map["data-mce-type"]||n.cleanup||i.remove()}),f.addAttributeFilter("data-mce-expando",function(e,t){for(var n=e.length;n--;)e[n].attr(t,null)}),f.addNodeFilter("noscript",function(e){for(var t=e.length,r;t--;)r=e[t].firstChild,r&&(r.value=n.decode(r.value))}),f.addNodeFilter("script,style",function(e,t){function n(e){return e.replace(/()/g,"\n").replace(/^[\r\n]*|[\r\n]*$/g,"").replace(/^\s*(()?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g,"")}for(var r=e.length,i,o;r--;)if(i=e[r],o=i.firstChild?i.firstChild.value:"","script"===t){var a=(i.attr("type")||"text/javascript").replace(/^mce\-/,"");i.attr("type","text/javascript"===a?null:a),o.length>0&&(i.firstChild.value="// ")}else o.length>0&&(i.firstChild.value="")}),f.addNodeFilter("#comment",function(e){for(var t=e.length,n;t--;)n=e[t],0===n.value.indexOf("[CDATA[")?(n.name="#cdata",n.type=4,n.value=n.value.replace(/^\[CDATA\[|\]\]$/g,"")):0===n.value.indexOf("mce:protected ")&&(n.name="#text",n.type=3,n.raw=!0,n.value=unescape(n.value).substr(14))}),f.addNodeFilter("xml:namespace,input",function(e,t){for(var n=e.length,r;n--;)r=e[n],7===r.type?r.remove():1===r.type&&("input"!==t||"type"in r.attributes.map||r.attr("type","text"))}),e.fix_list_elements&&f.addNodeFilter("ul,ol",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.parent,("ul"===r.name||"ol"===r.name)&&n.prev&&"li"===n.prev.name&&n.prev.append(n)}),f.addAttributeFilter("data-mce-src,data-mce-href,data-mce-style,data-mce-selected",function(e,t){for(var n=e.length;n--;)e[n].attr(t,null)}),{schema:d,addNodeFilter:f.addNodeFilter,addAttributeFilter:f.addAttributeFilter,serialize:function(t,n){var i=this,o,u,p,h,m;return a.ie&&s.select("script,style,select,map").length>0?(m=t.innerHTML,t=t.cloneNode(!1),s.setHTML(t,m)):t=t.cloneNode(!0),o=t.ownerDocument.implementation,o.createHTMLDocument&&(u=o.createHTMLDocument(""),l("BODY"==t.nodeName?t.childNodes:[t],function(e){u.body.appendChild(u.importNode(e,!0))}),t="BODY"!=t.nodeName?u.body.firstChild:u.body,p=s.doc,s.doc=u),n=n||{},n.format=n.format||"html",n.selection&&(n.forced_root_block=""),n.no_events||(n.node=t,i.onPreProcess(n)),h=new r(e,d),n.content=h.serialize(f.parse(c(n.getInner?t.innerHTML:s.getOuterHTML(t)),n)),n.cleanup||(n.content=n.content.replace(/\uFEFF/g,"")),n.no_events||i.onPostProcess(n),p&&(s.doc=p),n.node=null,n.content},addRules:function(e){d.addValidElements(e)},setRules:function(e){d.setValidElements(e)},onPreProcess:function(e){i&&i.fire("PreProcess",e)},onPostProcess:function(e){i&&i.fire("PostProcess",e)}}}}),r(T,[],function(){function e(e){function t(t,n){var r,i=0,o,a,s,l,c,u,d=-1,f;if(r=t.duplicate(),r.collapse(n),f=r.parentElement(),f.ownerDocument===e.dom.doc){for(;"false"===f.contentEditable;)f=f.parentNode; +if(!f.hasChildNodes())return{node:f,inside:1};for(s=f.children,o=s.length-1;o>=i;)if(u=Math.floor((i+o)/2),l=s[u],r.moveToElementText(l),d=r.compareEndPoints(n?"StartToStart":"EndToEnd",t),d>0)o=u-1;else{if(!(0>d))return{node:l};i=u+1}if(0>d)for(l?r.collapse(!1):(r.moveToElementText(f),r.collapse(!0),l=f,a=!0),c=0;0!==r.compareEndPoints(n?"StartToStart":"StartToEnd",t)&&0!==r.move("character",1)&&f==r.parentElement();)c++;else for(r.collapse(!0),c=0;0!==r.compareEndPoints(n?"StartToStart":"StartToEnd",t)&&0!==r.move("character",-1)&&f==r.parentElement();)c++;return{node:l,position:d,offset:c,inside:a}}}function n(){function n(e){var n=t(o,e),r,i,s=0,l,c,u;if(r=n.node,i=n.offset,n.inside&&!r.hasChildNodes())return void a[e?"setStart":"setEnd"](r,0);if(i===c)return void a[e?"setStartBefore":"setEndAfter"](r);if(n.position<0){if(l=n.inside?r.firstChild:r.nextSibling,!l)return void a[e?"setStartAfter":"setEndAfter"](r);if(!i)return void(3==l.nodeType?a[e?"setStart":"setEnd"](l,0):a[e?"setStartBefore":"setEndBefore"](l));for(;l;){if(u=l.nodeValue,s+=u.length,s>=i){r=l,s-=i,s=u.length-s;break}l=l.nextSibling}}else{if(l=r.previousSibling,!l)return a[e?"setStartBefore":"setEndBefore"](r);if(!i)return void(3==r.nodeType?a[e?"setStart":"setEnd"](l,r.nodeValue.length):a[e?"setStartAfter":"setEndAfter"](l));for(;l;){if(s+=l.nodeValue.length,s>=i){r=l,s-=i;break}l=l.previousSibling}}a[e?"setStart":"setEnd"](r,s)}var o=e.getRng(),a=i.createRng(),s,l,c,u,d;if(s=o.item?o.item(0):o.parentElement(),s.ownerDocument!=i.doc)return a;if(l=e.isCollapsed(),o.item)return a.setStart(s.parentNode,i.nodeIndex(s)),a.setEnd(a.startContainer,a.startOffset+1),a;try{n(!0),l||n()}catch(f){if(-2147024809!=f.number)throw f;d=r.getBookmark(2),c=o.duplicate(),c.collapse(!0),s=c.parentElement(),l||(c=o.duplicate(),c.collapse(!1),u=c.parentElement(),u.innerHTML=u.innerHTML),s.innerHTML=s.innerHTML,r.moveToBookmark(d),o=e.getRng(),n(!0),l||n()}return a}var r=this,i=e.dom,o=!1;this.getBookmark=function(n){function r(e){var t,n,r,o,a=[];for(t=e.parentNode,n=i.getRoot().parentNode;t!=n&&9!==t.nodeType;){for(r=t.children,o=r.length;o--;)if(e===r[o]){a.push(o);break}e=t,t=t.parentNode}return a}function o(e){var n;return n=t(a,e),n?{position:n.position,offset:n.offset,indexes:r(n.node),inside:n.inside}:void 0}var a=e.getRng(),s={};return 2===n&&(a.item?s.start={ctrl:!0,indexes:r(a.item(0))}:(s.start=o(!0),e.isCollapsed()||(s.end=o()))),s},this.moveToBookmark=function(e){function t(e){var t,n,r,o;for(t=i.getRoot(),n=e.length-1;n>=0;n--)o=t.children,r=e[n],r<=o.length-1&&(t=o[r]);return t}function n(n){var i=e[n?"start":"end"],a,s,l,c;i&&(a=i.position>0,s=o.createTextRange(),s.moveToElementText(t(i.indexes)),c=i.offset,c!==l?(s.collapse(i.inside||a),s.moveStart("character",a?-c:c)):s.collapse(n),r.setEndPoint(n?"StartToStart":"EndToStart",s),n&&r.collapse(!0))}var r,o=i.doc.body;e.start&&(e.start.ctrl?(r=o.createControlRange(),r.addElement(t(e.start.indexes)),r.select()):(r=o.createTextRange(),n(!0),n(),r.select()))},this.addRange=function(t){function n(e){var t,n,a,d,h;a=i.create("a"),t=e?s:c,n=e?l:u,d=r.duplicate(),(t==f||t==f.documentElement)&&(t=p,n=0),3==t.nodeType?(t.parentNode.insertBefore(a,t),d.moveToElementText(a),d.moveStart("character",n),i.remove(a),r.setEndPoint(e?"StartToStart":"EndToEnd",d)):(h=t.childNodes,h.length?(n>=h.length?i.insertAfter(a,h[h.length-1]):t.insertBefore(a,h[n]),d.moveToElementText(a)):t.canHaveHTML&&(t.innerHTML="",a=t.firstChild,d.moveToElementText(a),d.collapse(o)),r.setEndPoint(e?"StartToStart":"EndToEnd",d),i.remove(a))}var r,a,s,l,c,u,d,f=e.dom.doc,p=f.body,h,m;if(s=t.startContainer,l=t.startOffset,c=t.endContainer,u=t.endOffset,r=p.createTextRange(),s==c&&1==s.nodeType){if(l==u&&!s.hasChildNodes()){if(s.canHaveHTML)return d=s.previousSibling,d&&!d.hasChildNodes()&&i.isBlock(d)?d.innerHTML="":d=null,s.innerHTML="",r.moveToElementText(s.lastChild),r.select(),i.doc.selection.clear(),s.innerHTML="",void(d&&(d.innerHTML=""));l=i.nodeIndex(s),s=s.parentNode}if(l==u-1)try{if(m=s.childNodes[l],a=p.createControlRange(),a.addElement(m),a.select(),h=e.getRng(),h.item&&m===h.item(0))return}catch(g){}}n(!0),n(),r.select()},this.getRangeAt=n}return e}),r(R,[g],function(e){return{BACKSPACE:8,DELETE:46,DOWN:40,ENTER:13,LEFT:37,RIGHT:39,SPACEBAR:32,TAB:9,UP:38,modifierPressed:function(e){return e.shiftKey||e.ctrlKey||e.altKey},metaKeyPressed:function(t){return(e.mac?t.metaKey:t.ctrlKey)&&!t.altKey}}}),r(A,[R,p,g],function(e,t,n){return function(r,i){function o(e){var t=i.settings.object_resizing;return t===!1||n.iOS?!1:("string"!=typeof t&&(t="table,img,div"),"false"===e.getAttribute("data-mce-resize")?!1:i.dom.is(e,t))}function a(t){var n,r;n=t.screenX-k,r=t.screenY-T,H=n*E[2]+B,P=r*E[3]+D,H=5>H?5:H,P=5>P?5:P,(e.modifierPressed(t)||"IMG"==w.nodeName&&E[2]*E[3]!==0)&&(H=Math.round(P/L),P=Math.round(H*L)),C.setStyles(_,{width:H,height:P}),E[2]<0&&_.clientWidth<=H&&C.setStyle(_,"left",R+(B-H)),E[3]<0&&_.clientHeight<=P&&C.setStyle(_,"top",A+(D-P)),M||(i.fire("ObjectResizeStart",{target:w,width:B,height:D}),M=!0)}function s(){function e(e,t){t&&(w.style[e]||!i.schema.isValid(w.nodeName.toLowerCase(),e)?C.setStyle(w,e,t):C.setAttrib(w,e,t))}M=!1,e("width",H),e("height",P),C.unbind(O,"mousemove",a),C.unbind(O,"mouseup",s),I!=O&&(C.unbind(I,"mousemove",a),C.unbind(I,"mouseup",s)),C.remove(_),F&&"TABLE"!=w.nodeName||l(w),i.fire("ObjectResized",{target:w,width:H,height:P}),i.nodeChanged()}function l(e,t,r){var l,u,d,f,p,h=i.getBody();g(),l=C.getPos(e,h),R=l.x,A=l.y,p=e.getBoundingClientRect(),u=p.width||p.right-p.left,d=p.height||p.bottom-p.top,w!=e&&(m(),w=e,H=P=0),f=i.fire("ObjectSelected",{target:e}),o(e)&&!f.isDefaultPrevented()?x(N,function(e,o){function l(t){k=t.screenX,T=t.screenY,B=w.clientWidth,D=w.clientHeight,L=D/B,E=e,_=w.cloneNode(!0),C.addClass(_,"mce-clonedresizable"),_.contentEditable=!1,_.unSelectabe=!0,C.setStyles(_,{left:R,top:A,margin:0}),_.removeAttribute("data-mce-selected"),i.getBody().appendChild(_),C.bind(O,"mousemove",a),C.bind(O,"mouseup",s),I!=O&&(C.bind(I,"mousemove",a),C.bind(I,"mouseup",s))}var c,f;return t?void(o==t&&l(r)):(c=C.get("mceResizeHandle"+o),c?C.show(c):(f=i.getBody(),c=C.add(f,"div",{id:"mceResizeHandle"+o,"data-mce-bogus":!0,"class":"mce-resizehandle",unselectable:!0,style:"cursor:"+o+"-resize; margin:0; padding:0"}),n.ie&&(c.contentEditable=!1)),e.elm||(C.bind(c,"mousedown",function(e){e.stopImmediatePropagation(),e.preventDefault(),l(e)}),e.elm=c),void C.setStyles(c,{left:u*e[0]+R-c.offsetWidth/2,top:d*e[1]+A-c.offsetHeight/2}))}):c(),w.setAttribute("data-mce-selected","1")}function c(){var e,t;g(),w&&w.removeAttribute("data-mce-selected");for(e in N)t=C.get("mceResizeHandle"+e),t&&(C.unbind(t),C.remove(t))}function u(e){function t(e,t){if(e)do if(e===t)return!0;while(e=e.parentNode)}var n;return x(C.select("img[data-mce-selected],hr[data-mce-selected]"),function(e){e.removeAttribute("data-mce-selected")}),n="mousedown"==e.type?e.target:r.getNode(),n=C.getParent(n,F?"table":"table,img,hr"),t(n,i.getBody())&&(v(),t(r.getStart(),n)&&t(r.getEnd(),n)&&(!F||n!=r.getStart()&&"IMG"!==r.getStart().nodeName))?void l(n):void c()}function d(e,t,n){e&&e.attachEvent&&e.attachEvent("on"+t,n)}function f(e,t,n){e&&e.detachEvent&&e.detachEvent("on"+t,n)}function p(e){var t=e.srcElement,n,r,o,a,s,c,u;n=t.getBoundingClientRect(),c=S.clientX-n.left,u=S.clientY-n.top;for(r in N)if(o=N[r],a=t.offsetWidth*o[0],s=t.offsetHeight*o[1],Math.abs(a-c)<8&&Math.abs(s-u)<8){E=o;break}M=!0,i.getDoc().selection.empty(),l(t,r,S)}function h(e){var t=e.srcElement;if(t!=w){if(m(),0===t.id.indexOf("mceResizeHandle"))return void(e.returnValue=!1);("IMG"==t.nodeName||"TABLE"==t.nodeName)&&(c(),w=t,d(t,"resizestart",p))}}function m(){f(w,"resizestart",p)}function g(){for(var e in N){var t=N[e];t.elm&&(C.unbind(t.elm),delete t.elm)}}function v(){try{i.getDoc().execCommand("enableObjectResizing",!1,!1)}catch(e){}}function y(e){var t;if(F){t=O.body.createControlRange();try{return t.addElement(e),t.select(),!0}catch(n){}}}function b(){w=_=null,F&&(m(),f(i.getBody(),"controlselect",h))}var C=i.dom,x=t.each,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O=i.getDoc(),I=document,F=n.ie&&n.ie<11;N={n:[.5,0,0,-1],e:[1,.5,1,0],s:[.5,1,0,1],w:[0,.5,-1,0],nw:[0,0,-1,-1],ne:[1,0,1,-1],se:[1,1,1,1],sw:[0,1,-1,1]};var z=".mce-content-body";return i.contentStyles.push(z+" div.mce-resizehandle {position: absolute;border: 1px solid black;background: #FFF;width: 5px;height: 5px;z-index: 10000}"+z+" .mce-resizehandle:hover {background: #000}"+z+" img[data-mce-selected], hr[data-mce-selected] {outline: 1px solid black;resize: none}"+z+" .mce-clonedresizable {position: absolute;"+(n.gecko?"":"outline: 1px dashed black;")+"opacity: .5;filter: alpha(opacity=50);z-index: 10000}"),i.on("init",function(){F?(i.on("ObjectResized",function(e){"TABLE"!=e.target.nodeName&&(c(),y(e.target))}),d(i.getBody(),"controlselect",h),i.on("mousedown",function(e){S=e})):(v(),n.ie>=11&&(i.on("mouseup",function(e){var t=e.target.nodeName;/^(TABLE|IMG|HR)$/.test(t)&&(i.selection.select(e.target,"TABLE"==t),i.nodeChanged())}),i.dom.bind(i.getBody(),"mscontrolselect",function(e){/^(TABLE|IMG|HR)$/.test(e.target.nodeName)&&(e.preventDefault(),"IMG"==e.target.tagName&&window.setTimeout(function(){i.selection.select(e.target)},0))}))),i.on("nodechange mousedown mouseup ResizeEditor",u),i.on("keydown keyup",function(e){w&&"TABLE"==w.nodeName&&u(e)}),i.on("hide",c)}),i.on("remove",g),{isResizable:o,showResizeRect:l,hideResizeRect:c,updateResizeRect:u,controlSelect:y,destroy:b}}}),r(B,[p,f],function(e,t){function n(e){this.walk=function(t,n){function i(e){var t;return t=e[0],3===t.nodeType&&t===l&&c>=t.nodeValue.length&&e.splice(0,1),t=e[e.length-1],0===d&&e.length>0&&t===u&&3===t.nodeType&&e.splice(e.length-1,1),e}function o(e,t,n){for(var r=[];e&&e!=n;e=e[t])r.push(e);return r}function a(e,t){do{if(e.parentNode==t)return e;e=e.parentNode}while(e)}function s(e,t,r){var a=r?"nextSibling":"previousSibling";for(m=e,g=m.parentNode;m&&m!=t;m=g)g=m.parentNode,v=o(m==e?m:m[a],a),v.length&&(r||v.reverse(),n(i(v)))}var l=t.startContainer,c=t.startOffset,u=t.endContainer,d=t.endOffset,f,p,h,m,g,v,y;if(y=e.select("td.mce-item-selected,th.mce-item-selected"),y.length>0)return void r(y,function(e){n([e])});if(1==l.nodeType&&l.hasChildNodes()&&(l=l.childNodes[c]),1==u.nodeType&&u.hasChildNodes()&&(u=u.childNodes[Math.min(d-1,u.childNodes.length-1)]),l==u)return n(i([l]));for(f=e.findCommonAncestor(l,u),m=l;m;m=m.parentNode){if(m===u)return s(l,f,!0);if(m===f)break}for(m=u;m;m=m.parentNode){if(m===l)return s(u,f);if(m===f)break}p=a(l,f)||l,h=a(u,f)||u,s(l,p,!0),v=o(p==l?p:p.nextSibling,"nextSibling",h==u?h.nextSibling:h),v.length&&n(i(v)),s(u,h)},this.split=function(e){function t(e,t){return e.splitText(t)}var n=e.startContainer,r=e.startOffset,i=e.endContainer,o=e.endOffset;return n==i&&3==n.nodeType?r>0&&rr?(o-=r,n=i=t(i,o).previousSibling,o=i.nodeValue.length,r=0):o=0):(3==n.nodeType&&r>0&&r0&&o0)return c=p,u=n?p.nodeValue.length:0,void(i=!0);if(e.isBlock(p)||h[p.nodeName.toLowerCase()])return;s=p}o&&s&&(c=s,i=!0,u=0)}var c,u,d,f=e.getRoot(),p,h,m,g;if(c=n[(r?"start":"end")+"Container"],u=n[(r?"start":"end")+"Offset"],g=1==c.nodeType&&u===c.childNodes.length,h=e.schema.getNonEmptyElements(),m=r,1==c.nodeType&&u>c.childNodes.length-1&&(m=!1),9===c.nodeType&&(c=e.getRoot(),u=0),c===f){if(m&&(p=c.childNodes[u>0?u-1:0],p&&(h[p.nodeName]||"TABLE"==p.nodeName)))return;if(c.hasChildNodes()&&(u=Math.min(!m&&u>0?u-1:u,c.childNodes.length-1),c=c.childNodes[u],u=0,c.hasChildNodes()&&!/TABLE/.test(c.nodeName))){p=c,d=new t(c,f);do{if(3===p.nodeType&&p.nodeValue.length>0){u=m?0:p.nodeValue.length,c=p,i=!0;break}if(h[p.nodeName.toLowerCase()]){u=e.nodeIndex(p),c=p.parentNode,"IMG"!=p.nodeName||m||u++,i=!0;break}}while(p=m?d.next():d.prev())}}o&&(3===c.nodeType&&0===u&&l(!0),1===c.nodeType&&(p=c.childNodes[u],p||(p=c.childNodes[u-1]),!p||"BR"!==p.nodeName||s(p,"A")||a(p)||a(p,!0)||l(!0,p))),m&&!o&&3===c.nodeType&&u===c.nodeValue.length&&l(!1),i&&n["set"+(r?"Start":"End")](c,u)}var i,o;return o=n.collapsed,r(!0),o||r(),i&&o&&n.collapse(!0),i}}var r=e.each;return n.compareRanges=function(e,t){if(e&&t){if(!e.item&&!e.duplicate)return e.startContainer==t.startContainer&&e.startOffset==t.startOffset;if(e.item&&t.item&&e.item(0)===t.item(0))return!0;if(e.isEqual&&t.isEqual&&t.isEqual(e))return!0}return!1},n}),r(D,[f,T,A,B,g,p],function(e,n,r,i,o,a){function s(e,t,i,o){var a=this;a.dom=e,a.win=t,a.serializer=i,a.editor=o,a.controlSelection=new r(a,o),a.win.getSelection||(a.tridentSel=new n(a))}var l=a.each,c=a.grep,u=a.trim,d=o.ie,f=o.opera;return s.prototype={setCursorLocation:function(e,t){var n=this,r=n.dom.createRng();e?(r.setStart(e,t),r.setEnd(e,t),n.setRng(r),n.collapse(!1)):(n._moveEndPoint(r,n.editor.getBody(),!0),n.setRng(r))},getContent:function(e){var n=this,r=n.getRng(),i=n.dom.create("body"),o=n.getSel(),a,s,l;return e=e||{},a=s="",e.get=!0,e.format=e.format||"html",e.selection=!0,n.editor.fire("BeforeGetContent",e),"text"==e.format?n.isCollapsed()?"":r.text||(o.toString?o.toString():""):(r.cloneContents?(l=r.cloneContents(),l&&i.appendChild(l)):r.item!==t||r.htmlText!==t?(i.innerHTML="
    "+(r.item?r.item(0).outerHTML:r.htmlText),i.removeChild(i.firstChild)):i.innerHTML=r.toString(),/^\s/.test(i.innerHTML)&&(a=" "),/\s+$/.test(i.innerHTML)&&(s=" "),e.getInner=!0,e.content=n.isCollapsed()?"":a+n.serializer.serialize(i,e)+s,n.editor.fire("GetContent",e),e.content)},setContent:function(e,t){var n=this,r=n.getRng(),i,o=n.win.document,a,s;if(t=t||{format:"html"},t.set=!0,t.selection=!0,e=t.content=e,t.no_events||n.editor.fire("BeforeSetContent",t),e=t.content,r.insertNode){e+='_',r.startContainer==o&&r.endContainer==o?o.body.innerHTML=e:(r.deleteContents(),0===o.body.childNodes.length?o.body.innerHTML=e:r.createContextualFragment?r.insertNode(r.createContextualFragment(e)):(a=o.createDocumentFragment(),s=o.createElement("div"),a.appendChild(s),s.outerHTML=e,r.insertNode(a))),i=n.dom.get("__caret"),r=o.createRange(),r.setStartBefore(i),r.setEndBefore(i),n.setRng(r),n.dom.remove("__caret");try{n.setRng(r)}catch(l){}}else r.item&&(o.execCommand("Delete",!1,null),r=n.getRng()),/^\s+/.test(e)?(r.pasteHTML('_'+e),n.dom.remove("__mce_tmp")):r.pasteHTML(e);t.no_events||n.editor.fire("SetContent",t)},getStart:function(){var e=this,t=e.getRng(),n,r,i,o;if(t.duplicate||t.item){if(t.item)return t.item(0);for(i=t.duplicate(),i.collapse(1),n=i.parentElement(),n.ownerDocument!==e.dom.doc&&(n=e.dom.getRoot()),r=o=t.parentElement();o=o.parentNode;)if(o==n){n=r;break}return n}return n=t.startContainer,1==n.nodeType&&n.hasChildNodes()&&(n=n.childNodes[Math.min(n.childNodes.length-1,t.startOffset)]),n&&3==n.nodeType?n.parentNode:n},getEnd:function(){var e=this,t=e.getRng(),n,r;return t.duplicate||t.item?t.item?t.item(0):(t=t.duplicate(),t.collapse(0),n=t.parentElement(),n.ownerDocument!==e.dom.doc&&(n=e.dom.getRoot()),n&&"BODY"==n.nodeName?n.lastChild||n:n):(n=t.endContainer,r=t.endOffset,1==n.nodeType&&n.hasChildNodes()&&(n=n.childNodes[r>0?r-1:r]),n&&3==n.nodeType?n.parentNode:n)},getBookmark:function(e,t){function n(e,t){var n=0;return l(a.select(e),function(e,r){e==t&&(n=r)}),n}function r(e){function t(t){var n,r,i,o=t?"start":"end";n=e[o+"Container"],r=e[o+"Offset"],1==n.nodeType&&"TR"==n.nodeName&&(i=n.childNodes,n=i[Math.min(t?r:r-1,i.length-1)],n&&(r=t?0:n.childNodes.length,e["set"+(t?"Start":"End")](n,r)))}return t(!0),t(),e}function i(){function e(e,n){var i=e[n?"startContainer":"endContainer"],a=e[n?"startOffset":"endOffset"],s=[],l,c,u=0;if(3==i.nodeType){if(t)for(l=i.previousSibling;l&&3==l.nodeType;l=l.previousSibling)a+=l.nodeValue.length;s.push(a)}else c=i.childNodes,a>=c.length&&c.length&&(u=1,a=Math.max(0,c.length-1)),s.push(o.dom.nodeIndex(c[a],t)+u);for(;i&&i!=r;i=i.parentNode)s.push(o.dom.nodeIndex(i,t));return s}var n=o.getRng(!0),r=a.getRoot(),i={};return i.start=e(n,!0),o.isCollapsed()||(i.end=e(n)),i}var o=this,a=o.dom,s,c,u,d,f,p,h="",m;if(2==e)return p=o.getNode(),f=p?p.nodeName:null,"IMG"==f?{name:f,index:n(f,p)}:o.tridentSel?o.tridentSel.getBookmark(e):i();if(e)return{rng:o.getRng()};if(s=o.getRng(),u=a.uniqueId(),d=o.isCollapsed(),m="overflow:hidden;line-height:0px",s.duplicate||s.item){if(s.item)return p=s.item(0),f=p.nodeName,{name:f,index:n(f,p)};c=s.duplicate();try{s.collapse(),s.pasteHTML(''+h+""),d||(c.collapse(!1),s.moveToElementText(c.parentElement()),0===s.compareEndPoints("StartToEnd",c)&&c.move("character",-1),c.pasteHTML(''+h+""))}catch(g){return null}}else{if(p=o.getNode(),f=p.nodeName,"IMG"==f)return{name:f,index:n(f,p)};c=r(s.cloneRange()),d||(c.collapse(!1),c.insertNode(a.create("span",{"data-mce-type":"bookmark",id:u+"_end",style:m},h))),s=r(s),s.collapse(!0),s.insertNode(a.create("span",{"data-mce-type":"bookmark",id:u+"_start",style:m},h))}return o.moveToBookmark({id:u,keep:1}),{id:u}},moveToBookmark:function(e){function t(t){var n=e[t?"start":"end"],r,i,o,l;if(n){for(o=n[0],i=s,r=n.length-1;r>=1;r--){if(l=i.childNodes,n[r]>l.length-1)return;i=l[n[r]]}3===i.nodeType&&(o=Math.min(n[0],i.nodeValue.length)),1===i.nodeType&&(o=Math.min(n[0],i.childNodes.length)),t?a.setStart(i,o):a.setEnd(i,o)}return!0}function n(t){var n=o.get(e.id+"_"+t),r,i,a,s,d=e.keep;if(n&&(r=n.parentNode,"start"==t?(d?(r=n.firstChild,i=1):i=o.nodeIndex(n),u=p=r,h=m=i):(d?(r=n.firstChild,i=1):i=o.nodeIndex(n),p=r,m=i),!d)){for(s=n.previousSibling,a=n.nextSibling,l(c(n.childNodes),function(e){3==e.nodeType&&(e.nodeValue=e.nodeValue.replace(/\uFEFF/g,""))});n=o.get(e.id+"_"+t);)o.remove(n,1);s&&a&&s.nodeType==a.nodeType&&3==s.nodeType&&!f&&(i=s.nodeValue.length,s.appendData(a.nodeValue),o.remove(a),"start"==t?(u=p=s,h=m=i):(p=s,m=i))}}function r(e){return!o.isBlock(e)||e.innerHTML||d||(e.innerHTML='
    '),e}var i=this,o=i.dom,a,s,u,p,h,m;if(e)if(e.start){if(a=o.createRng(),s=o.getRoot(),i.tridentSel)return i.tridentSel.moveToBookmark(e);t(!0)&&t()&&i.setRng(a)}else e.id?(n("start"),n("end"),u&&(a=o.createRng(),a.setStart(r(u),h),a.setEnd(r(p),m),i.setRng(a))):e.name?i.select(o.select(e.name)[e.index]):e.rng&&i.setRng(e.rng)},select:function(e,t){var n=this,r=n.dom,i=r.createRng(),o;if(n.lastFocusBookmark=null,e){if(!t&&n.controlSelection.controlSelect(e))return;o=r.nodeIndex(e),i.setStart(e.parentNode,o),i.setEnd(e.parentNode,o+1),t&&(n._moveEndPoint(i,e,!0),n._moveEndPoint(i,e)),n.setRng(i)}return e},isCollapsed:function(){var e=this,t=e.getRng(),n=e.getSel();return!t||t.item?!1:t.compareEndPoints?0===t.compareEndPoints("StartToEnd",t):!n||t.collapsed},collapse:function(e){var t=this,n=t.getRng(),r;n.item&&(r=n.item(0),n=t.win.document.body.createTextRange(),n.moveToElementText(r)),n.collapse(!!e),t.setRng(n)},getSel:function(){var e=this.win;return e.getSelection?e.getSelection():e.document.selection},getRng:function(e){function t(e,t,n){try{return t.compareBoundaryPoints(e,n)}catch(r){return-1}}var n=this,r,i,o,a=n.win.document,s;if(!e&&n.lastFocusBookmark){var l=n.lastFocusBookmark;return l.startContainer?(i=a.createRange(),i.setStart(l.startContainer,l.startOffset),i.setEnd(l.endContainer,l.endOffset)):i=l,i}if(e&&n.tridentSel)return n.tridentSel.getRangeAt(0);try{(r=n.getSel())&&(i=r.rangeCount>0?r.getRangeAt(0):r.createRange?r.createRange():a.createRange())}catch(c){}if(d&&i&&i.setStart&&a.selection){try{s=a.selection.createRange()}catch(c){}s&&s.item&&(o=s.item(0),i=a.createRange(),i.setStartBefore(o),i.setEndAfter(o))}return i||(i=a.createRange?a.createRange():a.body.createTextRange()),i.setStart&&9===i.startContainer.nodeType&&i.collapsed&&(o=n.dom.getRoot(),i.setStart(o,0),i.setEnd(o,0)),n.selectedRange&&n.explicitRange&&(0===t(i.START_TO_START,i,n.selectedRange)&&0===t(i.END_TO_END,i,n.selectedRange)?i=n.explicitRange:(n.selectedRange=null,n.explicitRange=null)),i},setRng:function(e,t){var n=this,r;if(e.select)try{e.select()}catch(i){}else if(n.tridentSel){if(e.cloneRange)try{return void n.tridentSel.addRange(e)}catch(i){}}else if(r=n.getSel()){n.explicitRange=e;try{r.removeAllRanges(),r.addRange(e)}catch(i){}t===!1&&r.extend&&(r.collapse(e.endContainer,e.endOffset),r.extend(e.startContainer,e.startOffset)),n.selectedRange=r.rangeCount>0?r.getRangeAt(0):null}},setNode:function(e){var t=this;return t.setContent(t.dom.getOuterHTML(e)),e},getNode:function(){function e(e,t){for(var n=e;e&&3===e.nodeType&&0===e.length;)e=t?e.nextSibling:e.previousSibling;return e||n}var t=this,n=t.getRng(),r,i=n.startContainer,o=n.endContainer,a=n.startOffset,s=n.endOffset,l=t.dom.getRoot();return n?n.setStart?(r=n.commonAncestorContainer,!n.collapsed&&(i==o&&2>s-a&&i.hasChildNodes()&&(r=i.childNodes[a]),3===i.nodeType&&3===o.nodeType&&(i=i.length===a?e(i.nextSibling,!0):i.parentNode,o=0===s?e(o.previousSibling,!1):o.parentNode,i&&i===o))?i:r&&3==r.nodeType?r.parentNode:r):(r=n.item?n.item(0):n.parentElement(),r.ownerDocument!==t.win.document&&(r=l),r):l},getSelectedBlocks:function(t,n){var r=this,i=r.dom,o,a,s=[];if(a=i.getRoot(),t=i.getParent(t||r.getStart(),i.isBlock),n=i.getParent(n||r.getEnd(),i.isBlock),t&&t!=a&&s.push(t),t&&n&&t!=n){o=t;for(var l=new e(t,a);(o=l.next())&&o!=n;)i.isBlock(o)&&s.push(o)}return n&&t!=n&&n!=a&&s.push(n),s},isForward:function(){var e=this.dom,t=this.getSel(),n,r;return t&&t.anchorNode&&t.focusNode?(n=e.createRng(),n.setStart(t.anchorNode,t.anchorOffset),n.collapse(!0),r=e.createRng(),r.setStart(t.focusNode,t.focusOffset),r.collapse(!0),n.compareBoundaryPoints(n.START_TO_START,r)<=0):!0},normalize:function(){var e=this,t=e.getRng();return!d&&new i(e.dom).normalize(t)&&e.setRng(t,e.isForward()),t},selectorChanged:function(e,t){var n=this,r;return n.selectorChangedData||(n.selectorChangedData={},r={},n.editor.on("NodeChange",function(e){var t=e.element,i=n.dom,o=i.getParents(t,null,i.getRoot()),a={};l(n.selectorChangedData,function(e,t){l(o,function(n){return i.is(n,t)?(r[t]||(l(e,function(e){e(!0,{node:n,selector:t,parents:o})}),r[t]=e),a[t]=e,!1):void 0})}),l(r,function(e,n){a[n]||(delete r[n],l(e,function(e){e(!1,{node:t,selector:n,parents:o})}))})})),n.selectorChangedData[e]||(n.selectorChangedData[e]=[]),n.selectorChangedData[e].push(t),n},getScrollContainer:function(){for(var e,t=this.dom.getRoot();t&&"BODY"!=t.nodeName;){if(t.scrollHeight>t.clientHeight){e=t;break}t=t.parentNode}return e},scrollIntoView:function(e){function t(e){for(var t=0,n=0,r=e;r&&r.nodeType;)t+=r.offsetLeft||0,n+=r.offsetTop||0,r=r.offsetParent;return{x:t,y:n}}var n,r,i=this,o=i.dom,a=o.getRoot(),s,l;if("BODY"!=a.nodeName){var c=i.getScrollContainer();if(c)return n=t(e).y-t(c).y,l=c.clientHeight,s=c.scrollTop,void((s>n||n+25>s+l)&&(c.scrollTop=s>n?n:n-l+25))}r=o.getViewPort(i.editor.getWin()),n=o.getPos(e).y,s=r.y,l=r.h,(ns+l)&&i.editor.getWin().scrollTo(0,s>n?n:n-l+25)},_moveEndPoint:function(t,n,r){var i=n,a=new e(n,i),s=this.dom.schema.getNonEmptyElements();do{if(3==n.nodeType&&0!==u(n.nodeValue).length)return void(r?t.setStart(n,0):t.setEnd(n,n.nodeValue.length));if(s[n.nodeName])return void(r?t.setStartBefore(n):"BR"==n.nodeName?t.setEndBefore(n):t.setEndAfter(n));if(o.ie&&o.ie<11&&this.dom.isBlock(n)&&this.dom.isEmpty(n))return void(r?t.setStart(n,0):t.setEnd(n,0))}while(n=r?a.next():a.prev());"BODY"==i.nodeName&&(r?t.setStart(i,0):t.setEnd(i,i.childNodes.length))},destroy:function(){this.win=null,this.controlSelection.destroy()}},s}),r(L,[p],function(e){function t(e,t){function r(e){return e.replace(/%(\w+)/g,"")}var i,o,a=e.dom,s="",l,c;if(c=e.settings.preview_styles,c===!1)return"";if(c||(c="font-family font-size font-weight font-style text-decoration text-transform color background-color border border-radius outline text-shadow"),"string"==typeof t){if(t=e.formatter.get(t),!t)return;t=t[0]}return i=t.block||t.inline||"span",o=a.create(i),n(t.styles,function(e,t){e=r(e),e&&a.setStyle(o,t,e)}),n(t.attributes,function(e,t){e=r(e),e&&a.setAttrib(o,t,e)}),n(t.classes,function(e){e=r(e),a.hasClass(o,e)||a.addClass(o,e)}),e.fire("PreviewFormats"),a.setStyles(o,{position:"absolute",left:-65535}),e.getBody().appendChild(o),l=a.getStyle(e.getBody(),"fontSize",!0),l=/px$/.test(l)?parseInt(l,10):0,n(c.split(" "),function(t){var n=a.getStyle(o,t,!0);if(!("background-color"==t&&/transparent|rgba\s*\([^)]+,\s*0\)/.test(n)&&(n=a.getStyle(e.getBody(),t,!0),"#ffffff"==a.toHex(n).toLowerCase())||"color"==t&&"#000000"==a.toHex(n).toLowerCase())){if("font-size"==t&&/em|%$/.test(n)){if(0===l)return;n=parseFloat(n,10)/(/%$/.test(n)?100:1),n=n*l+"px"}"border"==t&&n&&(s+="padding:0 2px;"),s+=t+":"+n+";"}}),e.fire("AfterPreviewFormats"),a.remove(o),s}var n=e.each;return{getCssText:t}}),r(M,[f,B,p,L],function(e,t,n,r){return function(i){function o(e){return e.nodeType&&(e=e.nodeName),!!i.schema.getTextBlockElements()[e.toLowerCase()]}function a(e,t){return z.getParents(e,t,z.getRoot())}function s(e){return 1===e.nodeType&&"_mce_caret"===e.id}function l(){d({valigntop:[{selector:"td,th",styles:{verticalAlign:"top"}}],valignmiddle:[{selector:"td,th",styles:{verticalAlign:"middle"}}],valignbottom:[{selector:"td,th",styles:{verticalAlign:"bottom"}}],alignleft:[{selector:"figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",styles:{textAlign:"left"},defaultBlock:"div"},{selector:"img,table",collapsed:!1,styles:{"float":"left"}}],aligncenter:[{selector:"figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",styles:{textAlign:"center"},defaultBlock:"div"},{selector:"img",collapsed:!1,styles:{display:"block",marginLeft:"auto",marginRight:"auto"}},{selector:"table",collapsed:!1,styles:{marginLeft:"auto",marginRight:"auto"}}],alignright:[{selector:"figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",styles:{textAlign:"right"},defaultBlock:"div"},{selector:"img,table",collapsed:!1,styles:{"float":"right"}}],alignjustify:[{selector:"figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",styles:{textAlign:"justify"},defaultBlock:"div"}],bold:[{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}},{inline:"b",remove:"all"}],italic:[{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}},{inline:"i",remove:"all"}],underline:[{inline:"span",styles:{textDecoration:"underline"},exact:!0},{inline:"u",remove:"all"}],strikethrough:[{inline:"span",styles:{textDecoration:"line-through"},exact:!0},{inline:"strike",remove:"all"}],forecolor:{inline:"span",styles:{color:"%value"},wrap_links:!1},hilitecolor:{inline:"span",styles:{backgroundColor:"%value"},wrap_links:!1},fontname:{inline:"span",styles:{fontFamily:"%value"}},fontsize:{inline:"span",styles:{fontSize:"%value"}},fontsize_class:{inline:"span",attributes:{"class":"%value"}},blockquote:{block:"blockquote",wrapper:1,remove:"all"},subscript:{inline:"sub"},superscript:{inline:"sup"},code:{inline:"code"},link:{inline:"a",selector:"a",remove:"all",split:!0,deep:!0,onmatch:function(){return!0},onformat:function(e,t,n){nt(n,function(t,n){z.setAttrib(e,n,t)})}},removeformat:[{selector:"b,strong,em,i,font,u,strike,sub,sup,dfn,code,samp,kbd,var,cite,mark,q",remove:"all",split:!0,expand:!1,block_expand:!0,deep:!0},{selector:"span",attributes:["style","class"],remove:"empty",split:!0,expand:!1,deep:!0},{selector:"*",attributes:["style","class"],split:!1,expand:!1,deep:!0}]}),nt("p h1 h2 h3 h4 h5 h6 div address pre div dt dd samp".split(/\s/),function(e){d(e,{block:e,remove:"all"})}),d(i.settings.formats)}function c(){i.addShortcut("ctrl+b","bold_desc","Bold"),i.addShortcut("ctrl+i","italic_desc","Italic"),i.addShortcut("ctrl+u","underline_desc","Underline");for(var e=1;6>=e;e++)i.addShortcut("ctrl+"+e,"",["FormatBlock",!1,"h"+e]);i.addShortcut("ctrl+7","",["FormatBlock",!1,"p"]),i.addShortcut("ctrl+8","",["FormatBlock",!1,"div"]),i.addShortcut("ctrl+9","",["FormatBlock",!1,"address"])}function u(e){return e?F[e]:F}function d(e,t){e&&("string"!=typeof e?nt(e,function(e,t){d(t,e)}):(t=t.length?t:[t],nt(t,function(e){e.deep===Q&&(e.deep=!e.selector),e.split===Q&&(e.split=!e.selector||e.inline),e.remove===Q&&e.selector&&!e.inline&&(e.remove="none"),e.selector&&e.inline&&(e.mixed=!0,e.block_expand=!0),"string"==typeof e.classes&&(e.classes=e.classes.split(/\s+/))}),F[e]=t))}function f(e){var t;return i.dom.getParent(e,function(e){return t=i.dom.getStyle(e,"text-decoration"),t&&"none"!==t}),t}function p(e){var t;1===e.nodeType&&e.parentNode&&1===e.parentNode.nodeType&&(t=f(e.parentNode),i.dom.getStyle(e,"color")&&t?i.dom.setStyle(e,"text-decoration",t):i.dom.getStyle(e,"textdecoration")===t&&i.dom.setStyle(e,"text-decoration",null))}function h(t,n,r){function a(e,t){if(t=t||m,e){if(t.onformat&&t.onformat(e,t,n,r),nt(t.styles,function(t,r){z.setStyle(e,r,k(t,n))}),t.styles){var i=z.getAttrib(e,"style");i&&e.setAttribute("data-mce-style",i)}nt(t.attributes,function(t,r){z.setAttrib(e,r,k(t,n))}),nt(t.classes,function(t){t=k(t,n),z.hasClass(e,t)||z.addClass(e,t)})}}function l(){function t(t,n){var i=new e(n);for(r=i.current();r;r=i.prev())if(r.childNodes.length>1||r==t||"BR"==r.tagName)return r}var n=i.selection.getRng(),o=n.startContainer,a=n.endContainer;if(o!=a&&0===n.endOffset){var s=t(o,a),l=3==s.nodeType?s.length:s.childNodes.length;n.setEnd(s,l)}return n}function c(e,t,n,r,i){var o=[],a=-1,s,l=-1,c=-1,u;return nt(e.childNodes,function(e,t){return"UL"===e.nodeName||"OL"===e.nodeName?(a=t,s=e,!1):void 0}),nt(e.childNodes,function(e,n){"SPAN"===e.nodeName&&"bookmark"==z.getAttrib(e,"data-mce-type")&&(e.id==t.id+"_start"?l=n:e.id==t.id+"_end"&&(c=n))}),0>=a||a>l&&c>a?(nt(rt(e.childNodes),i),0):(u=z.clone(n,Y),nt(rt(e.childNodes),function(e,t){(a>l&&a>t||l>a&&t>a)&&(o.push(e),e.parentNode.removeChild(e))}),a>l?e.insertBefore(u,s):l>a&&e.insertBefore(u,s.nextSibling),r.push(u),nt(o,function(e){u.appendChild(e)}),u)}function d(e,r,i){var l=[],u,d,p=!0;u=m.inline||m.block,d=z.create(u),a(d),V.walk(e,function(e){function h(e){var y,C,x,w,_;return _=p,y=e.nodeName.toLowerCase(),C=e.parentNode.nodeName.toLowerCase(),1===e.nodeType&&Z(e)&&(_=p,p="true"===Z(e),w=!0),N(y,"br")?(g=0,void(m.block&&z.remove(e))):m.wrapper&&v(e,t,n)?void(g=0):p&&!w&&m.block&&!m.wrapper&&o(y)&&U(C,u)?(e=z.rename(e,u),a(e),l.push(e),void(g=0)):m.selector&&(nt(f,function(t){"collapsed"in t&&t.collapsed!==b||z.is(e,t.selector)&&!s(e)&&(a(e,t),x=!0)}),!m.inline||x)?void(g=0):void(!p||w||!U(u,y)||!U(C,u)||!i&&3===e.nodeType&&1===e.nodeValue.length&&65279===e.nodeValue.charCodeAt(0)||s(e)||m.inline&&q(e)?"li"==y&&r?g=c(e,r,d,l,h):(g=0,nt(rt(e.childNodes),h),w&&(p=_),g=0):(g||(g=z.clone(d,Y),e.parentNode.insertBefore(g,e),l.push(g)),g.appendChild(e)))}var g;nt(e,h)}),m.wrap_links===!1&&nt(l,function(e){function t(e){var n,r,i;if("A"===e.nodeName){for(r=z.clone(d,Y),l.push(r),i=rt(e.childNodes),n=0;n1||!q(e))&&0===o)return void z.remove(e,1);if(m.inline||m.wrapper){if(m.exact||1!==o||(e=i(e)),nt(f,function(t){nt(z.select(t.inline,e),function(e){var r;if(!M(e)){if(t.wrap_links===!1){r=e.parentNode;do if("A"===r.nodeName)return;while(r=r.parentNode)}B(t,n,e,t.exact?e:null)}})}),v(e.parentNode,t,n))return z.remove(e,1),e=0,X;m.merge_with_parents&&z.getParent(e.parentNode,function(r){return v(r,t,n)?(z.remove(e,1),e=0,X):void 0}),e&&m.merge_siblings!==!1&&(e=H(L(e),e),e=H(e,L(e,X)))}})}var f=u(t),m=f[0],g,y,b=!r&&W.isCollapsed();if(m)if(r)r.nodeType?(y=z.createRng(),y.setStartBefore(r),y.setEndAfter(r),d(A(y,f),null,!0)):d(r,null,!0);else if(b&&m.inline&&!z.select("td.mce-item-selected,th.mce-item-selected").length)O("apply",t,n);else{var C=i.selection.getNode();$||!f[0].defaultBlock||z.getParent(C,z.isBlock)||h(f[0].defaultBlock),i.selection.setRng(l()),g=W.getBookmark(),d(A(W.getRng(X),f),g),m.styles&&(m.styles.color||m.styles.textDecoration)&&(it(C,p,"childNodes"),p(C)),W.moveToBookmark(g),I(W.getRng(X)),i.nodeChanged()}}function m(e,t,n){function r(e){var n,i,o,a,s;if(1===e.nodeType&&Z(e)&&(a=b,b="true"===Z(e),s=!0),n=rt(e.childNodes),b&&!s)for(i=0,o=p.length;o>i&&!B(p[i],t,e,e);i++);if(h.deep&&n.length){for(i=0,o=n.length;o>i;i++)r(n[i]);s&&(b=a)}}function o(n){var r;return nt(a(n.parentNode).reverse(),function(n){var i;r||"_start"==n.id||"_end"==n.id||(i=v(n,e,t),i&&i.split!==!1&&(r=n))}),r}function s(e,n,r,i){var o,a,s,l,c,u;if(e){for(u=e.parentNode,o=n.parentNode;o&&o!=u;o=o.parentNode){for(a=z.clone(o,Y),c=0;c=0;o--){if(s=t[o].selector,!s||t[o].defaultBlock)return X;for(i=r.length-1;i>=0;i--)if(z.is(r[i],s))return X}return Y}function x(e,t,n){var r;return J||(J={},r={},i.on("NodeChange",function(e){var t=a(e.element),n={};nt(J,function(e,i){nt(t,function(o){return v(o,i,{},e.similar)?(r[i]||(nt(e,function(e){e(!0,{node:o,format:i,parents:t})}),r[i]=e),n[i]=e,!1):void 0})}),nt(r,function(i,o){n[o]||(delete r[o],nt(i,function(n){n(!1,{node:e.element,format:o,parents:t})}))})})),nt(e.split(","),function(e){J[e]||(J[e]=[],J[e].similar=n),J[e].push(t)}),this}function w(e){return r.getCssText(i,e)}function _(e,t){return N(e,t.inline)?X:N(e,t.block)?X:t.selector?1==e.nodeType&&z.is(e,t.selector):void 0}function N(e,t){return e=e||"",t=t||"",e=""+(e.nodeName||e),t=""+(t.nodeName||t),e.toLowerCase()==t.toLowerCase()}function E(e,t){return S(z.getStyle(e,t),t)}function S(e,t){return("color"==t||"backgroundColor"==t)&&(e=z.toHex(e)),"fontWeight"==t&&700==e&&(e="bold"),"fontFamily"==t&&(e=e.replace(/[\'\"]/g,"").replace(/,\s+/g,",")),""+e}function k(e,t){return"string"!=typeof e?e=e(t):t&&(e=e.replace(/%(\w+)/g,function(e,n){return t[n]||e})),e}function T(e){return e&&3===e.nodeType&&/^([\t \r\n]+|)$/.test(e.nodeValue)}function R(e,t,n){var r=z.create(t,n);return e.parentNode.insertBefore(r,e),r.appendChild(e),r}function A(t,n,r){function s(e){function t(e){return"BR"==e.nodeName&&e.getAttribute("data-mce-bogus")&&!e.nextSibling}var r,i,o,a,s;if(r=i=e?g:y,a=e?"previousSibling":"nextSibling",s=z.getRoot(),3==r.nodeType&&!T(r)&&(e?v>0:bi?n:i,-1===n||r||n++):(n=a.indexOf(" ",t),i=a.indexOf("\xa0",t),n=-1!==n&&(-1===i||i>n)?n:i),n}var s,l,c,u;if(3===t.nodeType){if(c=a(t,n),-1!==c)return{container:t,offset:c};u=t}for(s=new e(t,z.getParent(t,q)||i.getBody());l=s[o?"prev":"next"]();)if(3===l.nodeType){if(u=l,c=a(l),-1!==c)return{container:l,offset:c}}else if(q(l))break;return u?(n=o?0:u.length,{container:u,offset:n}):void 0}function d(e,r){var i,o,s,l;for(3==e.nodeType&&0===e.nodeValue.length&&e[r]&&(e=e[r]),i=a(e),o=0;op?p:v],3==g.nodeType&&(v=0)),1==y.nodeType&&y.hasChildNodes()&&(p=y.childNodes.length-1,y=y.childNodes[b>p?p:b-1],3==y.nodeType&&(b=y.nodeValue.length)),g=c(g),y=c(y),(M(g.parentNode)||M(g))&&(g=M(g)?g:g.parentNode,g=g.nextSibling||g,3==g.nodeType&&(v=0)),(M(y.parentNode)||M(y))&&(y=M(y)?y:y.parentNode,y=y.previousSibling||y,3==y.nodeType&&(b=y.length)),n[0].inline&&(t.collapsed&&(m=u(g,v,!0),m&&(g=m.container,v=m.offset),m=u(y,b),m&&(y=m.container,b=m.offset)),h=l(y,b),h.node)){for(;h.node&&0===h.offset&&h.node.previousSibling;)h=l(h.node.previousSibling);h.node&&h.offset>0&&3===h.node.nodeType&&" "===h.node.nodeValue.charAt(h.offset-1)&&h.offset>1&&(y=h.node,y.splitText(h.offset-1))}return(n[0].inline||n[0].block_expand)&&(n[0].inline&&3==g.nodeType&&0!==v||(g=s(!0)),n[0].inline&&3==y.nodeType&&b!==y.nodeValue.length||(y=s())),n[0].selector&&n[0].expand!==Y&&!n[0].inline&&(g=d(g,"previousSibling"),y=d(y,"nextSibling")),(n[0].block||n[0].selector)&&(g=f(g,"previousSibling"),y=f(y,"nextSibling"),n[0].block&&(q(g)||(g=s(!0)),q(y)||(y=s()))),1==g.nodeType&&(v=j(g),g=g.parentNode),1==y.nodeType&&(b=j(y)+1,y=y.parentNode),{startContainer:g,startOffset:v,endContainer:y,endOffset:b}}function B(e,t,n,r){var i,o,a;if(!_(n,e))return Y;if("all"!=e.remove)for(nt(e.styles,function(e,i){e=S(k(e,t),i),"number"==typeof i&&(i=e,r=0),(!r||N(E(r,i),e))&&z.setStyle(n,i,""),a=1}),a&&""===z.getAttrib(n,"style")&&(n.removeAttribute("style"),n.removeAttribute("data-mce-style")),nt(e.attributes,function(e,i){var o;if(e=k(e,t),"number"==typeof i&&(i=e,r=0),!r||N(z.getAttrib(r,i),e)){if("class"==i&&(e=z.getAttrib(n,i),e&&(o="",nt(e.split(/\s+/),function(e){/mce\w+/.test(e)&&(o+=(o?" ":"")+e)}),o)))return void z.setAttrib(n,i,o);"class"==i&&n.removeAttribute("className"),G.test(i)&&n.removeAttribute("data-mce-"+i),n.removeAttribute(i)}}),nt(e.classes,function(e){e=k(e,t),(!r||z.hasClass(r,e))&&z.removeClass(n,e)}),o=z.getAttribs(n),i=0;ia?a:o]),3===r.nodeType&&n&&o>=r.nodeValue.length&&(r=new e(r,i.getBody()).next()||r),3!==r.nodeType||n||0!==o||(r=new e(r,i.getBody()).prev()||r),r}function O(t,n,r){function a(e){var t=z.create("span",{id:y,"data-mce-bogus":!0,style:b?"color:red":""});return e&&t.appendChild(i.getDoc().createTextNode(K)),t}function s(e,t){for(;e;){if(3===e.nodeType&&e.nodeValue!==K||e.childNodes.length>1)return!1;t&&1===e.nodeType&&t.push(e),e=e.firstChild}return!0}function l(e){for(;e;){if(e.id===y)return e;e=e.parentNode}}function c(t){var n;if(t)for(n=new e(t,t),t=n.current();t;t=n.next())if(3===t.nodeType)return t}function d(e,t){var n,r;if(e)r=W.getRng(!0),s(e)?(t!==!1&&(r.setStartBefore(e),r.setEndBefore(e)),z.remove(e)):(n=c(e),n.nodeValue.charAt(0)===K&&(n=n.deleteData(0,1)),z.remove(e,1)),W.setRng(r);else if(e=l(W.getStart()),!e)for(;e=z.get(y);)d(e,!1)}function f(){var e,t,i,o,s,d,f;e=W.getRng(!0),o=e.startOffset,d=e.startContainer,f=d.nodeValue,t=l(W.getStart()),t&&(i=c(t)),f&&o>0&&o=0;p--)c.appendChild(z.clone(f[p],!1)),c=c.firstChild;c.appendChild(z.doc.createTextNode(K)),c=c.firstChild;var g=z.getParent(d,o);g&&z.isEmpty(g)?d.parentNode.replaceChild(h,d):z.insertAfter(h,d),W.setCursorLocation(c,1),z.isEmpty(d)&&z.remove(d)}}function g(){var e;e=l(W.getStart()),e&&!z.isEmpty(e)&&it(e,function(e){1!=e.nodeType||e.id===y||z.isEmpty(e)||z.setAttrib(e,"data-mce-bogus",null)},"childNodes")}var y="_mce_caret",b=i.settings.caret_debug;i._hasCaretEvents||(tt=function(){var e=[],t;if(s(l(W.getStart()),e))for(t=e.length;t--;)z.setAttrib(e[t],"data-mce-bogus","1")},et=function(e){var t=e.keyCode;d(),(8==t||37==t||39==t)&&d(l(W.getStart())),g()},i.on("SetContent",function(e){e.selection&&g()}),i._hasCaretEvents=!0),"apply"==t?f():p()}function I(t){var n=t.startContainer,r=t.startOffset,i,o,a,s,l;if(3==n.nodeType&&r>=n.nodeValue.length&&(r=j(n),n=n.parentNode,i=!0),1==n.nodeType)for(s=n.childNodes,n=s[Math.min(r,s.length-1)],o=new e(n,z.getParent(n,z.isBlock)),(r>s.length-1||i)&&o.next(),a=o.current();a;a=o.next())if(3==a.nodeType&&!T(a))return l=z.create("a",null,K),a.parentNode.insertBefore(l,a),t.setStart(a,0),W.setRng(t),void z.remove(l)}var F={},z=i.dom,W=i.selection,V=new t(z),U=i.schema.isValidChild,q=z.isBlock,$=i.settings.forced_root_block,j=z.nodeIndex,K="\ufeff",G=/^(src|href|style)$/,Y=!1,X=!0,J,Q,Z=z.getContentEditable,et,tt,nt=n.each,rt=n.grep,it=n.walk,ot=n.extend;ot(this,{get:u,register:d,apply:h,remove:m,toggle:g,match:y,matchAll:b,matchNode:v,canApply:C,formatChanged:x,getCssText:w}),l(),c(),i.on("BeforeGetContent",function(){tt&&tt()}),i.on("mouseup keydown",function(e){et&&et(e)})}}),r(H,[g,p],function(e,t){var n=t.trim,r;return r=new RegExp(["]+data-mce-bogus[^>]+>[\u200b\ufeff]+<\\/span>","]+data-mce-bogus[^>]+><\\/div>",'\\s?data-mce-selected="[^"]+"'].join("|"),"gi"),function(t){function i(){return n(t.getContent({format:"raw",no_events:1}).replace(r,""))}function o(e){a.typing=!1,a.add({},e)}var a=this,s=0,l=[],c,u,d=0;return t.on("init",function(){a.add()}),t.on("BeforeExecCommand",function(e){var t=e.command;"Undo"!=t&&"Redo"!=t&&"mceRepaint"!=t&&a.beforeChange()}),t.on("ExecCommand",function(e){var t=e.command;"Undo"!=t&&"Redo"!=t&&"mceRepaint"!=t&&o(e)}),t.on("ObjectResizeStart",function(){a.beforeChange()}),t.on("SaveContent ObjectResized blur",o),t.on("DragEnd",o),t.on("KeyUp",function(n){var r=n.keyCode;(r>=33&&36>=r||r>=37&&40>=r||45==r||13==r||n.ctrlKey)&&(o(),t.nodeChanged()),(46==r||8==r||e.mac&&(91==r||93==r))&&t.nodeChanged(),u&&a.typing&&(t.isDirty()||(t.isNotDirty=!l[0]||i()==l[0].content,t.isNotDirty||t.fire("change",{level:l[0],lastLevel:null})),t.fire("TypingUndo"),u=!1,t.nodeChanged())}),t.on("KeyDown",function(e){var t=e.keyCode;return t>=33&&36>=t||t>=37&&40>=t||45==t?void(a.typing&&o(e)):void((16>t||t>20)&&224!=t&&91!=t&&!a.typing&&(a.beforeChange(),a.typing=!0,a.add({},e),u=!0))}),t.on("MouseDown",function(e){a.typing&&o(e)}),t.addShortcut("ctrl+z","","Undo"),t.addShortcut("ctrl+y,ctrl+shift+z","","Redo"),t.on("AddUndo Undo Redo ClearUndos MouseUp",function(e){e.isDefaultPrevented()||t.nodeChanged()}),a={data:l,typing:!1,beforeChange:function(){d||(c=t.selection.getBookmark(2,!0))},add:function(e,n){var r,o=t.settings,a;if(e=e||{},e.content=i(),d||t.removed)return null;if(a=l[s],t.fire("BeforeAddUndo",{level:e,lastLevel:a,originalEvent:n}).isDefaultPrevented())return null;if(a&&a.content==e.content)return null;if(l[s]&&(l[s].beforeBookmark=c),o.custom_undo_redo_levels&&l.length>o.custom_undo_redo_levels){for(r=0;r0&&(t.isNotDirty=!1,t.fire("change",u)),e},undo:function(){var e;return a.typing&&(a.add(),a.typing=!1),s>0&&(e=l[--s],0===s&&(t.isNotDirty=!0),t.setContent(e.content,{format:"raw"}),t.selection.moveToBookmark(e.beforeBookmark),t.fire("undo",{level:e})),e},redo:function(){var e;return s0||a.typing&&l[0]&&i()!=l[0].content},hasRedo:function(){return sD)&&(u=a.create("br"),t.parentNode.insertBefore(u,t)),l.setStartBefore(t),l.setEndBefore(t)):(l.setStartAfter(t),l.setEndAfter(t)):(l.setStart(t,0),l.setEnd(t,0));s.setRng(l),a.remove(u),s.scrollIntoView(t)}function g(e){var t=l.forced_root_block;t&&t.toLowerCase()===e.tagName.toLowerCase()&&a.setAttribs(e,l.forced_root_block_attrs)}function v(e){var t=R,n,i,o;if(e||"TABLE"==O?(n=a.create(e||F),g(n)):n=B.cloneNode(!1),o=n,l.keep_styles!==!1)do if(/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U|VAR|CITE|DFN|CODE|MARK|Q|SUP|SUB|SAMP)$/.test(t.nodeName)){if("_mce_caret"==t.id)continue;i=t.cloneNode(!1),a.setAttrib(i,"id",""),n.hasChildNodes()?(i.appendChild(n.firstChild),n.appendChild(i)):(o=i,n.appendChild(i))}while(t=t.parentNode);return r||(o.innerHTML='
    '),n}function y(t){var n,r,i;if(3==R.nodeType&&(t?A>0:A0)return!0}function w(){var e,t,n;R&&3==R.nodeType&&A>=R.nodeValue.length&&(r||x()||(e=a.create("br"),S.insertNode(e),S.setStartAfter(e),S.setEndAfter(e),t=!0)),e=a.create("br"),S.insertNode(e),r&&"PRE"==O&&(!D||8>D)&&e.parentNode.insertBefore(a.doc.createTextNode("\r"),e),n=a.create("span",{}," "),e.parentNode.insertBefore(n,e),s.scrollIntoView(n),a.remove(n),t?(S.setStartBefore(e),S.setEndBefore(e)):(S.setStartAfter(e),S.setEndAfter(e)),s.setRng(S),c.add()}function _(e){do 3===e.nodeType&&(e.nodeValue=e.nodeValue.replace(/^[\r\n]+/,"")),e=e.firstChild;while(e)}function N(e){var t=a.getRoot(),n,r;for(n=e;n!==t&&"false"!==a.getContentEditable(n);)"true"===a.getContentEditable(n)&&(r=n),n=n.parentNode;return n!==t?r:t}function E(e){var t;r||(e.normalize(),t=e.lastChild,(!t||/^(left|right)$/gi.test(a.getStyle(t,"float",!0)))&&a.add(e,"br"))}var S,k,T,R,A,B,D,L,M,H,P,O,I,F,z;if(S=s.getRng(!0),!o.isDefaultPrevented()){if(!S.collapsed)return void i.execCommand("Delete");if(new t(a).normalize(S),R=S.startContainer,A=S.startOffset,F=(l.force_p_newlines?"p":"")||l.forced_root_block,F=F?F.toUpperCase():"",D=a.doc.documentMode,L=o.shiftKey,1==R.nodeType&&R.hasChildNodes()&&(z=A>R.childNodes.length-1,R=R.childNodes[Math.min(A,R.childNodes.length-1)]||R,A=z&&3==R.nodeType?R.nodeValue.length:0),T=N(R)){if(c.beforeChange(),!a.isBlock(T)&&T!=a.getRoot())return void((!F||L)&&w());if((F&&!L||!F&&L)&&(R=b(R,A)),B=a.getParent(R,a.isBlock),P=B?a.getParent(B.parentNode,a.isBlock):null,O=B?B.nodeName.toUpperCase():"",I=P?P.nodeName.toUpperCase():"","LI"!=I||o.ctrlKey||(B=P,O=I),"LI"==O){if(!F&&L)return void w();if(a.isEmpty(B))return void C()}if("PRE"==O&&l.br_in_pre!==!1){if(!L)return void w()}else if(!F&&!L&&"LI"!=O||F&&L)return void w();F&&B===i.getBody()||(F=F||"P",y()?(M=/^(H[1-6]|PRE|FIGURE)$/.test(O)&&"HGROUP"!=I?v(F):v(),l.end_container_on_empty_block&&f(P)&&a.isEmpty(B)?M=a.split(P,B):a.insertAfter(M,B),m(M)):y(!0)?(M=B.parentNode.insertBefore(v(),B),p(M),m(B)):(k=S.cloneRange(),k.setEndAfter(B),H=k.extractContents(),_(H),M=H.firstChild,a.insertAfter(H,B),h(M),E(B),m(M)),a.setAttrib(M,"id",""),i.fire("NewBlock",{newBlock:M}),c.add())}}}var a=i.dom,s=i.selection,l=i.settings,c=i.undoManager,u=i.schema,d=u.getNonEmptyElements();i.on("keydown",function(e){13==e.keyCode&&o(e)!==!1&&e.preventDefault()})}}),r(O,[],function(){return function(e){function t(){var t=i.getStart(),s=e.getBody(),l,c,u,d,f,p,h,m=-16777215,g,v,y,b,C;if(C=n.forced_root_block,t&&1===t.nodeType&&C){for(;t&&t!=s;){if(a[t.nodeName])return;t=t.parentNode}if(l=i.getRng(),l.setStart){c=l.startContainer,u=l.startOffset,d=l.endContainer,f=l.endOffset;try{v=e.getDoc().activeElement===s}catch(x){}}else l.item&&(t=l.item(0),l=e.getDoc().body.createTextRange(),l.moveToElementText(t)),v=l.parentElement().ownerDocument===e.getDoc(),y=l.duplicate(),y.collapse(!0),u=-1*y.move("character",m),y.collapsed||(y=l.duplicate(),y.collapse(!1),f=-1*y.move("character",m)-u);for(t=s.firstChild,b=s.nodeName.toLowerCase();t;)if((3===t.nodeType||1==t.nodeType&&!a[t.nodeName])&&o.isValidChild(b,C.toLowerCase())){if(3===t.nodeType&&0===t.nodeValue.length){h=t,t=t.nextSibling,r.remove(h);continue}p||(p=r.create(C,e.settings.forced_root_block_attrs),t.parentNode.insertBefore(p,t),g=!0),h=t,t=t.nextSibling,p.appendChild(h)}else p=null,t=t.nextSibling;if(g&&v){if(l.setStart)l.setStart(c,u),l.setEnd(d,f),i.setRng(l);else try{l=e.getDoc().body.createTextRange(),l.moveToElementText(s),l.collapse(!0),l.moveStart("character",u),f>0&&l.moveEnd("character",f),l.select()}catch(x){}e.nodeChanged()}}}var n=e.settings,r=e.dom,i=e.selection,o=e.schema,a=o.getBlockElements();n.forced_root_block&&e.on("NodeChange",t)}}),r(I,[S,g,p],function(e,n,r){var i=r.each,o=r.extend,a=r.map,s=r.inArray,l=r.explode,c=n.gecko,u=n.ie,d=!0,f=!1;return function(r){function p(e,t,n){var r;return e=e.toLowerCase(),(r=N.exec[e])?(r(e,t,n),d):f}function h(e){var t;return e=e.toLowerCase(),(t=N.state[e])?t(e):-1}function m(e){var t;return e=e.toLowerCase(),(t=N.value[e])?t(e):f}function g(e,t){t=t||"exec",i(e,function(e,n){i(n.toLowerCase().split(","),function(n){N[t][n]=e})})}function v(e,n,i){return n===t&&(n=f),i===t&&(i=null),r.getDoc().execCommand(e,n,i)}function y(e){return S.match(e)}function b(e,n){S.toggle(e,n?{value:n}:t),r.nodeChanged()}function C(e){k=_.getBookmark(e)}function x(){_.moveToBookmark(k)}var w=r.dom,_=r.selection,N={state:{},exec:{},value:{}},E=r.settings,S=r.formatter,k;o(this,{execCommand:p,queryCommandState:h,queryCommandValue:m,addCommands:g}),g({"mceResetDesignMode,mceBeginUndoLevel":function(){},"mceEndUndoLevel,mceAddUndoLevel":function(){r.undoManager.add()},"Cut,Copy,Paste":function(e){var t=r.getDoc(),i;try{v(e)}catch(o){i=d}if(i||!t.queryCommandSupported(e)){var a=r.translate("Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.");n.mac&&(a=a.replace(/Ctrl\+/g,"\u2318+")),r.windowManager.alert(a)}},unlink:function(){if(_.isCollapsed()){var e=_.getNode();return void("A"==e.tagName&&r.dom.remove(e,!0))}S.remove("link")},"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(e){var t=e.substring(7);"full"==t&&(t="justify"),i("left,center,right,justify".split(","),function(e){t!=e&&S.remove("align"+e)}),b("align"+t),p("mceRepaint")},"InsertUnorderedList,InsertOrderedList":function(e){var t,n;v(e),t=w.getParent(_.getNode(),"ol,ul"),t&&(n=t.parentNode,/^(H[1-6]|P|ADDRESS|PRE)$/.test(n.nodeName)&&(C(),w.split(n,t),x()))},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(e){b(e)},"ForeColor,HiliteColor,FontName":function(e,t,n){b(e,n)},FontSize:function(e,t,n){var r,i;n>=1&&7>=n&&(i=l(E.font_size_style_values),r=l(E.font_size_classes),n=r?r[n-1]||n:i[n-1]||n),b(e,n)},RemoveFormat:function(e){S.remove(e)},mceBlockQuote:function(){b("blockquote")},FormatBlock:function(e,t,n){return b(n||"p")},mceCleanup:function(){var e=_.getBookmark();r.setContent(r.getContent({cleanup:d}),{cleanup:d}),_.moveToBookmark(e)},mceRemoveNode:function(e,t,n){var i=n||_.getNode();i!=r.getBody()&&(C(),r.dom.remove(i,d),x())},mceSelectNodeDepth:function(e,t,n){var i=0;w.getParent(_.getNode(),function(e){return 1==e.nodeType&&i++==n?(_.select(e),f):void 0},r.getBody())},mceSelectNode:function(e,t,n){_.select(n)},mceInsertContent:function(t,n,i){function o(e){function t(e){return r[e]&&3==r[e].nodeType}var n,r,i;return n=_.getRng(!0),r=n.startContainer,i=n.startOffset,3==r.nodeType&&(i>0?e=e.replace(/^ /," "):t("previousSibling")||(e=e.replace(/^ /," ")),i|)$/," "):t("nextSibling")||(e=e.replace(/( | )(
    |)$/," "))),e}var a,s,l,c,d,f,p,h,m,g,v;/^ | $/.test(i)&&(i=o(i)),a=r.parser,s=new e({},r.schema),v='ÈB;',f={content:i,format:"html",selection:!0},r.fire("BeforeSetContent",f),i=f.content,-1==i.indexOf("{$caret}")&&(i+="{$caret}"),i=i.replace(/\{\$caret\}/,v),h=_.getRng();var y=h.startContainer||(h.parentElement?h.parentElement():null),b=r.getBody();y===b&&_.isCollapsed()&&w.isBlock(b.firstChild)&&w.isEmpty(b.firstChild)&&(h=w.createRng(),h.setStart(b.firstChild,0),h.setEnd(b.firstChild,0),_.setRng(h)),_.isCollapsed()||r.getDoc().execCommand("Delete",!1,null),l=_.getNode();var C={context:l.nodeName.toLowerCase()};if(d=a.parse(i,C),m=d.lastChild,"mce_marker"==m.attr("id"))for(p=m,m=m.prev;m;m=m.walk(!0))if(3==m.type||!w.isBlock(m.name)){m.parent.insert(p,m,"br"===m.name);break}if(C.invalid){for(_.setContent(v),l=_.getNode(),c=r.getBody(),9==l.nodeType?l=m=c:m=l;m!==c;)l=m,m=m.parentNode;i=l==c?c.innerHTML:w.getOuterHTML(l),i=s.serialize(a.parse(i.replace(//i,function(){return s.serialize(d)}))),l==c?w.setHTML(c,i):w.setOuterHTML(l,i)}else i=s.serialize(d),m=l.firstChild,g=l.lastChild,!m||m===g&&"BR"===m.nodeName?w.setHTML(l,i):_.setContent(i);p=w.get("mce_marker"),_.scrollIntoView(p),h=w.createRng(),m=p.previousSibling,m&&3==m.nodeType?(h.setStart(m,m.nodeValue.length),u||(g=p.nextSibling,g&&3==g.nodeType&&(m.appendData(g.data),g.parentNode.removeChild(g)))):(h.setStartBefore(p),h.setEndBefore(p)),w.remove(p),_.setRng(h),r.fire("SetContent",f),r.addVisual()},mceInsertRawHTML:function(e,t,n){_.setContent("tiny_mce_marker"),r.setContent(r.getContent().replace(/tiny_mce_marker/g,function(){return n}))},mceToggleFormat:function(e,t,n){b(n)},mceSetContent:function(e,t,n){r.setContent(n)},"Indent,Outdent":function(e){var t,n,o;t=E.indentation,n=/[a-z%]+$/i.exec(t),t=parseInt(t,10),h("InsertUnorderedList")||h("InsertOrderedList")?v(e):(E.forced_root_block||w.getParent(_.getNode(),w.isBlock)||S.apply("div"),i(_.getSelectedBlocks(),function(i){if("LI"!=i.nodeName){var a=r.getParam("indent_use_margin",!1)?"margin":"padding";a+="rtl"==w.getStyle(i,"direction",!0)?"Right":"Left","outdent"==e?(o=Math.max(0,parseInt(i.style[a]||0,10)-t),w.setStyle(i,a,o?o+n:"")):(o=parseInt(i.style[a]||0,10)+t+n,w.setStyle(i,a,o))}}))},mceRepaint:function(){if(c)try{C(d),_.getSel()&&_.getSel().selectAllChildren(r.getBody()),_.collapse(d),x()}catch(e){}},InsertHorizontalRule:function(){r.execCommand("mceInsertContent",!1,"
    ")},mceToggleVisualAid:function(){r.hasVisual=!r.hasVisual,r.addVisual()},mceReplaceContent:function(e,t,n){r.execCommand("mceInsertContent",!1,n.replace(/\{\$selection\}/g,_.getContent({format:"text"})))},mceInsertLink:function(e,t,n){var r;"string"==typeof n&&(n={href:n}),r=w.getParent(_.getNode(),"a"),n.href=n.href.replace(" ","%20"),r&&n.href||S.remove("link"),n.href&&S.apply("link",n,r)},selectAll:function(){var e=w.getRoot(),t;_.getRng().setStart?(t=w.createRng(),t.setStart(e,0),t.setEnd(e,e.childNodes.length),_.setRng(t)):(t=_.getRng(),t.item||(t.moveToElementText(e),t.select()))},"delete":function(){v("Delete");var e=r.getBody();w.isEmpty(e)&&(r.setContent(""),e.firstChild&&w.isBlock(e.firstChild)?r.selection.setCursorLocation(e.firstChild,0):r.selection.setCursorLocation(e,0))},mceNewDocument:function(){r.setContent("")}}),g({"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(e){var t="align"+e.substring(7),n=_.isCollapsed()?[w.getParent(_.getNode(),w.isBlock)]:_.getSelectedBlocks(),r=a(n,function(e){return!!S.matchNode(e,t)});return-1!==s(r,d)},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(e){return y(e)},mceBlockQuote:function(){return y("blockquote")},Outdent:function(){var e;if(E.inline_styles){if((e=w.getParent(_.getStart(),w.isBlock))&&parseInt(e.style.paddingLeft,10)>0)return d;if((e=w.getParent(_.getEnd(),w.isBlock))&&parseInt(e.style.paddingLeft,10)>0)return d +}return h("InsertUnorderedList")||h("InsertOrderedList")||!E.inline_styles&&!!w.getParent(_.getNode(),"BLOCKQUOTE")},"InsertUnorderedList,InsertOrderedList":function(e){var t=w.getParent(_.getNode(),"ul,ol");return t&&("insertunorderedlist"===e&&"UL"===t.tagName||"insertorderedlist"===e&&"OL"===t.tagName)}},"state"),g({"FontSize,FontName":function(e){var t=0,n;return(n=w.getParent(_.getNode(),"span"))&&(t="fontsize"==e?n.style.fontSize:n.style.fontFamily.replace(/, /g,",").replace(/[\'\"]/g,"").toLowerCase()),t}},"value"),g({Undo:function(){r.undoManager.undo()},Redo:function(){r.undoManager.redo()}})}}),r(F,[p],function(e){function t(e,i){var o=this,a,s;if(e=r(e),i=o.settings=i||{},/^([\w\-]+):([^\/]{2})/i.test(e)||/^\s*#/.test(e))return void(o.source=e);var l=0===e.indexOf("//");0!==e.indexOf("/")||l||(e=(i.base_uri?i.base_uri.protocol||"http":"http")+"://mce_host"+e),/^[\w\-]*:?\/\//.test(e)||(s=i.base_uri?i.base_uri.path:new t(location.href).directory,e=""===i.base_uri.protocol?"//mce_host"+o.toAbsPath(s,e):(i.base_uri&&i.base_uri.protocol||"http")+"://mce_host"+o.toAbsPath(s,e)),e=e.replace(/@@/g,"(mce_at)"),e=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(e),n(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],function(t,n){var r=e[n];r&&(r=r.replace(/\(mce_at\)/g,"@@")),o[t]=r}),a=i.base_uri,a&&(o.protocol||(o.protocol=a.protocol),o.userInfo||(o.userInfo=a.userInfo),o.port||"mce_host"!==o.host||(o.port=a.port),o.host&&"mce_host"!==o.host||(o.host=a.host),o.source=""),l&&(o.protocol="")}var n=e.each,r=e.trim,i={ftp:21,http:80,https:443,mailto:25};return t.prototype={setPath:function(e){var t=this;e=/^(.*?)\/?(\w+)?$/.exec(e),t.path=e[0],t.directory=e[1],t.file=e[2],t.source="",t.getURI()},toRelative:function(e){var n=this,r;if("./"===e)return e;if(e=new t(e,{base_uri:n}),"mce_host"!=e.host&&n.host!=e.host&&e.host||n.port!=e.port||n.protocol!=e.protocol&&""!==e.protocol)return e.getURI();var i=n.getURI(),o=e.getURI();return i==o||"/"==i.charAt(i.length-1)&&i.substr(0,i.length-1)==o?i:(r=n.toRelPath(n.path,e.path),e.query&&(r+="?"+e.query),e.anchor&&(r+="#"+e.anchor),r)},toAbsolute:function(e,n){return e=new t(e,{base_uri:this}),e.getURI(n&&this.isSameOrigin(e))},isSameOrigin:function(e){if(this.host==e.host&&this.protocol==e.protocol){if(this.port==e.port)return!0;var t=i[this.protocol];if(t&&(this.port||t)==(e.port||t))return!0}return!1},toRelPath:function(e,t){var n,r=0,i="",o,a;if(e=e.substring(0,e.lastIndexOf("/")),e=e.split("/"),n=t.split("/"),e.length>=n.length)for(o=0,a=e.length;a>o;o++)if(o>=n.length||e[o]!=n[o]){r=o+1;break}if(e.lengtho;o++)if(o>=e.length||e[o]!=n[o]){r=o+1;break}if(1===r)return t;for(o=0,a=e.length-(r-1);a>o;o++)i+="../";for(o=r-1,a=n.length;a>o;o++)i+=o!=r-1?"/"+n[o]:n[o];return i},toAbsPath:function(e,t){var r,i=0,o=[],a,s;for(a=/\/$/.test(t)?"/":"",e=e.split("/"),t=t.split("/"),n(e,function(e){e&&o.push(e)}),e=o,r=t.length-1,o=[];r>=0;r--)0!==t[r].length&&"."!==t[r]&&(".."!==t[r]?i>0?i--:o.push(t[r]):i++);return r=e.length-i,s=0>=r?o.reverse().join("/"):e.slice(0,r).join("/")+"/"+o.reverse().join("/"),0!==s.indexOf("/")&&(s="/"+s),a&&s.lastIndexOf("/")!==s.length-1&&(s+=a),s},getURI:function(e){var t,n=this;return(!n.source||e)&&(t="",e||(t+=n.protocol?n.protocol+"://":"//",n.userInfo&&(t+=n.userInfo+"@"),n.host&&(t+=n.host),n.port&&(t+=":"+n.port)),n.path&&(t+=n.path),n.query&&(t+="?"+n.query),n.anchor&&(t+="#"+n.anchor),n.source=t),n.source}},t}),r(z,[p],function(e){function t(){}var n=e.each,r=e.extend,i,o;return t.extend=i=function(e){function t(){var e,t,n,r=this;if(!o&&(r.init&&r.init.apply(r,arguments),t=r.Mixins))for(e=t.length;e--;)n=t[e],n.init&&n.init.apply(r,arguments)}function a(){return this}function s(e,t){return function(){var n=this,r=n._super,i;return n._super=c[e],i=t.apply(n,arguments),n._super=r,i}}var l=this,c=l.prototype,u,d,f;o=!0,u=new l,o=!1,e.Mixins&&(n(e.Mixins,function(t){t=t;for(var n in t)"init"!==n&&(e[n]=t[n])}),c.Mixins&&(e.Mixins=c.Mixins.concat(e.Mixins))),e.Methods&&n(e.Methods.split(","),function(t){e[t]=a}),e.Properties&&n(e.Properties.split(","),function(t){var n="_"+t;e[t]=function(e){var t=this,r;return e!==r?(t[n]=e,t):t[n]}}),e.Statics&&n(e.Statics,function(e,n){t[n]=e}),e.Defaults&&c.Defaults&&(e.Defaults=r({},c.Defaults,e.Defaults));for(d in e)f=e[d],u[d]="function"==typeof f&&c[d]?s(d,f):f;return t.prototype=u,t.constructor=t,t.extend=i,t},t}),r(W,[p],function(e){function t(e){function t(){return!1}function n(){return!0}function r(r,i){var o,a,s,u;if(r=r.toLowerCase(),i=i||{},i.type=r,i.target||(i.target=l),i.preventDefault||(i.preventDefault=function(){i.isDefaultPrevented=n},i.stopPropagation=function(){i.isPropagationStopped=n},i.stopImmediatePropagation=function(){i.isImmediatePropagationStopped=n},i.isDefaultPrevented=t,i.isPropagationStopped=t,i.isImmediatePropagationStopped=t),e.beforeFire&&e.beforeFire(i),o=c[r])for(a=0,s=o.length;s>a;a++){if(o[a]=u=o[a],i.isImmediatePropagationStopped())return i.stopPropagation(),i;if(u.call(l,i)===!1)return i.preventDefault(),i}return i}function i(e,n,r){var i,o,a;if(n===!1&&(n=t),n)for(o=e.toLowerCase().split(" "),a=o.length;a--;)e=o[a],i=c[e],i||(i=c[e]=[],u(e,!0)),r?i.unshift(n):i.push(n);return s}function o(e,t){var n,r,i,o,a;if(e)for(o=e.toLowerCase().split(" "),n=o.length;n--;){if(e=o[n],r=c[e],!e){for(i in c)u(i,!1),delete c[i];return s}if(r){if(t)for(a=r.length;a--;)r[a]===t&&r.splice(a,1);else r.length=0;r.length||(u(e,!1),delete c[e])}}else{for(e in c)u(e,!1);c={}}return s}function a(e){return e=e.toLowerCase(),!(!c[e]||0===c[e].length)}var s=this,l,c={},u;e=e||{},l=e.scope||s,u=e.toggleEvent||t,s.fire=r,s.on=i,s.off=o,s.has=a}var n=e.makeMap("focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange mouseout mouseenter mouseleave wheel keydown keypress keyup input contextmenu dragstart dragend dragover draggesture dragdrop drop drag submit"," ");return t.isNative=function(e){return!!n[e.toLowerCase()]},t}),r(V,[z],function(e){function t(e){for(var t=[],n=e.length,r;n--;)r=e[n],r.__checked||(t.push(r),r.__checked=1);for(n=t.length;n--;)delete t[n].__checked;return t}var n=/^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i,r=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,i=/^\s*|\s*$/g,o,a=e.extend({init:function(e){function t(e){return e?(e=e.toLowerCase(),function(t){return"*"===e||t.type===e}):void 0}function o(e){return e?function(t){return t._name===e}:void 0}function a(e){return e?(e=e.split("."),function(t){for(var n=e.length;n--;)if(!t.hasClass(e[n]))return!1;return!0}):void 0}function s(e,t,n){return e?function(r){var i=r[e]?r[e]():"";return t?"="===t?i===n:"*="===t?i.indexOf(n)>=0:"~="===t?(" "+i+" ").indexOf(" "+n+" ")>=0:"!="===t?i!=n:"^="===t?0===i.indexOf(n):"$="===t?i.substr(i.length-n.length)===n:!1:!!n}:void 0}function l(e){var t;return e?(e=/(?:not\((.+)\))|(.+)/i.exec(e),e[1]?(t=u(e[1],[]),function(e){return!d(e,t)}):(e=e[2],function(t,n,r){return"first"===e?0===n:"last"===e?n===r-1:"even"===e?n%2===0:"odd"===e?n%2===1:t[e]?t[e]():!1})):void 0}function c(e,r,c){function u(e){e&&r.push(e)}var d;return d=n.exec(e.replace(i,"")),u(t(d[1])),u(o(d[2])),u(a(d[3])),u(s(d[4],d[5],d[6])),u(l(d[7])),r.psuedo=!!d[7],r.direct=c,r}function u(e,t){var n=[],i,o,a;do if(r.exec(""),o=r.exec(e),o&&(e=o[3],n.push(o[1]),o[2])){i=o[3];break}while(o);for(i&&u(i,t),e=[],a=0;a"!=n[a]&&e.push(c(n[a],[],">"===n[a-1]));return t.push(e),t}var d=this.match;this._selectors=u(e,[])},match:function(e,t){var n,r,i,o,a,s,l,c,u,d,f,p,h;for(t=t||this._selectors,n=0,r=t.length;r>n;n++){for(a=t[n],o=a.length,h=e,p=0,i=o-1;i>=0;i--)for(c=a[i];h;){if(c.psuedo)for(f=h.parent().items(),u=d=f.length;u--&&f[u]!==h;);for(s=0,l=c.length;l>s;s++)if(!c[s](h,u,d)){s=l+1;break}if(s===l){p++;break}if(i===o-1)break;h=h.parent()}if(p===o)return!0}return!1},find:function(e){function n(e,t,i){var o,a,s,l,c,u=t[i];for(o=0,a=e.length;a>o;o++){for(c=e[o],s=0,l=u.length;l>s;s++)if(!u[s](c,o,a)){s=l+1;break}if(s===l)i==t.length-1?r.push(c):c.items&&n(c.items(),t,i+1);else if(u.direct)return;c.items&&n(c.items(),t,i)}}var r=[],i,s,l=this._selectors;if(e.items){for(i=0,s=l.length;s>i;i++)n(e.items(),l[i],0);s>1&&(r=t(r))}return o||(o=a.Collection),new o(r)}});return a}),r(U,[p,V,z],function(e,t,n){var r,i,o=Array.prototype.push,a=Array.prototype.slice;return i={length:0,init:function(e){e&&this.add(e)},add:function(t){var n=this;return e.isArray(t)?o.apply(n,t):t instanceof r?n.add(t.toArray()):o.call(n,t),n},set:function(e){var t=this,n=t.length,r;for(t.length=0,t.add(e),r=t.length;n>r;r++)delete t[r];return t},filter:function(e){var n=this,i,o,a=[],s,l;for("string"==typeof e?(e=new t(e),l=function(t){return e.match(t)}):l=e,i=0,o=n.length;o>i;i++)s=n[i],l(s)&&a.push(s);return new r(a)},slice:function(){return new r(a.apply(this,arguments))},eq:function(e){return-1===e?this.slice(e):this.slice(e,+e+1)},each:function(t){return e.each(this,t),this},toArray:function(){return e.toArray(this)},indexOf:function(e){for(var t=this,n=t.length;n--&&t[n]!==e;);return n},reverse:function(){return new r(e.toArray(this).reverse())},hasClass:function(e){return this[0]?this[0].hasClass(e):!1},prop:function(e,t){var n=this,r,i;return t!==r?(n.each(function(n){n[e]&&n[e](t)}),n):(i=n[0],i&&i[e]?i[e]():void 0)},exec:function(t){var n=this,r=e.toArray(arguments).slice(1);return n.each(function(e){e[t]&&e[t].apply(e,r)}),n},remove:function(){for(var e=this.length;e--;)this[e].remove();return this}},e.each("fire on off show hide addClass removeClass append prepend before after reflow".split(" "),function(t){i[t]=function(){var n=e.toArray(arguments);return this.each(function(e){t in e&&e[t].apply(e,n)}),this}}),e.each("text name disabled active selected checked visible parent value data".split(" "),function(e){i[e]=function(t){return this.prop(e,t)}}),r=n.extend(i),t.Collection=r,r}),r(q,[p,y],function(e,t){return{id:function(){return t.DOM.uniqueId()},createFragment:function(e){return t.DOM.createFragment(e)},getWindowSize:function(){return t.DOM.getViewPort()},getSize:function(e){var t,n;if(e.getBoundingClientRect){var r=e.getBoundingClientRect();t=Math.max(r.width||r.right-r.left,e.offsetWidth),n=Math.max(r.height||r.bottom-r.bottom,e.offsetHeight)}else t=e.offsetWidth,n=e.offsetHeight;return{width:t,height:n}},getPos:function(e,n){return t.DOM.getPos(e,n)},getViewPort:function(e){return t.DOM.getViewPort(e)},get:function(e){return document.getElementById(e)},addClass:function(e,n){return t.DOM.addClass(e,n)},removeClass:function(e,n){return t.DOM.removeClass(e,n)},hasClass:function(e,n){return t.DOM.hasClass(e,n)},toggleClass:function(e,n,r){return t.DOM.toggleClass(e,n,r)},css:function(e,n,r){return t.DOM.setStyle(e,n,r)},on:function(e,n,r,i){return t.DOM.bind(e,n,r,i)},off:function(e,n,r){return t.DOM.unbind(e,n,r)},fire:function(e,n,r){return t.DOM.fire(e,n,r)},innerHtml:function(e,n){t.DOM.setHTML(e,n)}}}),r($,[z,p,W,U,q],function(e,t,n,r,i){function o(e){return e._eventDispatcher||(e._eventDispatcher=new n({scope:e,toggleEvent:function(t,r){r&&n.isNative(t)&&(e._nativeEvents||(e._nativeEvents={}),e._nativeEvents[t]=!0,e._rendered&&e.bindPendingEvents())}})),e._eventDispatcher}var a={},s="onmousewheel"in document,l=!1,c="mce-",u=e.extend({Statics:{elementIdCache:a,classPrefix:c},isRtl:function(){return u.rtl},classPrefix:c,init:function(e){var n=this,r,o;if(n.settings=e=t.extend({},n.Defaults,e),n._id=e.id||i.id(),n._text=n._name="",n._width=n._height=0,n._aria={role:e.role},r=e.classes)for(r=r.split(" "),r.map={},o=r.length;o--;)r.map[r[o]]=!0;n._classes=r||[],n.visible(!0),t.each("title text width height name classes visible disabled active value".split(" "),function(t){var r=e[t],i;r!==i?n[t](r):n["_"+t]===i&&(n["_"+t]=!1)}),n.on("click",function(){return n.disabled()?!1:void 0}),e.classes&&t.each(e.classes.split(" "),function(e){n.addClass(e)}),n.settings=e,n._borderBox=n.parseBox(e.border),n._paddingBox=n.parseBox(e.padding),n._marginBox=n.parseBox(e.margin),e.hidden&&n.hide()},Properties:"parent,title,text,width,height,disabled,active,name,value",Methods:"renderHtml",getContainerElm:function(){return document.body},getParentCtrl:function(e){for(var t,n=this.getRoot().controlIdLookup;e&&n&&!(t=n[e.id]);)e=e.parentNode;return t},parseBox:function(e){var t,n=10;if(e)return"number"==typeof e?(e=e||0,{top:e,left:e,bottom:e,right:e}):(e=e.split(" "),t=e.length,1===t?e[1]=e[2]=e[3]=e[0]:2===t?(e[2]=e[0],e[3]=e[1]):3===t&&(e[3]=e[1]),{top:parseInt(e[0],n)||0,right:parseInt(e[1],n)||0,bottom:parseInt(e[2],n)||0,left:parseInt(e[3],n)||0})},borderBox:function(){return this._borderBox},paddingBox:function(){return this._paddingBox},marginBox:function(){return this._marginBox},measureBox:function(e,t){function n(t){var n=document.defaultView;return n?(t=t.replace(/[A-Z]/g,function(e){return"-"+e}),n.getComputedStyle(e,null).getPropertyValue(t)):e.currentStyle[t]}function r(e){var t=parseFloat(n(e),10);return isNaN(t)?0:t}return{top:r(t+"TopWidth"),right:r(t+"RightWidth"),bottom:r(t+"BottomWidth"),left:r(t+"LeftWidth")}},initLayoutRect:function(){var e=this,t=e.settings,n,r,o=e.getEl(),a,s,l,c,u,d,f,p;n=e._borderBox=e._borderBox||e.measureBox(o,"border"),e._paddingBox=e._paddingBox||e.measureBox(o,"padding"),e._marginBox=e._marginBox||e.measureBox(o,"margin"),p=i.getSize(o),d=t.minWidth,f=t.minHeight,l=d||p.width,c=f||p.height,a=t.width,s=t.height,u=t.autoResize,u="undefined"!=typeof u?u:!a&&!s,a=a||l,s=s||c;var h=n.left+n.right,m=n.top+n.bottom,g=t.maxWidth||65535,v=t.maxHeight||65535;return e._layoutRect=r={x:t.x||0,y:t.y||0,w:a,h:s,deltaW:h,deltaH:m,contentW:a-h,contentH:s-m,innerW:a-h,innerH:s-m,startMinWidth:d||0,startMinHeight:f||0,minW:Math.min(l,g),minH:Math.min(c,v),maxW:g,maxH:v,autoResize:u,scrollW:0},e._lastLayoutRect={},r},layoutRect:function(e){var t=this,n=t._layoutRect,r,i,o,a,s,l;return n||(n=t.initLayoutRect()),e?(o=n.deltaW,a=n.deltaH,e.x!==s&&(n.x=e.x),e.y!==s&&(n.y=e.y),e.minW!==s&&(n.minW=e.minW),e.minH!==s&&(n.minH=e.minH),i=e.w,i!==s&&(i=in.maxW?n.maxW:i,n.w=i,n.innerW=i-o),i=e.h,i!==s&&(i=in.maxH?n.maxH:i,n.h=i,n.innerH=i-a),i=e.innerW,i!==s&&(i=in.maxW-o?n.maxW-o:i,n.innerW=i,n.w=i+o),i=e.innerH,i!==s&&(i=in.maxH-a?n.maxH-a:i,n.innerH=i,n.h=i+a),e.contentW!==s&&(n.contentW=e.contentW),e.contentH!==s&&(n.contentH=e.contentH),r=t._lastLayoutRect,(r.x!==n.x||r.y!==n.y||r.w!==n.w||r.h!==n.h)&&(l=u.repaintControls,l&&l.map&&!l.map[t._id]&&(l.push(t),l.map[t._id]=!0),r.x=n.x,r.y=n.y,r.w=n.w,r.h=n.h),t):n},repaint:function(){var e=this,t,n,r,i,o=0,a=0,s,l;l=document.createRange?function(e){return e}:Math.round,t=e.getEl().style,r=e._layoutRect,s=e._lastRepaintRect||{},i=e._borderBox,o=i.left+i.right,a=i.top+i.bottom,r.x!==s.x&&(t.left=l(r.x)+"px",s.x=r.x),r.y!==s.y&&(t.top=l(r.y)+"px",s.y=r.y),r.w!==s.w&&(t.width=l(r.w-o)+"px",s.w=r.w),r.h!==s.h&&(t.height=l(r.h-a)+"px",s.h=r.h),e._hasBody&&r.innerW!==s.innerW&&(n=e.getEl("body").style,n.width=l(r.innerW)+"px",s.innerW=r.innerW),e._hasBody&&r.innerH!==s.innerH&&(n=n||e.getEl("body").style,n.height=l(r.innerH)+"px",s.innerH=r.innerH),e._lastRepaintRect=s,e.fire("repaint",{},!1)},on:function(e,t){function n(e){var t,n;return"string"!=typeof e?e:function(i){return t||r.parentsAndSelf().each(function(r){var i=r.settings.callbacks;return i&&(t=i[e])?(n=r,!1):void 0}),t.call(n,i)}}var r=this;return o(r).on(e,n(t)),r},off:function(e,t){return o(this).off(e,t),this},fire:function(e,t,n){var r=this;if(t=t||{},t.control||(t.control=r),t=o(r).fire(e,t),n!==!1&&r.parent)for(var i=r.parent();i&&!t.isPropagationStopped();)i.fire(e,t,!1),i=i.parent();return t},hasEventListeners:function(e){return o(this).has(e)},parents:function(e){var t=this,n,i=new r;for(n=t.parent();n;n=n.parent())i.add(n);return e&&(i=i.filter(e)),i},parentsAndSelf:function(e){return new r(this).add(this.parents(e))},next:function(){var e=this.parent().items();return e[e.indexOf(this)+1]},prev:function(){var e=this.parent().items();return e[e.indexOf(this)-1]},findCommonAncestor:function(e,t){for(var n;e;){for(n=t;n&&e!=n;)n=n.parent();if(e==n)break;e=e.parent()}return e},hasClass:function(e,t){var n=this._classes[t||"control"];return e=this.classPrefix+e,n&&!!n.map[e]},addClass:function(e,t){var n=this,r,i;return e=this.classPrefix+e,r=n._classes[t||"control"],r||(r=[],r.map={},n._classes[t||"control"]=r),r.map[e]||(r.map[e]=e,r.push(e),n._rendered&&(i=n.getEl(t),i&&(i.className=r.join(" ")))),n},removeClass:function(e,t){var n=this,r,i,o;if(e=this.classPrefix+e,r=n._classes[t||"control"],r&&r.map[e])for(delete r.map[e],i=r.length;i--;)r[i]===e&&r.splice(i,1);return n._rendered&&(o=n.getEl(t),o&&(o.className=r.join(" "))),n},toggleClass:function(e,t,n){var r=this;return t?r.addClass(e,n):r.removeClass(e,n),r},classes:function(e){var t=this._classes[e||"control"];return t?t.join(" "):""},innerHtml:function(e){return i.innerHtml(this.getEl(),e),this},getEl:function(e,t){var n,r=e?this._id+"-"+e:this._id;return n=a[r]=(t===!0?null:a[r])||i.get(r)},visible:function(e){var t=this,n;return"undefined"!=typeof e?(t._visible!==e&&(t._rendered&&(t.getEl().style.display=e?"":"none"),t._visible=e,n=t.parent(),n&&(n._lastRect=null),t.fire(e?"show":"hide")),t):t._visible},show:function(){return this.visible(!0)},hide:function(){return this.visible(!1)},focus:function(){try{this.getEl().focus()}catch(e){}return this},blur:function(){return this.getEl().blur(),this},aria:function(e,t){var n=this,r=n.getEl(n.ariaTarget);return"undefined"==typeof t?n._aria[e]:(n._aria[e]=t,n._rendered&&r.setAttribute("role"==e?e:"aria-"+e,t),n)},encode:function(e,t){return t!==!1&&(e=this.translate(e)),(e||"").replace(/[&<>"]/g,function(e){return"&#"+e.charCodeAt(0)+";"})},translate:function(e){return u.translate?u.translate(e):e},before:function(e){var t=this,n=t.parent();return n&&n.insert(e,n.items().indexOf(t),!0),t},after:function(e){var t=this,n=t.parent();return n&&n.insert(e,n.items().indexOf(t)),t},remove:function(){var e=this,t=e.getEl(),n=e.parent(),r,o;if(e.items){var s=e.items().toArray();for(o=s.length;o--;)s[o].remove()}n&&n.items&&(r=[],n.items().each(function(t){t!==e&&r.push(t)}),n.items().set(r),n._lastRect=null),e._eventsRoot&&e._eventsRoot==e&&i.off(t);var l=e.getRoot().controlIdLookup;if(l&&delete l[e._id],delete a[e._id],t&&t.parentNode){var c=t.getElementsByTagName("*");for(o=c.length;o--;)delete a[c[o].id];t.parentNode.removeChild(t)}return e._rendered=!1,e},renderBefore:function(e){var t=this;return e.parentNode.insertBefore(i.createFragment(t.renderHtml()),e),t.postRender(),t},renderTo:function(e){var t=this;return e=e||t.getContainerElm(),e.appendChild(i.createFragment(t.renderHtml())),t.postRender(),t},postRender:function(){var e=this,t=e.settings,n,r,o,a,s;for(a in t)0===a.indexOf("on")&&e.on(a.substr(2),t[a]);if(e._eventsRoot){for(o=e.parent();!s&&o;o=o.parent())s=o._eventsRoot;if(s)for(a in s._nativeEvents)e._nativeEvents[a]=!0}e.bindPendingEvents(),t.style&&(n=e.getEl(),n&&(n.setAttribute("style",t.style),n.style.cssText=t.style)),e._visible||i.css(e.getEl(),"display","none"),e.settings.border&&(r=e.borderBox(),i.css(e.getEl(),{"border-top-width":r.top,"border-right-width":r.right,"border-bottom-width":r.bottom,"border-left-width":r.left}));var l=e.getRoot();l.controlIdLookup||(l.controlIdLookup={}),l.controlIdLookup[e._id]=e;for(var c in e._aria)e.aria(c,e._aria[c]);e.fire("postrender",{},!1)},scrollIntoView:function(e){function t(e,t){var n,r,i=e;for(n=r=0;i&&i!=t&&i.nodeType;)n+=i.offsetLeft||0,r+=i.offsetTop||0,i=i.offsetParent;return{x:n,y:r}}var n=this.getEl(),r=n.parentNode,i,o,a,s,l,c,u=t(n,r);return i=u.x,o=u.y,a=n.offsetWidth,s=n.offsetHeight,l=r.clientWidth,c=r.clientHeight,"end"==e?(i-=l-a,o-=c-s):"center"==e&&(i-=l/2-a/2,o-=c/2-s/2),r.scrollLeft=i,r.scrollTop=o,this},bindPendingEvents:function(){function e(e){var t=o.getParentCtrl(e.target);t&&t.fire(e.type,e)}function t(){var e=d._lastHoverCtrl;e&&(e.fire("mouseleave",{target:e.getEl()}),e.parents().each(function(e){e.fire("mouseleave",{target:e.getEl()})}),d._lastHoverCtrl=null)}function n(e){var t=o.getParentCtrl(e.target),n=d._lastHoverCtrl,r=0,i,a,s;if(t!==n){if(d._lastHoverCtrl=t,a=t.parents().toArray().reverse(),a.push(t),n){for(s=n.parents().toArray().reverse(),s.push(n),r=0;r=r;i--)n=s[i],n.fire("mouseleave",{target:n.getEl()})}for(i=r;ia;a++)d=u[a]._eventsRoot;for(d||(d=u[u.length-1]||o),o._eventsRoot=d,c=a,a=0;c>a;a++)u[a]._eventsRoot=d;var h=d._delegates;h||(h=d._delegates={});for(p in f){if(!f)return!1;"wheel"!==p||l?("mouseenter"===p||"mouseleave"===p?d._hasMouseEnter||(i.on(d.getEl(),"mouseleave",t),i.on(d.getEl(),"mouseover",n),d._hasMouseEnter=1):h[p]||(i.on(d.getEl(),p,e),h[p]=!0),f[p]=!1):s?i.on(o.getEl(),"mousewheel",r):i.on(o.getEl(),"DOMMouseScroll",r)}}},getRoot:function(){for(var e=this,t,n=[];e;){if(e.rootControl){t=e.rootControl;break}n.push(e),t=e,e=e.parent()}t||(t=this);for(var r=n.length;r--;)n[r].rootControl=t;return t},reflow:function(){return this.repaint(),this}});return u}),r(j,[],function(){var e={},t;return{add:function(t,n){e[t.toLowerCase()]=n},has:function(t){return!!e[t.toLowerCase()]},create:function(n,r){var i,o,a;if(!t){a=tinymce.ui;for(o in a)e[o.toLowerCase()]=a[o];t=!0}if("string"==typeof n?(r=r||{},r.type=n):(r=n,n=r.type),n=n.toLowerCase(),i=e[n],!i)throw new Error("Could not find control by type: "+n);return i=new i(r),i.type=n,i}}}),r(K,[],function(){return function(e){function t(e){return e=e||b,e&&e.getAttribute("role")}function n(e){for(var n,r=e||b;r=r.parentNode;)if(n=t(r))return n}function r(e){var t=b;return t?t.getAttribute("aria-"+e):void 0}function i(e){var t=e.tagName.toUpperCase();return"INPUT"==t||"TEXTAREA"==t}function o(e){return i(e)&&!e.hidden?!0:/^(button|menuitem|checkbox|tab|menuitemcheckbox|option|gridcell)$/.test(t(e))?!0:!1}function a(e){function t(e){if(1==e.nodeType&&"none"!=e.style.display){o(e)&&n.push(e);for(var r=0;re?e=t.length-1:e>=t.length&&(e=0),t[e]&&t[e].focus(),e}function u(e,t){var n=-1,r=s();t=t||a(r.getEl());for(var i=0;i=0&&(n=t.getEl(),n&&n.parentNode.removeChild(n),n=e.getEl(),n&&n.parentNode.removeChild(n)),t.parent(this)},create:function(t){var n=this,i,a=[];return o.isArray(t)||(t=[t]),o.each(t,function(t){t&&(t instanceof e||("string"==typeof t&&(t={type:t}),i=o.extend({},n.settings.defaults,t),t.type=i.type=i.type||t.type||n.settings.defaultType||(i.defaults?i.defaults.type:null),t=r.create(i)),a.push(t))}),a},renderNew:function(){var e=this;return e.items().each(function(t,n){var r,i;t.parent(e),t._rendered||(r=e.getEl("body"),i=a.createFragment(t.renderHtml()),r.hasChildNodes()&&n<=r.childNodes.length-1?r.insertBefore(i,r.childNodes[n]):r.appendChild(i),t.postRender())}),e._layout.applyClasses(e),e._lastRect=null,e},append:function(e){return this.add(e).renderNew()},prepend:function(e){var t=this;return t.items().set(t.create(e).concat(t.items().toArray())),t.renderNew()},insert:function(e,t,n){var r=this,i,o,a;return e=r.create(e),i=r.items(),!n&&t=0&&t
    '+(e.settings.html||"")+t.renderHtml(e)+"
    "},postRender:function(){var e=this,t;return e.items().exec("postRender"),e._super(),e._layout.postRender(e),e._rendered=!0,e.settings.style&&a.css(e.getEl(),e.settings.style),e.settings.border&&(t=e.borderBox(),a.css(e.getEl(),{"border-top-width":t.top,"border-right-width":t.right,"border-bottom-width":t.bottom,"border-left-width":t.left})),e.parent()||(e.keyboardNav=new i({root:e})),e},initLayoutRect:function(){var e=this,t=e._super();return e._layout.recalc(e),t},recalc:function(){var e=this,t=e._layoutRect,n=e._lastRect;return n&&n.w==t.w&&n.h==t.h?void 0:(e._layout.recalc(e),t=e.layoutRect(),e._lastRect={x:t.x,y:t.y,w:t.w,h:t.h},!0)},reflow:function(){var t;if(this.visible()){for(e.repaintControls=[],e.repaintControls.map={},this.recalc(),t=e.repaintControls.length;t--;)e.repaintControls[t].repaint();"flow"!==this.settings.layout&&"stack"!==this.settings.layout&&this.repaint(),e.repaintControls=[]}return this}})}),r(Y,[q],function(e){function t(){var e=document,t,n,r,i,o,a,s,l,c=Math.max;return t=e.documentElement,n=e.body,r=c(t.scrollWidth,n.scrollWidth),i=c(t.clientWidth,n.clientWidth),o=c(t.offsetWidth,n.offsetWidth),a=c(t.scrollHeight,n.scrollHeight),s=c(t.clientHeight,n.clientHeight),l=c(t.offsetHeight,n.offsetHeight),{width:o>r?i:r,height:l>a?s:a}}return function(n,r){function i(){return a.getElementById(r.handle||n)}var o,a=document,s,l,c,u,d,f;r=r||{},l=function(n){var l=t(),p,h;n.preventDefault(),s=n.button,p=i(),d=n.screenX,f=n.screenY,h=window.getComputedStyle?window.getComputedStyle(p,null).getPropertyValue("cursor"):p.runtimeStyle.cursor,o=a.createElement("div"),e.css(o,{position:"absolute",top:0,left:0,width:l.width,height:l.height,zIndex:2147483647,opacity:1e-4,background:"red",cursor:h}),a.body.appendChild(o),e.on(a,"mousemove",u),e.on(a,"mouseup",c),r.start(n)},u=function(e){return e.button!==s?c(e):(e.deltaX=e.screenX-d,e.deltaY=e.screenY-f,e.preventDefault(),void r.drag(e))},c=function(t){e.off(a,"mousemove",u),e.off(a,"mouseup",c),o.parentNode.removeChild(o),r.stop&&r.stop(t)},this.destroy=function(){e.off(i())},e.on(i(),"mousedown",l)}}),r(X,[q,Y],function(e,t){return{init:function(){var e=this;e.on("repaint",e.renderScroll)},renderScroll:function(){function n(){function t(t,a,s,l,c,u){var d,f,p,h,m,g,v,y,b;if(f=i.getEl("scroll"+t)){if(y=a.toLowerCase(),b=s.toLowerCase(),i.getEl("absend")&&e.css(i.getEl("absend"),y,i.layoutRect()[l]-1),!c)return void e.css(f,"display","none");e.css(f,"display","block"),d=i.getEl("body"),p=i.getEl("scroll"+t+"t"),h=d["client"+s]-2*o,h-=n&&r?f["client"+u]:0,m=d["scroll"+s],g=h/m,v={},v[y]=d["offset"+a]+o,v[b]=h,e.css(f,v),v={},v[y]=d["scroll"+a]*g,v[b]=h*g,e.css(p,v)}}var n,r,a;a=i.getEl("body"),n=a.scrollWidth>a.clientWidth,r=a.scrollHeight>a.clientHeight,t("h","Left","Width","contentW",n,"Height"),t("v","Top","Height","contentH",r,"Width")}function r(){function n(n,r,a,s,l){var c,u=i._id+"-scroll"+n,d=i.classPrefix;i.getEl().appendChild(e.createFragment('
    ')),i.draghelper=new t(u+"t",{start:function(){c=i.getEl("body")["scroll"+r],e.addClass(e.get(u),d+"active")},drag:function(e){var t,u,d,f,p=i.layoutRect();u=p.contentW>p.innerW,d=p.contentH>p.innerH,f=i.getEl("body")["client"+a]-2*o,f-=u&&d?i.getEl("scroll"+n)["client"+l]:0,t=f/i.getEl("body")["scroll"+a],i.getEl("body")["scroll"+r]=c+e["delta"+s]/t},stop:function(){e.removeClass(e.get(u),d+"active")}})}i.addClass("scroll"),n("v","Top","Height","Y","Width"),n("h","Left","Width","X","Height")}var i=this,o=2;i.settings.autoScroll&&(i._hasScroll||(i._hasScroll=!0,r(),i.on("wheel",function(e){var t=i.getEl("body");t.scrollLeft+=10*(e.deltaX||0),t.scrollTop+=10*e.deltaY,n()}),e.on(i.getEl("body"),"scroll",n)),n())}}}),r(J,[G,X],function(e,t){return e.extend({Defaults:{layout:"fit",containerCls:"panel"},Mixins:[t],renderHtml:function(){var e=this,t=e._layout,n=e.settings.html;return e.preRender(),t.preRender(e),"undefined"==typeof n?n='
    '+t.renderHtml(e)+"
    ":("function"==typeof n&&(n=n.call(e)),e._hasBody=!1),'
    '+(e._preBodyHtml||"")+n+"
    "}})}),r(Q,[q],function(e){function t(t,n,r){var i,o,a,s,l,c,u,d,f,p;return f=e.getViewPort(),o=e.getPos(n),a=o.x,s=o.y,t._fixed&&(a-=f.x,s-=f.y),i=t.getEl(),p=e.getSize(i),l=p.width,c=p.height,p=e.getSize(n),u=p.width,d=p.height,r=(r||"").split(""),"b"===r[0]&&(s+=d),"r"===r[1]&&(a+=u),"c"===r[0]&&(s+=Math.round(d/2)),"c"===r[1]&&(a+=Math.round(u/2)),"b"===r[3]&&(s-=c),"r"===r[4]&&(a-=l),"c"===r[3]&&(s-=Math.round(c/2)),"c"===r[4]&&(a-=Math.round(l/2)),{x:a,y:s,w:l,h:c}}return{testMoveRel:function(n,r){for(var i=e.getViewPort(),o=0;o0&&a.x+a.w0&&a.y+a.hi.x&&a.x+a.wi.y&&a.y+a.he?0:e+n>t?(e=t-n,0>e?0:e):e}var i=this;if(i.settings.constrainToViewport){var o=e.getViewPort(window),a=i.layoutRect();t=r(t,o.w+o.x,a.w),n=r(n,o.h+o.y,a.h)}return i._rendered?i.layoutRect({x:t,y:n}).repaint():(i.settings.x=t,i.settings.y=n),i.fire("move",{x:t,y:n}),i}}}),r(Z,[q],function(e){return{resizeToContent:function(){this._layoutRect.autoResize=!0,this._lastRect=null,this.reflow()},resizeTo:function(t,n){if(1>=t||1>=n){var r=e.getWindowSize();t=1>=t?t*r.w:t,n=1>=n?n*r.h:n}return this._layoutRect.autoResize=!1,this.layoutRect({minW:t,minH:n,w:t,h:n}).reflow()},resizeBy:function(e,t){var n=this,r=n.layoutRect();return n.resizeTo(r.w+e,r.h+t)}}}),r(et,[J,Q,Z,q],function(e,t,n,r){function i(e){var t;for(t=s.length;t--;)s[t]===e&&s.splice(t,1);for(t=l.length;t--;)l[t]===e&&l.splice(t,1)}var o,a,s=[],l=[],c,u=e.extend({Mixins:[t,n],init:function(e){function t(){var e,t=u.zIndex||65535,n;if(l.length)for(e=0;en&&(e.fixed(!1).layoutRect({y:e._autoFixY}).repaint(),t(!1,e._autoFixY-n)):(e._autoFixY=e.layoutRect().y,e._autoFixY'),n=n.firstChild,d.getContainerElm().appendChild(n),setTimeout(function(){r.addClass(n,i+"in"),r.addClass(d.getEl(),i+"in")},0),c=!0),l.push(d),t()}}),d.on("close hide",function(e){if(e.control==d){for(var n=l.length;n--;)l[n]===d&&l.splice(n,1);t()}}),d.on("show",function(){d.parents().each(function(e){return e._fixed?(d.fixed(!0),!1):void 0})}),e.popover&&(d._preBodyHtml='
    ',d.addClass("popover").addClass("bottom").addClass(d.isRtl()?"end":"start"))},fixed:function(e){var t=this;if(t._fixed!=e){if(t._rendered){var n=r.getViewPort();e?t.layoutRect().y-=n.y:t.layoutRect().y+=n.y}t.toggleClass("fixed",e),t._fixed=e}return t},show:function(){var e=this,t,n=e._super();for(t=s.length;t--&&s[t]!==e;);return-1===t&&s.push(e),n},hide:function(){return i(this),this._super()},hideAll:function(){u.hideAll()},close:function(){var e=this;return e.fire("close"),e.remove()},remove:function(){i(this),this._super()},postRender:function(){var e=this;return e.settings.bodyRole&&this.getEl("body").setAttribute("role",e.settings.bodyRole),e._super()}});return u.hideAll=function(){for(var e=s.length;e--;){var t=s[e];t&&t.settings.autohide&&(t.hide(),s.splice(e,1))}},u}),r(tt,[et,J,q,Y],function(e,t,n,r){var i=e.extend({modal:!0,Defaults:{border:1,layout:"flex",containerCls:"panel",role:"dialog",callbacks:{submit:function(){this.fire("submit",{data:this.toJSON()})},close:function(){this.close()}}},init:function(e){var n=this;n._super(e),n.isRtl()&&n.addClass("rtl"),n.addClass("window"),n._fixed=!0,e.buttons&&(n.statusbar=new t({layout:"flex",border:"1 0 0 0",spacing:3,padding:10,align:"center",pack:n.isRtl()?"start":"end",defaults:{type:"button"},items:e.buttons}),n.statusbar.addClass("foot"),n.statusbar.parent(n)),n.on("click",function(e){-1!=e.target.className.indexOf(n.classPrefix+"close")&&n.close()}),n.on("cancel",function(){n.close()}),n.aria("describedby",n.describedBy||n._id+"-none"),n.aria("label",e.title),n._fullscreen=!1},recalc:function(){var e=this,t=e.statusbar,r,i,o,a;e._fullscreen&&(e.layoutRect(n.getWindowSize()),e.layoutRect().contentH=e.layoutRect().innerH),e._super(),r=e.layoutRect(),e.settings.title&&!e._fullscreen&&(i=r.headerW,i>r.w&&(o=r.x-Math.max(0,i/2),e.layoutRect({w:i,x:o}),a=!0)),t&&(t.layoutRect({w:e.layoutRect().innerW}).recalc(),i=t.layoutRect().minW+r.deltaW,i>r.w&&(o=r.x-Math.max(0,i-r.w),e.layoutRect({w:i,x:o}),a=!0)),a&&e.recalc()},initLayoutRect:function(){var e=this,t=e._super(),r=0,i;if(e.settings.title&&!e._fullscreen){i=e.getEl("head");var o=n.getSize(i);t.headerW=o.width,t.headerH=o.height,r+=t.headerH}e.statusbar&&(r+=e.statusbar.layoutRect().h),t.deltaH+=r,t.minH+=r,t.h+=r;var a=n.getWindowSize();return t.x=Math.max(0,a.w/2-t.w/2),t.y=Math.max(0,a.h/2-t.h/2),t},renderHtml:function(){var e=this,t=e._layout,n=e._id,r=e.classPrefix,i=e.settings,o="",a="",s=i.html;return e.preRender(),t.preRender(e),i.title&&(o='
    '+e.encode(i.title)+'
    '),i.url&&(s=''),"undefined"==typeof s&&(s=t.renderHtml(e)),e.statusbar&&(a=e.statusbar.renderHtml()),'
    '+o+'
    '+s+"
    "+a+"
    "},fullscreen:function(e){var t=this,r=document.documentElement,i,o=t.classPrefix,a;if(e!=t._fullscreen)if(n.on(window,"resize",function(){var e;if(t._fullscreen)if(i)t._timer||(t._timer=setTimeout(function(){var e=n.getWindowSize();t.moveTo(0,0).resizeTo(e.w,e.h),t._timer=0},50));else{e=(new Date).getTime();var r=n.getWindowSize();t.moveTo(0,0).resizeTo(r.w,r.h),(new Date).getTime()-e>50&&(i=!0)}}),a=t.layoutRect(),t._fullscreen=e,e){t._initial={x:a.x,y:a.y,w:a.w,h:a.h},t._borderBox=t.parseBox("0"),t.getEl("head").style.display="none",a.deltaH-=a.headerH+2,n.addClass(r,o+"fullscreen"),n.addClass(document.body,o+"fullscreen"),t.addClass("fullscreen");var s=n.getWindowSize();t.moveTo(0,0).resizeTo(s.w,s.h)}else t._borderBox=t.parseBox(t.settings.border),t.getEl("head").style.display="",a.deltaH+=a.headerH,n.removeClass(r,o+"fullscreen"),n.removeClass(document.body,o+"fullscreen"),t.removeClass("fullscreen"),t.moveTo(t._initial.x,t._initial.y).resizeTo(t._initial.w,t._initial.h);return t.reflow()},postRender:function(){var e=this,t;setTimeout(function(){e.addClass("in")},0),e._super(),e.statusbar&&e.statusbar.postRender(),e.focus(),this.dragHelper=new r(e._id+"-dragh",{start:function(){t={x:e.layoutRect().x,y:e.layoutRect().y}},drag:function(n){e.moveTo(t.x+n.deltaX,t.y+n.deltaY)}}),e.on("submit",function(t){t.isDefaultPrevented()||e.close()})},submit:function(){return this.fire("submit",{data:this.toJSON()})},remove:function(){var e=this,t=e.classPrefix;e.dragHelper.destroy(),e._super(),e.statusbar&&this.statusbar.remove(),e._fullscreen&&(n.removeClass(document.documentElement,t+"fullscreen"),n.removeClass(document.body,t+"fullscreen"))},getContentWindow:function(){var e=this.getEl().getElementsByTagName("iframe")[0];return e?e.contentWindow:null}});return i}),r(nt,[tt],function(e){var t=e.extend({init:function(e){e={border:1,padding:20,layout:"flex",pack:"center",align:"center",containerCls:"panel",autoScroll:!0,buttons:{type:"button",text:"Ok",action:"ok"},items:{type:"label",multiline:!0,maxWidth:500,maxHeight:200}},this._super(e)},Statics:{OK:1,OK_CANCEL:2,YES_NO:3,YES_NO_CANCEL:4,msgBox:function(n){var r,i=n.callback||function(){};switch(n.buttons){case t.OK_CANCEL:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close(),i(!0)}},{type:"button",text:"Cancel",onClick:function(e){e.control.parents()[1].close(),i(!1)}}];break;case t.YES_NO:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close(),i(!0)}}];break;case t.YES_NO_CANCEL:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close()}}];break;default:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close(),i(!0)}}]}return new e({padding:20,x:n.x,y:n.y,minWidth:300,minHeight:100,layout:"flex",pack:"center",align:"center",buttons:r,title:n.title,role:"alertdialog",items:{type:"label",multiline:!0,maxWidth:500,maxHeight:200,text:n.text},onPostRender:function(){this.aria("describedby",this.items()[0]._id)},onClose:n.onClose,onCancel:function(){i(!1)}}).renderTo(document.body).reflow()},alert:function(e,n){return"string"==typeof e&&(e={text:e}),e.callback=n,t.msgBox(e)},confirm:function(e,n){return"string"==typeof e&&(e={text:e}),e.callback=n,e.buttons=t.OK_CANCEL,t.msgBox(e)}}});return t}),r(rt,[tt,nt],function(e,t){return function(n){function r(){return o.length?o[o.length-1]:void 0}var i=this,o=[];i.windows=o,i.open=function(t,r){var i;return n.editorManager.activeEditor=n,t.title=t.title||" ",t.url=t.url||t.file,t.url&&(t.width=parseInt(t.width||320,10),t.height=parseInt(t.height||240,10)),t.body&&(t.items={defaults:t.defaults,type:t.bodyType||"form",items:t.body}),t.url||t.buttons||(t.buttons=[{text:"Ok",subtype:"primary",onclick:function(){i.find("form")[0].submit()}},{text:"Cancel",onclick:function(){i.close()}}]),i=new e(t),o.push(i),i.on("close",function(){for(var e=o.length;e--;)o[e]===i&&o.splice(e,1);n.focus()}),t.data&&i.on("postRender",function(){this.find("*").each(function(e){var n=e.name();n in t.data&&e.value(t.data[n])})}),i.features=t||{},i.params=r||{},n.nodeChanged(),i.renderTo().reflow()},i.alert=function(e,r,i){t.alert(e,function(){r?r.call(i||this):n.focus()})},i.confirm=function(e,n,r){t.confirm(e,function(e){n.call(r||this,e)})},i.close=function(){r()&&r().close()},i.getParams=function(){return r()?r().params:null},i.setParams=function(e){r()&&(r().params=e)},i.getWindows=function(){return o}}}),r(it,[R,B,x,m,g,p],function(e,t,n,r,i,o){return function(a){function s(e,t){try{a.getDoc().execCommand(e,!1,t)}catch(n){}}function l(){var e=a.getDoc().documentMode;return e?e:6}function c(e){return e.isDefaultPrevented()}function u(){function t(e){var t=new i(function(){});o.each(a.getBody().getElementsByTagName("*"),function(e){"SPAN"==e.tagName&&e.setAttribute("mce-data-marked",1),!e.hasAttribute("data-mce-style")&&e.hasAttribute("style")&&a.dom.setAttrib(e,"style",e.getAttribute("style"))}),t.observe(a.getDoc(),{childList:!0,attributes:!0,subtree:!0,attributeFilter:["style"]}),a.getDoc().execCommand(e?"ForwardDelete":"Delete",!1,null);var n=a.selection.getRng(),r=n.startContainer.parentNode;o.each(t.takeRecords(),function(e){if(q.isChildOf(e.target,a.getBody())){if("style"==e.attributeName){var t=e.target.getAttribute("data-mce-style");t?e.target.setAttribute("style",t):e.target.removeAttribute("style")}o.each(e.addedNodes,function(e){if("SPAN"==e.nodeName&&!e.getAttribute("mce-data-marked")){var t,i;e==r&&(t=n.startOffset,i=e.firstChild),q.remove(e,!0),i&&(n.setStart(i,t),n.setEnd(i,t),a.selection.setRng(n))}})}}),t.disconnect(),o.each(a.dom.select("span[mce-data-marked]"),function(e){e.removeAttribute("mce-data-marked")})}var n=a.getDoc(),r="data:text/mce-internal,",i=window.MutationObserver,s,l;i||(s=!0,i=function(){function e(e){var t=e.relatedNode||e.target;n.push({target:t,addedNodes:[t]})}function t(e){var t=e.relatedNode||e.target;n.push({target:t,attributeName:e.attrName})}var n=[],r;this.observe=function(n){r=n,r.addEventListener("DOMSubtreeModified",e,!1),r.addEventListener("DOMNodeInsertedIntoDocument",e,!1),r.addEventListener("DOMNodeInserted",e,!1),r.addEventListener("DOMAttrModified",t,!1)},this.disconnect=function(){r.removeEventListener("DOMSubtreeModified",e,!1),r.removeEventListener("DOMNodeInsertedIntoDocument",e,!1),r.removeEventListener("DOMNodeInserted",e,!1),r.removeEventListener("DOMAttrModified",t,!1)},this.takeRecords=function(){return n}}),a.on("keydown",function(n){var r=n.keyCode==U,i=e.metaKeyPressed(n);if(!c(n)&&(r||n.keyCode==V)){var o=a.selection.getRng(),s=o.startContainer,l=o.startOffset;if(!i&&o.collapsed&&3==s.nodeType&&(r?l0))return;n.preventDefault(),i&&a.selection.getSel().modify("extend",r?"forward":"backward","word"),t(r)}}),a.on("keypress",function(n){c(n)||$.isCollapsed()||!n.charCode||e.metaKeyPressed(n)||(n.preventDefault(),t(!0),a.selection.setContent(String.fromCharCode(n.charCode)))}),a.addCommand("Delete",function(){t()}),a.addCommand("ForwardDelete",function(){t(!0)}),s||(a.on("dragstart",function(e){var t;a.selection.isCollapsed()&&"IMG"==e.target.tagName&&$.select(e.target),l=$.getRng(),t=a.selection.getContent(),t.length>0&&e.dataTransfer.setData("URL","data:text/mce-internal,"+escape(t))}),a.on("drop",function(e){if(!c(e)){var i=e.dataTransfer.getData("URL");if(!i||-1==i.indexOf(r)||!n.caretRangeFromPoint)return;i=unescape(i.substr(r.length)),n.caretRangeFromPoint&&(e.preventDefault(),window.setTimeout(function(){var r=n.caretRangeFromPoint(e.x,e.y);l&&($.setRng(l),l=null),t(),$.setRng(r),a.insertContent(i)},0))}}),a.on("cut",function(e){!c(e)&&e.clipboardData&&(e.preventDefault(),e.clipboardData.clearData(),e.clipboardData.setData("text/html",a.selection.getContent()),e.clipboardData.setData("text/plain",a.selection.getContent({format:"text"})),t(!0))}))}function d(){function e(e){var t=q.create("body"),n=e.cloneContents();return t.appendChild(n),$.serializer.serialize(t,{format:"html"})}function n(n){if(!n.setStart){if(n.item)return!1;var r=n.duplicate();return r.moveToElementText(a.getBody()),t.compareRanges(n,r)}var i=e(n),o=q.createRng();o.selectNode(a.getBody());var s=e(o);return i===s}a.on("keydown",function(e){var t=e.keyCode,r,i;if(!c(e)&&(t==U||t==V)){if(r=a.selection.isCollapsed(),i=a.getBody(),r&&!q.isEmpty(i))return;if(!r&&!n(a.selection.getRng()))return;e.preventDefault(),a.setContent(""),i.firstChild&&q.isBlock(i.firstChild)?a.selection.setCursorLocation(i.firstChild,0):a.selection.setCursorLocation(i,0),a.nodeChanged()}})}function f(){a.on("keydown",function(t){!c(t)&&65==t.keyCode&&e.metaKeyPressed(t)&&(t.preventDefault(),a.execCommand("SelectAll"))})}function p(){a.settings.content_editable||(q.bind(a.getDoc(),"focusin",function(){$.setRng($.getRng())}),q.bind(a.getDoc(),"mousedown",function(e){e.target==a.getDoc().documentElement&&(a.getBody().focus(),$.setRng($.getRng()))}))}function h(){a.on("keydown",function(e){if(!c(e)&&e.keyCode===V&&$.isCollapsed()&&0===$.getRng(!0).startOffset){var t=$.getNode(),n=t.previousSibling;if("HR"==t.nodeName)return q.remove(t),void e.preventDefault();n&&n.nodeName&&"hr"===n.nodeName.toLowerCase()&&(q.remove(n),e.preventDefault())}})}function m(){window.Range.prototype.getClientRects||a.on("mousedown",function(e){if(!c(e)&&"HTML"===e.target.nodeName){var t=a.getBody();t.blur(),setTimeout(function(){t.focus()},0)}})}function g(){a.on("click",function(e){e=e.target,/^(IMG|HR)$/.test(e.nodeName)&&$.getSel().setBaseAndExtent(e,0,e,1),"A"==e.nodeName&&q.hasClass(e,"mce-item-anchor")&&$.select(e),a.nodeChanged()})}function v(){function e(){var e=q.getAttribs($.getStart().cloneNode(!1));return function(){var t=$.getStart();t!==a.getBody()&&(q.setAttrib(t,"style",null),W(e,function(e){t.setAttributeNode(e.cloneNode(!0))}))}}function t(){return!$.isCollapsed()&&q.getParent($.getStart(),q.isBlock)!=q.getParent($.getEnd(),q.isBlock)}a.on("keypress",function(n){var r;return c(n)||8!=n.keyCode&&46!=n.keyCode||!t()?void 0:(r=e(),a.getDoc().execCommand("delete",!1,null),r(),n.preventDefault(),!1)}),q.bind(a.getDoc(),"cut",function(n){var r;!c(n)&&t()&&(r=e(),setTimeout(function(){r()},0))})}function y(){var e,n;a.on("selectionchange",function(){n&&(clearTimeout(n),n=0),n=window.setTimeout(function(){if(!a.removed){var n=$.getRng();e&&t.compareRanges(n,e)||(a.nodeChanged(),e=n)}},50)})}function b(){document.body.setAttribute("role","application")}function C(){a.on("keydown",function(e){if(!c(e)&&e.keyCode===V&&$.isCollapsed()&&0===$.getRng(!0).startOffset){var t=$.getNode().previousSibling;if(t&&t.nodeName&&"table"===t.nodeName.toLowerCase())return e.preventDefault(),!1}})}function x(){l()>7||(s("RespectVisibilityInDesign",!0),a.contentStyles.push(".mceHideBrInPre pre br {display: none}"),q.addClass(a.getBody(),"mceHideBrInPre"),K.addNodeFilter("pre",function(e){for(var t=e.length,r,i,o,a;t--;)for(r=e[t].getAll("br"),i=r.length;i--;)o=r[i],a=o.prev,a&&3===a.type&&"\n"!=a.value.charAt(a.value-1)?a.value+="\n":o.parent.insert(new n("#text",3),o,!0).value="\n"}),G.addNodeFilter("pre",function(e){for(var t=e.length,n,r,i,o;t--;)for(n=e[t].getAll("br"),r=n.length;r--;)i=n[r],o=i.prev,o&&3==o.type&&(o.value=o.value.replace(/\r?\n$/,""))}))}function w(){q.bind(a.getBody(),"mouseup",function(){var e,t=$.getNode();"IMG"==t.nodeName&&((e=q.getStyle(t,"width"))&&(q.setAttrib(t,"width",e.replace(/[^0-9%]+/g,"")),q.setStyle(t,"width","")),(e=q.getStyle(t,"height"))&&(q.setAttrib(t,"height",e.replace(/[^0-9%]+/g,"")),q.setStyle(t,"height","")))})}function _(){a.on("keydown",function(t){var n,r,i,o,s;if(!c(t)&&t.keyCode==e.BACKSPACE&&(n=$.getRng(),r=n.startContainer,i=n.startOffset,o=q.getRoot(),s=r,n.collapsed&&0===i)){for(;s&&s.parentNode&&s.parentNode.firstChild==s&&s.parentNode!=o;)s=s.parentNode;"BLOCKQUOTE"===s.tagName&&(a.formatter.toggle("blockquote",null,s),n=q.createRng(),n.setStart(r,0),n.setEnd(r,0),$.setRng(n))}})}function N(){function e(){a._refreshContentEditable(),s("StyleWithCSS",!1),s("enableInlineTableEditing",!1),j.object_resizing||s("enableObjectResizing",!1)}j.readonly||a.on("BeforeExecCommand MouseDown",e)}function E(){function e(){W(q.select("a"),function(e){var t=e.parentNode,n=q.getRoot();if(t.lastChild===e){for(;t&&!q.isBlock(t);){if(t.parentNode.lastChild!==t||t===n)return;t=t.parentNode}q.add(t,"br",{"data-mce-bogus":1})}})}a.on("SetContent ExecCommand",function(t){("setcontent"==t.type||"mceInsertLink"===t.command)&&e()})}function S(){j.forced_root_block&&a.on("init",function(){s("DefaultParagraphSeparator",j.forced_root_block)})}function k(){a.on("Undo Redo SetContent",function(e){e.initial||a.execCommand("mceRepaint")})}function T(){a.on("keydown",function(e){var t;c(e)||e.keyCode!=V||(t=a.getDoc().selection.createRange(),t&&t.item&&(e.preventDefault(),a.undoManager.beforeChange(),q.remove(t.item(0)),a.undoManager.add()))})}function R(){var e;l()>=10&&(e="",W("p div h1 h2 h3 h4 h5 h6".split(" "),function(t,n){e+=(n>0?",":"")+t+":empty"}),a.contentStyles.push(e+"{padding-right: 1px !important}"))}function A(){l()<9&&(K.addNodeFilter("noscript",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.firstChild,r&&n.attr("data-mce-innertext",r.value)}),G.addNodeFilter("noscript",function(e){for(var t=e.length,i,o,a;t--;)i=e[t],o=e[t].firstChild,o?o.value=r.decode(o.value):(a=i.attributes.map["data-mce-innertext"],a&&(i.attr("data-mce-innertext",null),o=new n("#text",3),o.value=a,o.raw=!0,i.append(o)))}))}function B(){function e(e,t){var n=i.createTextRange();try{n.moveToPoint(e,t)}catch(r){n=null}return n}function t(t){var r;t.button?(r=e(t.x,t.y),r&&(r.compareEndPoints("StartToStart",a)>0?r.setEndPoint("StartToStart",a):r.setEndPoint("EndToEnd",a),r.select())):n()}function n(){var e=r.selection.createRange();a&&!e.item&&0===e.compareEndPoints("StartToEnd",e)&&a.select(),q.unbind(r,"mouseup",n),q.unbind(r,"mousemove",t),a=o=0}var r=q.doc,i=r.body,o,a,s;r.documentElement.unselectable=!0,q.bind(r,"mousedown contextmenu",function(i){if("HTML"===i.target.nodeName){if(o&&n(),s=r.documentElement,s.scrollHeight>s.clientHeight)return;o=1,a=e(i.x,i.y),a&&(q.bind(r,"mouseup",n),q.bind(r,"mousemove",t),q.getRoot().focus(),a.select())}})}function D(){a.on("keyup focusin mouseup",function(t){65==t.keyCode&&e.metaKeyPressed(t)||$.normalize()},!0)}function L(){a.contentStyles.push("img:-moz-broken {-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}")}function M(){a.inline||a.on("keydown",function(){document.activeElement==document.body&&a.getWin().focus()})}function H(){a.inline||(a.contentStyles.push("body {min-height: 150px}"),a.on("click",function(e){"HTML"==e.target.nodeName&&(a.getBody().focus(),a.selection.normalize(),a.nodeChanged())}))}function P(){i.mac&&a.on("keydown",function(t){!e.metaKeyPressed(t)||37!=t.keyCode&&39!=t.keyCode||(t.preventDefault(),a.selection.getSel().modify("move",37==t.keyCode?"backward":"forward","word"))})}function O(){s("AutoUrlDetect",!1)}function I(){a.inline||a.on("focus blur beforegetcontent",function(){var e=a.dom.create("br");a.getBody().appendChild(e),e.parentNode.removeChild(e)},!0)}function F(){a.on("click",function(e){var t=e.target;do if("A"===t.tagName)return void e.preventDefault();while(t=t.parentNode)}),a.contentStyles.push(".mce-content-body {-webkit-touch-callout: none}")}function z(){a.on("init",function(){a.dom.bind(a.getBody(),"submit",function(e){e.preventDefault()})})}var W=o.each,V=e.BACKSPACE,U=e.DELETE,q=a.dom,$=a.selection,j=a.settings,K=a.parser,G=a.serializer,Y=i.gecko,X=i.ie,J=i.webkit;C(),_(),d(),D(),J&&(u(),p(),g(),S(),z(),i.iOS?(y(),M(),H(),F()):f()),X&&i.ie<11&&(h(),b(),x(),w(),T(),R(),A(),B()),i.ie>=11&&(H(),I()),i.ie&&(f(),O()),Y&&(h(),m(),v(),N(),E(),k(),L(),P())}}),r(ot,[W],function(e){function t(t){return t._eventDispatcher||(t._eventDispatcher=new e({scope:t,toggleEvent:function(n,r){e.isNative(n)&&t.toggleNativeEvent&&t.toggleNativeEvent(n,r)}})),t._eventDispatcher}return{fire:function(e,n,r){var i=this;if(i.removed&&"remove"!==e)return n;if(n=t(i).fire(e,n,r),r!==!1&&i.parent)for(var o=i.parent();o&&!n.isPropagationStopped();)o.fire(e,n,!1),o=o.parent();return n},on:function(e,n,r){return t(this).on(e,n,r)},off:function(e,n){return t(this).off(e,n)},hasEventListeners:function(e){return t(this).has(e)}}}),r(at,[ot,y,p],function(e,t,n){function r(e,t){return"selectionchange"==t?e.getDoc():!e.inline&&/^mouse|click|contextmenu|drop/.test(t)?e.getDoc():e.getBody()}function i(e,t){var n=e.settings.event_root,i=e.editorManager,a=i.eventRootElm||r(e,t);if(n){if(i.rootEvents||(i.rootEvents={},i.on("RemoveEditor",function(){i.activeEditor||(o.unbind(a),delete i.rootEvents)})),i.rootEvents[t])return;a==e.getBody()&&(a=o.select(n)[0],i.eventRootElm=a),i.rootEvents[t]=!0,o.bind(a,t,function(e){for(var n=e.target,r=i.editors,a=r.length;a--;){var s=r[a].getBody();(s===n||o.isChildOf(n,s))&&(r[a].hidden||r[a].fire(t,e))}})}else e.dom.bind(a,t,function(n){e.hidden||e.fire(t,n)})}var o=t.DOM,a={bindPendingEventDelegates:function(){var e=this;n.each(e._pendingNativeEvents,function(t){i(e,t)})},toggleNativeEvent:function(e,t){var n=this;n.settings.readonly||"focus"!=e&&"blur"!=e&&(t?n.initialized?i(n,e):n._pendingNativeEvents?n._pendingNativeEvents.push(e):n._pendingNativeEvents=[e]:n.initialized&&n.dom.unbind(r(n,e),e))}};return a=n.extend({},e,a)}),r(st,[p,g],function(e,t){var n=e.each,r=e.explode,i={f9:120,f10:121,f11:122};return function(o){var a=this,s={};o.on("keyup keypress keydown",function(e){(e.altKey||e.ctrlKey||e.metaKey)&&n(s,function(n){var r=t.mac?e.metaKey:e.ctrlKey;if(n.ctrl==r&&n.alt==e.altKey&&n.shift==e.shiftKey)return e.keyCode==n.keyCode||e.charCode&&e.charCode==n.charCode?(e.preventDefault(),"keydown"==e.type&&n.func.call(n.scope),!0):void 0})}),a.add=function(t,a,l,c){var u;return u=l,"string"==typeof l?l=function(){o.execCommand(u,!1,null)}:e.isArray(u)&&(l=function(){o.execCommand(u[0],u[1],u[2])}),n(r(t.toLowerCase()),function(e){var t={func:l,scope:c||o,desc:o.translate(a),alt:!1,ctrl:!1,shift:!1};n(r(e,"+"),function(e){switch(e){case"alt":case"ctrl":case"shift":t[e]=!0;break;default:t.charCode=e.charCodeAt(0),t.keyCode=i[e]||e.toUpperCase().charCodeAt(0)}}),s[(t.ctrl?"ctrl":"")+","+(t.alt?"alt":"")+","+(t.shift?"shift":"")+","+t.keyCode]=t}),!0}}}),r(lt,[y,C,x,k,S,D,M,H,P,O,I,F,b,l,rt,w,N,it,g,p,at,st],function(e,n,r,i,o,a,s,l,c,u,d,f,p,h,m,g,v,y,b,C,x,w){function _(e,t,r){var i=this,o,a;o=i.documentBaseUrl=r.documentBaseURL,a=r.baseURI,i.settings=t=k({id:e,theme:"modern",delta_width:0,delta_height:0,popup_css:"",plugins:"",document_base_url:o,add_form_submit_trigger:!0,submit_patch:!0,add_unload_trigger:!0,convert_urls:!0,relative_urls:!0,remove_script_host:!0,object_resizing:!0,doctype:"",visual:!0,font_size_style_values:"xx-small,x-small,small,medium,large,x-large,xx-large",font_size_legacy_values:"xx-small,small,medium,large,x-large,xx-large,300%",forced_root_block:"p",hidden_input:!0,padd_empty_editor:!0,render_ui:!0,indentation:"30px",inline_styles:!0,convert_fonts_to_spans:!0,indent:"simple",indent_before:"p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,option,optgroup,datalist",indent_after:"p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,option,optgroup,datalist",validate:!0,entity_encoding:"named",url_converter:i.convertURL,url_converter_scope:i,ie7_compat:!0},t),n.language=t.language||"en",n.languageLoad=t.language_load,n.baseURL=r.baseURL,i.id=t.id=e,i.isNotDirty=!0,i.plugins={},i.documentBaseURI=new f(t.document_base_url||o,{base_uri:a}),i.baseURI=a,i.contentCSS=[],i.contentStyles=[],i.shortcuts=new w(i),i.execCommands={},i.queryStateCommands={},i.queryValueCommands={},i.loadedCSS={},i.suffix=r.suffix,i.editorManager=r,i.inline=t.inline,r.fire("SetupEditor",i),i.execCallback("setup",i)}var N=e.DOM,E=n.ThemeManager,S=n.PluginManager,k=C.extend,T=C.each,R=C.explode,A=C.inArray,B=C.trim,D=C.resolve,L=h.Event,M=b.gecko,H=b.ie;return _.prototype={render:function(){function e(){N.unbind(window,"ready",e),n.render()}function t(){var e=p.ScriptLoader;if(r.language&&"en"!=r.language&&!r.language_url&&(r.language_url=n.editorManager.baseURL+"/langs/"+r.language+".js"),r.language_url&&e.add(r.language_url),r.theme&&"function"!=typeof r.theme&&"-"!=r.theme.charAt(0)&&!E.urls[r.theme]){var t=r.theme_url;t=t?n.documentBaseURI.toAbsolute(t):"themes/"+r.theme+"/theme"+o+".js",E.load(r.theme,t)}C.isArray(r.plugins)&&(r.plugins=r.plugins.join(" ")),T(r.external_plugins,function(e,t){S.load(t,e),r.plugins+=" "+t}),T(r.plugins.split(/[ ,]/),function(e){if(e=B(e),e&&!S.urls[e])if("-"==e.charAt(0)){e=e.substr(1,e.length);var t=S.dependencies(e);T(t,function(e){var t={prefix:"plugins/",resource:e,suffix:"/plugin"+o+".js"};e=S.createUrl(t,e),S.load(e.resource,e)})}else S.load(e,{prefix:"plugins/",resource:e,suffix:"/plugin"+o+".js"})}),e.loadQueue(function(){n.removed||n.init()})}var n=this,r=n.settings,i=n.id,o=n.suffix;if(!L.domLoaded)return void N.bind(window,"ready",e);if(n.getElement()&&b.contentEditable){r.inline?n.inline=!0:(n.orgVisibility=n.getElement().style.visibility,n.getElement().style.visibility="hidden");var a=n.getElement().form||N.getParent(i,"form");a&&(n.formElement=a,r.hidden_input&&!/TEXTAREA|INPUT/i.test(n.getElement().nodeName)&&(N.insertAfter(N.create("input",{type:"hidden",name:i}),i),n.hasHiddenInput=!0),n.formEventDelegate=function(e){n.fire(e.type,e)},N.bind(a,"submit reset",n.formEventDelegate),n.on("reset",function(){n.setContent(n.startContent,{format:"raw"})}),!r.submit_patch||a.submit.nodeType||a.submit.length||a._mceOldSubmit||(a._mceOldSubmit=a.submit,a.submit=function(){return n.editorManager.triggerSave(),n.isNotDirty=!0,a._mceOldSubmit(a)})),n.windowManager=new m(n),"xml"==r.encoding&&n.on("GetContent",function(e){e.save&&(e.content=N.encode(e.content))}),r.add_form_submit_trigger&&n.on("submit",function(){n.initialized&&n.save()}),r.add_unload_trigger&&(n._beforeUnload=function(){!n.initialized||n.destroyed||n.isHidden()||n.save({format:"raw",no_events:!0,set_dirty:!1})},n.editorManager.on("BeforeUnload",n._beforeUnload)),t()}},init:function(){function e(n){var r=S.get(n),i,o;i=S.urls[n]||t.documentBaseUrl.replace(/\/$/,""),n=B(n),r&&-1===A(m,n)&&(T(S.dependencies(n),function(t){e(t)}),o=new r(t,i),t.plugins[n]=o,o.init&&(o.init(t,i),m.push(n)))}var t=this,n=t.settings,r=t.getElement(),i,o,a,s,l,c,u,d,f,p,h,m=[];if(t.rtl=this.editorManager.i18n.rtl,t.editorManager.add(t),n.aria_label=n.aria_label||N.getAttrib(r,"aria-label",t.getLang("aria.rich_text_area")),n.theme&&("function"!=typeof n.theme?(n.theme=n.theme.replace(/-/,""),c=E.get(n.theme),t.theme=new c(t,E.urls[n.theme]),t.theme.init&&t.theme.init(t,E.urls[n.theme]||t.documentBaseUrl.replace(/\/$/,""))):t.theme=n.theme),T(n.plugins.replace(/\-/g,"").split(/[ ,]/),e),n.render_ui&&t.theme&&(t.orgDisplay=r.style.display,"function"!=typeof n.theme?(i=n.width||r.style.width||r.offsetWidth,o=n.height||r.style.height||r.offsetHeight,a=n.min_height||100,p=/^[0-9\.]+(|px)$/i,p.test(""+i)&&(i=Math.max(parseInt(i,10),100)),p.test(""+o)&&(o=Math.max(parseInt(o,10),a)),l=t.theme.renderUI({targetNode:r,width:i,height:o,deltaWidth:n.delta_width,deltaHeight:n.delta_height}),n.content_editable||(N.setStyles(l.sizeContainer||l.editorContainer,{wi2dth:i,h2eight:o}),o=(l.iframeHeight||o)+("number"==typeof o?l.deltaHeight||0:""),a>o&&(o=a))):(l=n.theme(t,r),l.editorContainer.nodeType&&(l.editorContainer=l.editorContainer.id=l.editorContainer.id||t.id+"_parent"),l.iframeContainer.nodeType&&(l.iframeContainer=l.iframeContainer.id=l.iframeContainer.id||t.id+"_iframecontainer"),o=l.iframeHeight||r.offsetHeight),t.editorContainer=l.editorContainer),n.content_css&&T(R(n.content_css),function(e){t.contentCSS.push(t.documentBaseURI.toAbsolute(e))}),n.content_style&&t.contentStyles.push(n.content_style),n.content_editable)return r=s=l=null,t.initContentBody();for(t.iframeHTML=n.doctype+"",n.document_base_url!=t.documentBaseUrl&&(t.iframeHTML+=''),!b.caretAfter&&n.ie7_compat&&(t.iframeHTML+=''),t.iframeHTML+='',h=0;h',t.loadedCSS[g]=!0}d=n.body_id||"tinymce",-1!=d.indexOf("=")&&(d=t.getParam("body_id","","hash"),d=d[t.id]||d),f=n.body_class||"",-1!=f.indexOf("=")&&(f=t.getParam("body_class","","hash"),f=f[t.id]||""),t.iframeHTML+='
    ";var v='javascript:(function(){document.open();document.domain="'+document.domain+'";var ed = window.parent.tinymce.get("'+t.id+'");document.write(ed.iframeHTML);document.close();ed.initContentBody(true);})()';if(document.domain!=location.hostname&&(u=v),s=N.add(l.iframeContainer,"iframe",{id:t.id+"_ifr",src:u||'javascript:""',frameBorder:"0",allowTransparency:"true",title:t.editorManager.translate("Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help"),style:{width:"100%",height:o,display:"block"}}),H)try{t.getDoc()}catch(y){s.src=u=v}t.contentAreaContainer=l.iframeContainer,l.editorContainer&&(N.get(l.editorContainer).style.display=t.orgDisplay),N.get(t.id).style.display="none",N.setAttrib(t.id,"aria-hidden",!0),u||t.initContentBody(),r=s=l=null},initContentBody:function(t){var n=this,o=n.settings,f=N.get(n.id),p=n.getDoc(),h,m;o.inline||(n.getElement().style.visibility=n.orgVisibility),t||o.content_editable||(p.open(),p.write(n.iframeHTML),p.close()),o.content_editable&&(n.on("remove",function(){var e=this.getBody();N.removeClass(e,"mce-content-body"),N.removeClass(e,"mce-edit-focus"),N.setAttrib(e,"contentEditable",null)}),N.addClass(f,"mce-content-body"),n.contentDocument=p=o.content_document||document,n.contentWindow=o.content_window||window,n.bodyElement=f,o.content_document=o.content_window=null,o.root_name=f.nodeName.toLowerCase()),h=n.getBody(),h.disabled=!0,o.readonly||(n.inline&&"static"==N.getStyle(h,"position",!0)&&(h.style.position="relative"),h.contentEditable=n.getParam("content_editable_state",!0)),h.disabled=!1,n.schema=new g(o),n.dom=new e(p,{keep_values:!0,url_converter:n.convertURL,url_converter_scope:n,hex_colors:o.force_hex_style_colors,class_filter:o.class_filter,update_styles:!0,root_element:o.content_editable?n.id:null,collect:o.content_editable,schema:n.schema,onSetAttrib:function(e){n.fire("SetAttrib",e) +}}),n.parser=new v(o,n.schema),n.parser.addAttributeFilter("src,href,style,tabindex",function(e,t){for(var r=e.length,i,o=n.dom,a,s;r--;)i=e[r],a=i.attr(t),s="data-mce-"+t,i.attributes.map[s]||("style"===t?i.attr(s,o.serializeStyle(o.parseStyle(a),i.name)):"tabindex"===t?(i.attr(s,a),i.attr(t,null)):i.attr(s,n.convertURL(a,t,i.name)))}),n.parser.addNodeFilter("script",function(e){for(var t=e.length,n;t--;)n=e[t],n.attr("type","mce-"+(n.attr("type")||"text/javascript"))}),n.parser.addNodeFilter("#cdata",function(e){for(var t=e.length,n;t--;)n=e[t],n.type=8,n.name="#comment",n.value="[CDATA["+n.value+"]]"}),n.parser.addNodeFilter("p,h1,h2,h3,h4,h5,h6,div",function(e){for(var t=e.length,i,o=n.schema.getNonEmptyElements();t--;)i=e[t],i.isEmpty(o)&&(i.empty().append(new r("br",1)).shortEnded=!0)}),n.serializer=new i(o,n),n.selection=new a(n.dom,n.getWin(),n.serializer,n),n.formatter=new s(n),n.undoManager=new l(n),n.forceBlocks=new u(n),n.enterKey=new c(n),n.editorCommands=new d(n),n.fire("PreInit"),o.browser_spellcheck||o.gecko_spellcheck||(p.body.spellcheck=!1,N.setAttrib(h,"spellcheck","false")),n.fire("PostRender"),n.quirks=y(n),o.directionality&&(h.dir=o.directionality),o.nowrap&&(h.style.whiteSpace="nowrap"),o.protect&&n.on("BeforeSetContent",function(e){T(o.protect,function(t){e.content=e.content.replace(t,function(e){return""})})}),n.on("SetContent",function(){n.addVisual(n.getBody())}),o.padd_empty_editor&&n.on("PostProcess",function(e){e.content=e.content.replace(/^(]*>( | |\s|\u00a0|)<\/p>[\r\n]*|
    [\r\n]*)$/,"")}),n.load({initial:!0,format:"html"}),n.startContent=n.getContent({format:"raw"}),n.initialized=!0,n.bindPendingEventDelegates(),n.fire("init"),n.focus(!0),n.nodeChanged({initial:!0}),n.execCallback("init_instance_callback",n),n.contentStyles.length>0&&(m="",T(n.contentStyles,function(e){m+=e+"\r\n"}),n.dom.addStyle(m)),T(n.contentCSS,function(e){n.loadedCSS[e]||(n.dom.loadCSS(e),n.loadedCSS[e]=!0)}),o.auto_focus&&setTimeout(function(){var e=n.editorManager.get(o.auto_focus);e.selection.select(e.getBody(),1),e.selection.collapse(1),e.getBody().focus(),e.getWin().focus()},100),f=p=h=null},focus:function(e){var t,n=this,r=n.selection,i=n.settings.content_editable,o,a,s=n.getDoc(),l;if(!e){if(o=r.getRng(),o.item&&(a=o.item(0)),n._refreshContentEditable(),i||(b.opera||n.getBody().focus(),n.getWin().focus()),M||i){if(l=n.getBody(),l.setActive)try{l.setActive()}catch(c){l.focus()}else l.focus();i&&r.normalize()}a&&a.ownerDocument==s&&(o=s.body.createControlRange(),o.addElement(a),o.select())}n.editorManager.activeEditor!=n&&((t=n.editorManager.activeEditor)&&t.fire("deactivate",{relatedTarget:n}),n.fire("activate",{relatedTarget:t})),n.editorManager.activeEditor=n},execCallback:function(e){var t=this,n=t.settings[e],r;if(n)return t.callbackLookup&&(r=t.callbackLookup[e])&&(n=r.func,r=r.scope),"string"==typeof n&&(r=n.replace(/\.\w+$/,""),r=r?D(r):0,n=D(n),t.callbackLookup=t.callbackLookup||{},t.callbackLookup[e]={func:n,scope:r}),n.apply(r||t,Array.prototype.slice.call(arguments,1))},translate:function(e){var t=this.settings.language||"en",n=this.editorManager.i18n;return e?n.data[t+"."+e]||e.replace(/\{\#([^\}]+)\}/g,function(e,r){return n.data[t+"."+r]||"{#"+r+"}"}):""},getLang:function(e,n){return this.editorManager.i18n.data[(this.settings.language||"en")+"."+e]||(n!==t?n:"{#"+e+"}")},getParam:function(e,t,n){var r=e in this.settings?this.settings[e]:t,i;return"hash"===n?(i={},"string"==typeof r?T(r.split(r.indexOf("=")>0?/[;,](?![^=;,]*(?:[;,]|$))/:","),function(e){e=e.split("="),i[B(e[0])]=B(e.length>1?e[1]:e)}):i=r,i):r},nodeChanged:function(){var e=this,t=e.selection,n,r,i;!e.initialized||e.settings.disable_nodechange||e.settings.readonly||(i=e.getBody(),n=t.getStart()||i,n=H&&n.ownerDocument!=e.getDoc()?e.getBody():n,"IMG"==n.nodeName&&t.isCollapsed()&&(n=n.parentNode),r=[],e.dom.getParent(n,function(e){return e===i?!0:void r.push(e)}),e.fire("NodeChange",{element:n,parents:r}))},addButton:function(e,t){var n=this;t.cmd&&(t.onclick=function(){n.execCommand(t.cmd)}),t.text||t.icon||(t.icon=e),n.buttons=n.buttons||{},t.tooltip=t.tooltip||t.title,n.buttons[e]=t},addMenuItem:function(e,t){var n=this;t.cmd&&(t.onclick=function(){n.execCommand(t.cmd)}),n.menuItems=n.menuItems||{},n.menuItems[e]=t},addCommand:function(e,t,n){this.execCommands[e]={func:t,scope:n||this}},addQueryStateHandler:function(e,t,n){this.queryStateCommands[e]={func:t,scope:n||this}},addQueryValueHandler:function(e,t,n){this.queryValueCommands[e]={func:t,scope:n||this}},addShortcut:function(e,t,n,r){this.shortcuts.add(e,t,n,r)},execCommand:function(e,t,n,r){var i=this,o=0,a;return/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(e)||r&&r.skip_focus||i.focus(),r=k({},r),r=i.fire("BeforeExecCommand",{command:e,ui:t,value:n}),r.isDefaultPrevented()?!1:(a=i.execCommands[e])&&a.func.call(a.scope,t,n)!==!0?(i.fire("ExecCommand",{command:e,ui:t,value:n}),!0):(T(i.plugins,function(r){return r.execCommand&&r.execCommand(e,t,n)?(i.fire("ExecCommand",{command:e,ui:t,value:n}),o=!0,!1):void 0}),o?o:i.theme&&i.theme.execCommand&&i.theme.execCommand(e,t,n)?(i.fire("ExecCommand",{command:e,ui:t,value:n}),!0):i.editorCommands.execCommand(e,t,n)?(i.fire("ExecCommand",{command:e,ui:t,value:n}),!0):(i.getDoc().execCommand(e,t,n),void i.fire("ExecCommand",{command:e,ui:t,value:n})))},queryCommandState:function(e){var t=this,n,r;if(!t._isHidden()){if((n=t.queryStateCommands[e])&&(r=n.func.call(n.scope),r!==!0))return r;if(r=t.editorCommands.queryCommandState(e),-1!==r)return r;try{return t.getDoc().queryCommandState(e)}catch(i){}}},queryCommandValue:function(e){var n=this,r,i;if(!n._isHidden()){if((r=n.queryValueCommands[e])&&(i=r.func.call(r.scope),i!==!0))return i;if(i=n.editorCommands.queryCommandValue(e),i!==t)return i;try{return n.getDoc().queryCommandValue(e)}catch(o){}}},show:function(){var e=this;e.hidden&&(e.hidden=!1,e.inline?e.getBody().contentEditable=!0:(N.show(e.getContainer()),N.hide(e.id)),e.load(),e.fire("show"))},hide:function(){var e=this,t=e.getDoc();e.hidden||(e.hidden=!0,H&&t&&!e.inline&&t.execCommand("SelectAll"),e.save(),e.inline?(e.getBody().contentEditable=!1,e==e.editorManager.focusedEditor&&(e.editorManager.focusedEditor=null)):(N.hide(e.getContainer()),N.setStyle(e.id,"display",e.orgDisplay)),e.fire("hide"))},isHidden:function(){return!!this.hidden},setProgressState:function(e,t){this.fire("ProgressState",{state:e,time:t})},load:function(e){var n=this,r=n.getElement(),i;return r?(e=e||{},e.load=!0,i=n.setContent(r.value!==t?r.value:r.innerHTML,e),e.element=r,e.no_events||n.fire("LoadContent",e),e.element=r=null,i):void 0},save:function(e){var t=this,n=t.getElement(),r,i;if(n&&t.initialized)return e=e||{},e.save=!0,e.element=n,r=e.content=t.getContent(e),e.no_events||t.fire("SaveContent",e),r=e.content,/TEXTAREA|INPUT/i.test(n.nodeName)?n.value=r:(t.inline||(n.innerHTML=r),(i=N.getParent(t.id,"form"))&&T(i.elements,function(e){return e.name==t.id?(e.value=r,!1):void 0})),e.element=n=null,e.set_dirty!==!1&&(t.isNotDirty=!0),r},setContent:function(e,t){var n=this,r=n.getBody(),i;return t=t||{},t.format=t.format||"html",t.set=!0,t.content=e,t.no_events||n.fire("BeforeSetContent",t),e=t.content,0===e.length||/^\s+$/.test(e)?(i=n.settings.forced_root_block,i&&n.schema.isValidChild(r.nodeName.toLowerCase(),i.toLowerCase())?(e=H&&11>H?"":'
    ',e=n.dom.createHTML(i,n.settings.forced_root_block_attrs,e)):H||(e='
    '),r.innerHTML=e,n.fire("SetContent",t)):("raw"!==t.format&&(e=new o({},n.schema).serialize(n.parser.parse(e,{isRootContent:!0}))),t.content=B(e),n.dom.setHTML(r,t.content),t.no_events||n.fire("SetContent",t)),t.content},getContent:function(e){var t=this,n,r=t.getBody();return e=e||{},e.format=e.format||"html",e.get=!0,e.getInner=!0,e.no_events||t.fire("BeforeGetContent",e),n="raw"==e.format?r.innerHTML:"text"==e.format?r.innerText||r.textContent:t.serializer.serialize(r,e),e.content="text"!=e.format?B(n):n,e.no_events||t.fire("GetContent",e),e.content},insertContent:function(e){this.execCommand("mceInsertContent",!1,e)},isDirty:function(){return!this.isNotDirty},getContainer:function(){var e=this;return e.container||(e.container=N.get(e.editorContainer||e.id+"_parent")),e.container},getContentAreaContainer:function(){return this.contentAreaContainer},getElement:function(){return N.get(this.settings.content_element||this.id)},getWin:function(){var e=this,t;return e.contentWindow||(t=N.get(e.id+"_ifr"),t&&(e.contentWindow=t.contentWindow)),e.contentWindow},getDoc:function(){var e=this,t;return e.contentDocument||(t=e.getWin(),t&&(e.contentDocument=t.document)),e.contentDocument},getBody:function(){return this.bodyElement||this.getDoc().body},convertURL:function(e,t,n){var r=this,i=r.settings;return i.urlconverter_callback?r.execCallback("urlconverter_callback",e,n,!0,t):!i.convert_urls||n&&"LINK"==n.nodeName||0===e.indexOf("file:")||0===e.length?e:i.relative_urls?r.documentBaseURI.toRelative(e):e=r.documentBaseURI.toAbsolute(e,i.remove_script_host)},addVisual:function(e){var n=this,r=n.settings,i=n.dom,o;e=e||n.getBody(),n.hasVisual===t&&(n.hasVisual=r.visual),T(i.select("table,a",e),function(e){var t;switch(e.nodeName){case"TABLE":return o=r.visual_table_class||"mce-item-table",t=i.getAttrib(e,"border"),void(t&&"0"!=t||(n.hasVisual?i.addClass(e,o):i.removeClass(e,o)));case"A":return void(i.getAttrib(e,"href",!1)||(t=i.getAttrib(e,"name")||e.id,o=r.visual_anchor_class||"mce-item-anchor",t&&(n.hasVisual?i.addClass(e,o):i.removeClass(e,o))))}}),n.fire("VisualAid",{element:e,hasVisual:n.hasVisual})},remove:function(){var e=this;if(!e.removed){e.removed=1,e.save(),e.hasHiddenInput&&N.remove(e.getElement().nextSibling),e.inline||(H&&10>H&&e.getDoc().execCommand("SelectAll",!1,null),N.setStyle(e.id,"display",e.orgDisplay),e.getBody().onload=null,L.unbind(e.getWin()),L.unbind(e.getDoc()));var t=e.getContainer();L.unbind(e.getBody()),L.unbind(t),e.fire("remove"),e.editorManager.remove(e),N.remove(t),e.destroy()}},destroy:function(e){var t=this,n;if(!t.destroyed){if(!e&&!t.removed)return void t.remove();e&&M&&(L.unbind(t.getDoc()),L.unbind(t.getWin()),L.unbind(t.getBody())),e||(t.editorManager.off("beforeunload",t._beforeUnload),t.theme&&t.theme.destroy&&t.theme.destroy(),t.selection.destroy(),t.dom.destroy()),n=t.formElement,n&&(n._mceOldSubmit&&(n.submit=n._mceOldSubmit,n._mceOldSubmit=null),N.unbind(n,"submit reset",t.formEventDelegate)),t.contentAreaContainer=t.formElement=t.container=t.editorContainer=null,t.settings.content_element=t.bodyElement=t.contentDocument=t.contentWindow=null,t.selection&&(t.selection=t.selection.win=t.selection.dom=t.selection.dom.doc=null),t.destroyed=1}},_refreshContentEditable:function(){var e=this,t,n;e._isHidden()&&(t=e.getBody(),n=t.parentNode,n.removeChild(t),n.appendChild(t),t.focus())},_isHidden:function(){var e;return M?(e=this.selection.getSel(),!e||!e.rangeCount||0===e.rangeCount):0}},k(_.prototype,x),_}),r(ct,[],function(){var e={};return{rtl:!1,add:function(t,n){for(var r in n)e[r]=n[r];this.rtl=this.rtl||"rtl"===e._dir},translate:function(t){if("undefined"==typeof t)return t;if("string"!=typeof t&&t.raw)return t.raw;if(t.push){var n=t.slice(1);t=(e[t[0]]||t[0]).replace(/\{([^\}]+)\}/g,function(e,t){return n[t]})}return e[t]||t},data:e}}),r(ut,[y,g],function(e,t){function n(e){function s(){try{return document.activeElement}catch(e){return document.body}}function l(e,t){if(t&&t.startContainer){if(!e.isChildOf(t.startContainer,e.getRoot())||!e.isChildOf(t.endContainer,e.getRoot()))return;return{startContainer:t.startContainer,startOffset:t.startOffset,endContainer:t.endContainer,endOffset:t.endOffset}}return t}function c(e,t){var n;return t.startContainer?(n=e.getDoc().createRange(),n.setStart(t.startContainer,t.startOffset),n.setEnd(t.endContainer,t.endOffset)):n=t,n}function u(e){return!!a.getParent(e,n.isEditorUIElement)}function d(n){var d=n.editor;d.on("init",function(){(d.inline||t.ie)&&(d.on("nodechange keyup",function(){var e=document.activeElement;e&&e.id==d.id+"_ifr"&&(e=d.getBody()),d.dom.isChildOf(e,d.getBody())&&(d.lastRng=d.selection.getRng())}),t.webkit&&!r&&(r=function(){var t=e.activeEditor;if(t&&t.selection){var n=t.selection.getRng();n&&!n.collapsed&&(d.lastRng=n)}},a.bind(document,"selectionchange",r)))}),d.on("setcontent",function(){d.lastRng=null}),d.on("mousedown",function(){d.selection.lastFocusBookmark=null}),d.on("focusin",function(){var t=e.focusedEditor;d.selection.lastFocusBookmark&&(d.selection.setRng(c(d,d.selection.lastFocusBookmark)),d.selection.lastFocusBookmark=null),t!=d&&(t&&t.fire("blur",{focusedEditor:d}),e.activeEditor=d,e.focusedEditor=d,d.fire("focus",{blurredEditor:t}),d.focus(!0)),d.lastRng=null}),d.on("focusout",function(){window.setTimeout(function(){var t=e.focusedEditor;u(s())||t!=d||(d.fire("blur",{focusedEditor:null}),e.focusedEditor=null,d.selection&&(d.selection.lastFocusBookmark=null))},0)}),i||(i=function(t){var n=e.activeEditor;n&&t.target.ownerDocument==document&&(n.selection&&(n.selection.lastFocusBookmark=l(n.dom,n.lastRng)),u(t.target)||e.focusedEditor!=n||(n.fire("blur",{focusedEditor:null}),e.focusedEditor=null))},a.bind(document,"focusin",i)),d.inline&&!o&&(o=function(t){var n=e.activeEditor;if(n.inline&&!n.dom.isChildOf(t.target,n.getBody())){var r=n.selection.getRng();r.collapsed||(n.lastRng=r)}},a.bind(document,"mouseup",o))}function f(t){e.focusedEditor==t.editor&&(e.focusedEditor=null),e.activeEditor||(a.unbind(document,"selectionchange",r),a.unbind(document,"focusin",i),a.unbind(document,"mouseup",o),r=i=o=null)}e.on("AddEditor",d),e.on("RemoveEditor",f)}var r,i,o,a=e.DOM;return n.isEditorUIElement=function(e){return-1!==e.className.toString().indexOf("mce-")},n}),r(dt,[lt,y,F,g,p,ot,ct,ut],function(e,t,n,r,i,o,a,s){function l(e){var t=g.editors,n;delete t[e.id];for(var r=0;r0&&f(d(c),function(n){u.get(n)?(m=new e(n,t,s),l.push(m),m.render()):f(document.forms,function(e){f(e.elements,function(e){e.name===n&&(n="mce_editor_"+h++,u.setAttrib(e,"id",n),r(n,t))})})});break;case"textareas":case"specific_textareas":f(u.select("textarea"),function(e){t.editor_deselector&&o(e,t.editor_deselector)||(!t.editor_selector||o(e,t.editor_selector))&&r(n(e),t)})}t.oninit&&(c=g=0,f(l,function(e){g++,e.initialized?c++:e.on("init",function(){c++,c==g&&i(t,"oninit")}),c==g&&i(t,"oninit")}))}var s=this,l=[],m;s.settings=t,u.bind(window,"ready",a)},get:function(e){return arguments.length?e in this.editors?this.editors[e]:null:this.editors},add:function(e){var t=this,n=t.editors;return n[e.id]=e,n.push(e),t.activeEditor=e,t.fire("AddEditor",{editor:e}),m||(m=function(){t.fire("BeforeUnload")},u.bind(window,"beforeunload",m)),e},createEditor:function(t,n){return this.add(new e(t,n,this))},remove:function(e){var t=this,n,r=t.editors,i;{if(e)return"string"==typeof e?(e=e.selector||e,void f(u.select(e),function(e){t.remove(r[e.id])})):(i=e,r[i.id]?(l(i)&&t.fire("RemoveEditor",{editor:i}),r.length||u.unbind(window,"beforeunload",m),i.remove(),i):null);for(n=r.length-1;n>=0;n--)t.remove(r[n])}},execCommand:function(t,n,r){var i=this,o=i.get(r);switch(t){case"mceAddEditor":return i.get(r)||new e(r,i.settings,i).render(),!0;case"mceRemoveEditor":return o&&o.remove(),!0;case"mceToggleEditor":return o?(o.isHidden()?o.show():o.hide(),!0):(i.execCommand("mceAddEditor",0,r),!0)}return i.activeEditor?i.activeEditor.execCommand(t,n,r):!1},triggerSave:function(){f(this.editors,function(e){e.save()})},addI18n:function(e,t){a.add(e,t)},translate:function(e){return a.translate(e)}},p(g,o),g.setup(),window.tinymce=window.tinyMCE=g,g}),r(ft,[dt,p],function(e,t){var n=t.each,r=t.explode;e.on("AddEditor",function(e){var t=e.editor;t.on("preInit",function(){function e(e,t){n(t,function(t,n){t&&s.setStyle(e,n,t)}),s.rename(e,"span")}function i(e){s=t.dom,l.convert_fonts_to_spans&&n(s.select("font,u,strike",e.node),function(e){o[e.nodeName.toLowerCase()](s,e)})}var o,a,s,l=t.settings;l.inline_styles&&(a=r(l.font_size_legacy_values),o={font:function(t,n){e(n,{backgroundColor:n.style.backgroundColor,color:n.color,fontFamily:n.face,fontSize:a[parseInt(n.size,10)-1]})},u:function(t,n){e(n,{textDecoration:"underline"})},strike:function(t,n){e(n,{textDecoration:"line-through"})}},t.on("PreProcess SetContent",i))})})}),r(pt,[],function(){return{send:function(e){function t(){!e.async||4==n.readyState||r++>1e4?(e.success&&1e4>r&&200==n.status?e.success.call(e.success_scope,""+n.responseText,n,e):e.error&&e.error.call(e.error_scope,r>1e4?"TIMED_OUT":"GENERAL",n,e),n=null):setTimeout(t,10)}var n,r=0;if(e.scope=e.scope||this,e.success_scope=e.success_scope||e.scope,e.error_scope=e.error_scope||e.scope,e.async=e.async===!1?!1:!0,e.data=e.data||"",n=new XMLHttpRequest){if(n.overrideMimeType&&n.overrideMimeType(e.content_type),n.open(e.type||(e.data?"POST":"GET"),e.url,e.async),e.content_type&&n.setRequestHeader("Content-Type",e.content_type),n.setRequestHeader("X-Requested-With","XMLHttpRequest"),n.send(e.data),!e.async)return t();setTimeout(t,10)}}}}),r(ht,[],function(){function e(t,n){var r,i,o,a;if(n=n||'"',null===t)return"null";if(o=typeof t,"string"==o)return i="\bb t\nn\ff\rr\"\"''\\\\",n+t.replace(/([\u0080-\uFFFF\x00-\x1f\"\'\\])/g,function(e,t){return'"'===n&&"'"===e?e:(r=i.indexOf(t),r+1?"\\"+i.charAt(r+1):(e=t.charCodeAt().toString(16),"\\u"+"0000".substring(e.length)+e))})+n;if("object"==o){if(t.hasOwnProperty&&"[object Array]"===Object.prototype.toString.call(t)){for(r=0,i="[";r0?",":"")+e(t[r],n);return i+"]"}i="{";for(a in t)t.hasOwnProperty(a)&&(i+="function"!=typeof t[a]?(i.length>1?","+n:n)+a+n+":"+e(t[a],n):"");return i+"}"}return""+t}return{serialize:e,parse:function(e){try{return window[String.fromCharCode(101)+"val"]("("+e+")")}catch(t){}}}}),r(mt,[ht,pt,p],function(e,t,n){function r(e){this.settings=i({},e),this.count=0}var i=n.extend;return r.sendRPC=function(e){return(new r).send(e)},r.prototype={send:function(n){var r=n.error,o=n.success;n=i(this.settings,n),n.success=function(t,i){t=e.parse(t),"undefined"==typeof t&&(t={error:"JSON Parse error."}),t.error?r.call(n.error_scope||n.scope,t.error,i):o.call(n.success_scope||n.scope,t.result)},n.error=function(e,t){r&&r.call(n.error_scope||n.scope,e,t)},n.data=e.serialize({id:n.id||"c"+this.count++,method:n.method,params:n.params}),n.content_type="application/json",t.send(n)}},r}),r(gt,[y],function(e){return{callbacks:{},count:0,send:function(n){var r=this,i=e.DOM,o=n.count!==t?n.count:r.count,a="tinymce_jsonp_"+o;r.callbacks[o]=function(e){i.remove(a),delete r.callbacks[o],n.callback(e)},i.add(i.doc.body,"script",{id:a,src:n.url,type:"text/javascript"}),r.count++}}}),r(vt,[],function(){function e(){s=[];for(var e in a)s.push(e);i.length=s.length}function n(){function n(e){var n,r;return r=e!==t?u+e:i.indexOf(",",u),-1===r||r>i.length?null:(n=i.substring(u,r),u=r+1,n)}var r,i,s,u=0;if(a={},c){o.load(l),i=o.getAttribute(l)||"";do{var d=n();if(null===d)break;if(r=n(parseInt(d,32)||0),null!==r){if(d=n(),null===d)break;s=n(parseInt(d,32)||0),r&&(a[r]=s)}}while(null!==r);e()}}function r(){var t,n="";if(c){for(var r in a)t=a[r],n+=(n?",":"")+r.length.toString(32)+","+r+","+t.length.toString(32)+","+t;o.setAttribute(l,n);try{o.save(l)}catch(i){}e()}}var i,o,a,s,l,c;try{if(window.localStorage)return localStorage}catch(u){}return l="tinymce",o=document.documentElement,c=!!o.addBehavior,c&&o.addBehavior("#default#userData"),i={key:function(e){return s[e]},getItem:function(e){return e in a?a[e]:null},setItem:function(e,t){a[e]=""+t,r()},removeItem:function(e){delete a[e],r()},clear:function(){a={},r()}},n(),i}),r(yt,[y,l,b,C,p,g],function(e,t,n,r,i,o){var a=window.tinymce;return a.DOM=e.DOM,a.ScriptLoader=n.ScriptLoader,a.PluginManager=r.PluginManager,a.ThemeManager=r.ThemeManager,a.dom=a.dom||{},a.dom.Event=t.Event,i.each(i,function(e,t){a[t]=e}),i.each("isOpera isWebKit isIE isGecko isMac".split(" "),function(e){a[e]=o[e.substr(2).toLowerCase()]}),{}}),r(bt,[z,p],function(e,t){return e.extend({Defaults:{firstControlClass:"first",lastControlClass:"last"},init:function(e){this.settings=t.extend({},this.Defaults,e)},preRender:function(e){e.addClass(this.settings.containerClass,"body")},applyClasses:function(e){var t=this,n=t.settings,r,i,o;r=e.items().filter(":visible"),i=n.firstControlClass,o=n.lastControlClass,r.each(function(e){e.removeClass(i).removeClass(o),n.controlClass&&e.addClass(n.controlClass)}),r.eq(0).addClass(i),r.eq(-1).addClass(o)},renderHtml:function(e){var t=this,n=t.settings,r,i="";return r=e.items(),r.eq(0).addClass(n.firstControlClass),r.eq(-1).addClass(n.lastControlClass),r.each(function(e){n.controlClass&&e.addClass(n.controlClass),i+=e.renderHtml()}),i},recalc:function(){},postRender:function(){}})}),r(Ct,[bt],function(e){return e.extend({Defaults:{containerClass:"abs-layout",controlClass:"abs-layout-item"},recalc:function(e){e.items().filter(":visible").each(function(e){var t=e.settings;e.layoutRect({x:t.x,y:t.y,w:t.w,h:t.h}),e.recalc&&e.recalc()})},renderHtml:function(e){return'
    '+this._super(e)}})}),r(xt,[$,Q],function(e,t){return e.extend({Mixins:[t],Defaults:{classes:"widget tooltip tooltip-n"},text:function(e){var t=this;return"undefined"!=typeof e?(t._value=e,t._rendered&&(t.getEl().lastChild.innerHTML=t.encode(e)),t):t._value},renderHtml:function(){var e=this,t=e.classPrefix;return'"},repaint:function(){var e=this,t,n;t=e.getEl().style,n=e._layoutRect,t.left=n.x+"px",t.top=n.y+"px",t.zIndex=131070}})}),r(wt,[$,xt],function(e,t){var n,r=e.extend({init:function(e){var t=this;t._super(e),e=t.settings,t.canFocus=!0,e.tooltip&&r.tooltips!==!1&&(t.on("mouseenter",function(n){var r=t.tooltip().moveTo(-65535);if(n.control==t){var i=r.text(e.tooltip).show().testMoveRel(t.getEl(),["bc-tc","bc-tl","bc-tr"]);r.toggleClass("tooltip-n","bc-tc"==i),r.toggleClass("tooltip-nw","bc-tl"==i),r.toggleClass("tooltip-ne","bc-tr"==i),r.moveRel(t.getEl(),i)}else r.hide()}),t.on("mouseleave mousedown click",function(){t.tooltip().hide()})),t.aria("label",e.ariaLabel||e.tooltip)},tooltip:function(){return n||(n=new t({type:"tooltip"}),n.renderTo()),n},active:function(e){var t=this,n;return e!==n&&(t.aria("pressed",e),t.toggleClass("active",e)),t._super(e)},disabled:function(e){var t=this,n;return e!==n&&(t.aria("disabled",e),t.toggleClass("disabled",e)),t._super(e)},postRender:function(){var e=this,t=e.settings;e._rendered=!0,e._super(),e.parent()||!t.width&&!t.height||(e.initLayoutRect(),e.repaint()),t.autofocus&&e.focus()},remove:function(){this._super(),n&&(n.remove(),n=null)}});return r}),r(_t,[wt],function(e){return e.extend({Defaults:{classes:"widget btn",role:"button"},init:function(e){var t=this,n;t.on("click mousedown",function(e){e.preventDefault()}),t._super(e),n=e.size,e.subtype&&t.addClass(e.subtype),n&&t.addClass("btn-"+n)},icon:function(e){var t=this,n=t.classPrefix;if("undefined"==typeof e)return t.settings.icon;if(t.settings.icon=e,e=e?n+"ico "+n+"i-"+t.settings.icon:"",t._rendered){var r=t.getEl().firstChild,i=r.getElementsByTagName("i")[0];e?(i&&i==r.firstChild||(i=document.createElement("i"),r.insertBefore(i,r.firstChild)),i.className=e):i&&r.removeChild(i),t.text(t._text)}return t},repaint:function(){var e=this.getEl().firstChild.style;e.width=e.height="100%",this._super()},text:function(e){var t=this;if(t._rendered){var n=t.getEl().lastChild.lastChild;n&&(n.data=t.translate(e))}return t._super(e)},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.settings.icon,i;return i=e.settings.image,i?(r="none","string"!=typeof i&&(i=window.getSelection?i[0]:i[1]),i=" style=\"background-image: url('"+i+"')\""):i="",r=e.settings.icon?n+"ico "+n+"i-"+r:"",'
    "}})}),r(Nt,[G],function(e){return e.extend({Defaults:{defaultType:"button",role:"group"},renderHtml:function(){var e=this,t=e._layout;return e.addClass("btn-group"),e.preRender(),t.preRender(e),'
    '+(e.settings.html||"")+t.renderHtml(e)+"
    "}})}),r(Et,[wt],function(e){return e.extend({Defaults:{classes:"checkbox",role:"checkbox",checked:!1},init:function(e){var t=this;t._super(e),t.on("click mousedown",function(e){e.preventDefault()}),t.on("click",function(e){e.preventDefault(),t.disabled()||t.checked(!t.checked())}),t.checked(t.settings.checked)},checked:function(e){var t=this;return"undefined"!=typeof e?(e?t.addClass("checked"):t.removeClass("checked"),t._checked=e,t.aria("checked",e),t):t._checked},value:function(e){return this.checked(e)},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix;return'
    '+e.encode(e._text)+"
    "}})}),r(St,[_t,et],function(e,t){return e.extend({showPanel:function(){var e=this,n=e.settings;if(e.active(!0),e.panel)e.panel.show();else{var r=n.panel;r.type&&(r={layout:"grid",items:r}),r.role=r.role||"dialog",r.popover=!0,r.autohide=!0,r.ariaRoot=!0,e.panel=new t(r).on("hide",function(){e.active(!1)}).on("cancel",function(t){t.stopPropagation(),e.focus(),e.hidePanel()}).parent(e).renderTo(e.getContainerElm()),e.panel.fire("show"),e.panel.reflow()}e.panel.moveRel(e.getEl(),n.popoverAlign||(e.isRtl()?["bc-tr","bc-tc"]:["bc-tl","bc-tc"]))},hidePanel:function(){var e=this;e.panel&&e.panel.hide()},postRender:function(){var e=this;return e.aria("haspopup",!0),e.on("click",function(t){t.control===e&&(e.panel&&e.panel.visible()?e.hidePanel():(e.showPanel(),e.panel.focus(!!t.aria)))}),e._super()}})}),r(kt,[St,y],function(e,t){var n=t.DOM;return e.extend({init:function(e){this._super(e),this.addClass("colorbutton")},color:function(e){return e?(this._color=e,this.getEl("preview").style.backgroundColor=e,this):this._color},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.settings.icon?n+"ico "+n+"i-"+e.settings.icon:"",i=e.settings.image?" style=\"background-image: url('"+e.settings.image+"')\"":"";return'
    '},postRender:function(){var e=this,t=e.settings.onclick;return e.on("click",function(r){r.aria&&"down"==r.aria.key||r.control!=e||n.getParent(r.target,"."+e.classPrefix+"open")||(r.stopImmediatePropagation(),t.call(e,r))}),delete e.settings.onclick,e._super()}})}),r(Tt,[wt,j,q],function(e,t,n){return e.extend({init:function(e){var t=this;t._super(e),t.addClass("combobox"),t.subinput=!0,t.ariaTarget="inp",e=t.settings,e.menu=e.menu||e.values,e.menu&&(e.icon="caret"),t.on("click",function(n){for(var r=n.target,i=t.getEl();r&&r!=i;)r.id&&-1!=r.id.indexOf("-open")&&(t.fire("action"),e.menu&&(t.showMenu(),n.aria&&t.menu.items()[0].focus())),r=r.parentNode}),t.on("keydown",function(e){"INPUT"==e.target.nodeName&&13==e.keyCode&&t.parents().reverse().each(function(n){return e.preventDefault(),t.fire("change"),n.hasEventListeners("submit")&&n.toJSON?(n.fire("submit",{data:n.toJSON()}),!1):void 0})}),e.placeholder&&(t.addClass("placeholder"),t.on("focusin",function(){t._hasOnChange||(n.on(t.getEl("inp"),"change",function(){t.fire("change")}),t._hasOnChange=!0),t.hasClass("placeholder")&&(t.getEl("inp").value="",t.removeClass("placeholder"))}),t.on("focusout",function(){0===t.value().length&&(t.getEl("inp").value=e.placeholder,t.addClass("placeholder"))}))},showMenu:function(){var e=this,n=e.settings,r;e.menu||(r=n.menu||[],r.length?r={type:"menu",items:r}:r.type=r.type||"menu",e.menu=t.create(r).parent(e).renderTo(e.getContainerElm()),e.fire("createmenu"),e.menu.reflow(),e.menu.on("cancel",function(t){t.control===e.menu&&e.focus()}),e.menu.on("show hide",function(t){t.control.items().each(function(t){t.active(t.value()==e.value())})}).fire("show"),e.menu.on("select",function(t){e.value(t.control.value())}),e.on("focusin",function(t){"INPUT"==t.target.tagName.toUpperCase()&&e.menu.hide()}),e.aria("expanded",!0)),e.menu.show(),e.menu.layoutRect({w:e.layoutRect().w}),e.menu.moveRel(e.getEl(),e.isRtl()?["br-tr","tr-br"]:["bl-tl","tl-bl"])},value:function(e){var t=this;return"undefined"!=typeof e?(t._value=e,t.removeClass("placeholder"),t._rendered&&(t.getEl("inp").value=e),t):t._rendered?(e=t.getEl("inp").value,e!=t.settings.placeholder?e:""):t._value},disabled:function(e){var t=this;return t._rendered&&"undefined"!=typeof e&&(t.getEl("inp").disabled=e),t._super(e)},focus:function(){this.getEl("inp").focus()},repaint:function(){var e=this,t=e.getEl(),r=e.getEl("open"),i=e.layoutRect(),o,a;o=r?i.w-n.getSize(r).width-10:i.w-10;var s=document;return s.all&&(!s.documentMode||s.documentMode<=8)&&(a=e.layoutRect().h-2+"px"),n.css(t.firstChild,{width:o,lineHeight:a}),e._super(),e},postRender:function(){var e=this;return n.on(this.getEl("inp"),"change",function(){e.fire("change")}),e._super()},remove:function(){n.off(this.getEl("inp")),this._super()},renderHtml:function(){var e=this,t=e._id,n=e.settings,r=e.classPrefix,i=n.value||n.placeholder||"",o,a,s="",l="";return"spellcheck"in n&&(l+=' spellcheck="'+n.spellcheck+'"'),n.maxLength&&(l+=' maxlength="'+n.maxLength+'"'),n.size&&(l+=' size="'+n.size+'"'),n.subtype&&(l+=' type="'+n.subtype+'"'),e.disabled()&&(l+=' disabled="disabled"'),o=n.icon,o&&"caret"!=o&&(o=r+"ico "+r+"i-"+n.icon),a=e._text,(o||a)&&(s='
    ",e.addClass("has-open")),'
    "+s+"
    " +}})}),r(Rt,[wt],function(e){return e.extend({init:function(e){var t=this;e.delimiter||(e.delimiter="\xbb"),t._super(e),t.addClass("path"),t.canFocus=!0,t.on("click",function(e){var n,r=e.target;(n=r.getAttribute("data-index"))&&t.fire("select",{value:t.data()[n],index:n})})},focus:function(){var e=this;return e.getEl().firstChild.focus(),e},data:function(e){var t=this;return"undefined"!=typeof e?(t._data=e,t.update(),t):t._data},update:function(){this.innerHtml(this._getPathHtml())},postRender:function(){var e=this;e._super(),e.data(e.settings.data)},renderHtml:function(){var e=this;return'
    '+e._getPathHtml()+"
    "},_getPathHtml:function(){var e=this,t=e._data||[],n,r,i="",o=e.classPrefix;for(n=0,r=t.length;r>n;n++)i+=(n>0?'":"")+'
    '+t[n].name+"
    ";return i||(i='
    \xa0
    '),i}})}),r(At,[Rt,dt],function(e,t){return e.extend({postRender:function(){function e(e){if(1===e.nodeType){if("BR"==e.nodeName||e.getAttribute("data-mce-bogus"))return!0;if("bookmark"===e.getAttribute("data-mce-type"))return!0}return!1}var n=this,r=t.activeEditor;return n.on("select",function(t){var n=[],i,o=r.getBody();for(r.focus(),i=r.selection.getStart();i&&i!=o;)e(i)||n.push(i),i=i.parentNode;r.selection.select(n[n.length-1-t.index]),r.nodeChanged()}),r.on("nodeChange",function(t){for(var i=[],o=t.parents,a=o.length;a--;)if(1==o[a].nodeType&&!e(o[a])){var s=r.fire("ResolveName",{name:o[a].nodeName.toLowerCase(),target:o[a]});i.push({name:s.name})}n.data(i)}),n._super()}})}),r(Bt,[G],function(e){return e.extend({Defaults:{layout:"flex",align:"center",defaults:{flex:1}},renderHtml:function(){var e=this,t=e._layout,n=e.classPrefix;return e.addClass("formitem"),t.preRender(e),'
    '+(e.settings.title?'
    '+e.settings.title+"
    ":"")+'
    '+(e.settings.html||"")+t.renderHtml(e)+"
    "}})}),r(Dt,[G,Bt],function(e,t){return e.extend({Defaults:{containerCls:"form",layout:"flex",direction:"column",align:"stretch",flex:1,padding:20,labelGap:30,spacing:10,callbacks:{submit:function(){this.submit()}}},preRender:function(){var e=this,n=e.items();n.each(function(n){var r,i=n.settings.label;i&&(r=new t({layout:"flex",autoResize:"overflow",defaults:{flex:1},items:[{type:"label",id:n._id+"-l",text:i,flex:0,forId:n._id,disabled:n.disabled()}]}),r.type="formitem",n.aria("labelledby",n._id+"-l"),"undefined"==typeof n.settings.flex&&(n.settings.flex=1),e.replace(n,r),r.add(n))})},recalcLabels:function(){var e=this,t=0,n=[],r,i;if(e.settings.labelGapCalc!==!1)for(e.items().filter("formitem").each(function(e){var r=e.items()[0],i=r.getEl().clientWidth;t=i>t?i:t,n.push(r)}),i=e.settings.labelGap||0,r=n.length;r--;)n[r].settings.minWidth=t+i},visible:function(e){var t=this._super(e);return e===!0&&this._rendered&&this.recalcLabels(),t},submit:function(){return this.fire("submit",{data:this.toJSON()})},postRender:function(){var e=this;e._super(),e.recalcLabels(),e.fromJSON(e.settings.data)}})}),r(Lt,[Dt],function(e){return e.extend({Defaults:{containerCls:"fieldset",layout:"flex",direction:"column",align:"stretch",flex:1,padding:"25 15 5 15",labelGap:30,spacing:10,border:1},renderHtml:function(){var e=this,t=e._layout,n=e.classPrefix;return e.preRender(),t.preRender(e),'
    '+(e.settings.title?''+e.settings.title+"":"")+'
    '+(e.settings.html||"")+t.renderHtml(e)+"
    "}})}),r(Mt,[Tt],function(e){return e.extend({init:function(e){var t=this,n=tinymce.activeEditor,r;e.spellcheck=!1,r=n.settings.file_browser_callback,r&&(e.icon="browse",e.onaction=function(){r(t.getEl("inp").id,t.getEl("inp").value,e.filetype,window)}),t._super(e)}})}),r(Ht,[Ct],function(e){return e.extend({recalc:function(e){var t=e.layoutRect(),n=e.paddingBox();e.items().filter(":visible").each(function(e){e.layoutRect({x:n.left,y:n.top,w:t.innerW-n.right-n.left,h:t.innerH-n.top-n.bottom}),e.recalc&&e.recalc()})}})}),r(Pt,[Ct],function(e){return e.extend({recalc:function(e){var t,n,r,i,o,a,s,l,c,u,d,f,p,h,m,g,v=[],y,b,C,x,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O,I,F,z=Math.max,W=Math.min;for(r=e.items().filter(":visible"),i=e.layoutRect(),o=e._paddingBox,a=e.settings,f=e.isRtl()?a.direction||"row-reversed":a.direction,s=a.align,l=e.isRtl()?a.pack||"end":a.pack,c=a.spacing||0,("row-reversed"==f||"column-reverse"==f)&&(r=r.set(r.toArray().reverse()),f=f.split("-")[0]),"column"==f?(S="y",N="h",E="minH",k="maxH",R="innerH",T="top",A="deltaH",B="contentH",P="left",M="w",D="x",L="innerW",H="minW",O="right",I="deltaW",F="contentW"):(S="x",N="w",E="minW",k="maxW",R="innerW",T="left",A="deltaW",B="contentW",P="top",M="h",D="y",L="innerH",H="minH",O="bottom",I="deltaH",F="contentH"),d=i[R]-o[T]-o[T],_=u=0,t=0,n=r.length;n>t;t++)p=r[t],h=p.layoutRect(),m=p.settings,g=m.flex,d-=n-1>t?c:0,g>0&&(u+=g,h[k]&&v.push(p),h.flex=g),d-=h[E],y=o[P]+h[H]+o[O],y>_&&(_=y);if(x={},x[E]=0>d?i[E]-d+i[A]:i[R]-d+i[A],x[H]=_+i[I],x[B]=i[R]-d,x[F]=_,x.minW=W(x.minW,i.maxW),x.minH=W(x.minH,i.maxH),x.minW=z(x.minW,i.startMinWidth),x.minH=z(x.minH,i.startMinHeight),!i.autoResize||x.minW==i.minW&&x.minH==i.minH){for(C=d/u,t=0,n=v.length;n>t;t++)p=v[t],h=p.layoutRect(),b=h[k],y=h[E]+h.flex*C,y>b?(d-=h[k]-h[E],u-=h.flex,h.flex=0,h.maxFlexSize=b):h.maxFlexSize=0;for(C=d/u,w=o[T],x={},0===u&&("end"==l?w=d+o[T]:"center"==l?(w=Math.round(i[R]/2-(i[R]-d)/2)+o[T],0>w&&(w=o[T])):"justify"==l&&(w=o[T],c=Math.floor(d/(r.length-1)))),x[D]=o[P],t=0,n=r.length;n>t;t++)p=r[t],h=p.layoutRect(),y=h.maxFlexSize||h[E],"center"===s?x[D]=Math.round(i[L]/2-h[M]/2):"stretch"===s?(x[M]=z(h[H]||0,i[L]-o[P]-o[O]),x[D]=o[P]):"end"===s&&(x[D]=i[L]-h[M]-o.top),h.flex>0&&(y+=h.flex*C),x[N]=y,x[S]=w,p.layoutRect(x),p.recalc&&p.recalc(),w+=y+c}else if(x.w=x.minW,x.h=x.minH,e.layoutRect(x),this.recalc(e),null===e._lastRect){var V=e.parent();V&&(V._lastRect=null,V.recalc())}}})}),r(Ot,[bt],function(e){return e.extend({Defaults:{containerClass:"flow-layout",controlClass:"flow-layout-item",endClass:"break"},recalc:function(e){e.items().filter(":visible").each(function(e){e.recalc&&e.recalc()})}})}),r(It,[$,wt,et,p,dt,g],function(e,t,n,r,i,o){function a(e){function t(t,n){return function(){var r=this;e.on("nodeChange",function(i){var o=e.formatter,a=null;s(i.parents,function(e){return s(t,function(t){return n?o.matchNode(e,n,{value:t.value})&&(a=t.value):o.matchNode(e,t.value)&&(a=t.value),a?!1:void 0}),a?!1:void 0}),r.value(a)})}}function r(e){e=e.replace(/;$/,"").split(";");for(var t=e.length;t--;)e[t]=e[t].split("=");return e}function i(){function t(e){var n=[];if(e)return s(e,function(e){var o={text:e.title,icon:e.icon};if(e.items)o.menu=t(e.items);else{var a=e.format||"custom"+r++;e.format||(e.name=a,i.push(e)),o.format=a}n.push(o)}),n}function n(){var n;return n=t(e.settings.style_formats_merge?e.settings.style_formats?o.concat(e.settings.style_formats):o:e.settings.style_formats||o)}var r=0,i=[],o=[{title:"Headings",items:[{title:"Heading 1",format:"h1"},{title:"Heading 2",format:"h2"},{title:"Heading 3",format:"h3"},{title:"Heading 4",format:"h4"},{title:"Heading 5",format:"h5"},{title:"Heading 6",format:"h6"}]},{title:"Inline",items:[{title:"Bold",icon:"bold",format:"bold"},{title:"Italic",icon:"italic",format:"italic"},{title:"Underline",icon:"underline",format:"underline"},{title:"Strikethrough",icon:"strikethrough",format:"strikethrough"},{title:"Superscript",icon:"superscript",format:"superscript"},{title:"Subscript",icon:"subscript",format:"subscript"},{title:"Code",icon:"code",format:"code"}]},{title:"Blocks",items:[{title:"Paragraph",format:"p"},{title:"Blockquote",format:"blockquote"},{title:"Div",format:"div"},{title:"Pre",format:"pre"}]},{title:"Alignment",items:[{title:"Left",icon:"alignleft",format:"alignleft"},{title:"Center",icon:"aligncenter",format:"aligncenter"},{title:"Right",icon:"alignright",format:"alignright"},{title:"Justify",icon:"alignjustify",format:"alignjustify"}]}];return e.on("init",function(){s(i,function(t){e.formatter.register(t.name,t)})}),{type:"menu",items:n(),onPostRender:function(t){e.fire("renderFormatsMenu",{control:t.control})},itemDefaults:{preview:!0,textStyle:function(){return this.settings.format?e.formatter.getCssText(this.settings.format):void 0},onPostRender:function(){var t=this,n=this.settings.format;n&&t.parent().on("show",function(){t.disabled(!e.formatter.canApply(n)),t.active(e.formatter.match(n))})},onclick:function(){this.settings.format&&d(this.settings.format)}}}}function o(){return e.undoManager?e.undoManager.hasUndo():!1}function a(){return e.undoManager?e.undoManager.hasRedo():!1}function l(){var t=this;t.disabled(!o()),e.on("Undo Redo AddUndo TypingUndo",function(){t.disabled(!o())})}function c(){var t=this;t.disabled(!a()),e.on("Undo Redo AddUndo TypingUndo",function(){t.disabled(!a())})}function u(){var t=this;e.on("VisualAid",function(e){t.active(e.hasVisual)}),t.active(e.hasVisual)}function d(t){t.control&&(t=t.control.value()),t&&e.execCommand("mceToggleFormat",!1,t)}var f;f=i(),s({bold:"Bold",italic:"Italic",underline:"Underline",strikethrough:"Strikethrough",subscript:"Subscript",superscript:"Superscript"},function(t,n){e.addButton(n,{tooltip:t,onPostRender:function(){var t=this;e.formatter?e.formatter.formatChanged(n,function(e){t.active(e)}):e.on("init",function(){e.formatter.formatChanged(n,function(e){t.active(e)})})},onclick:function(){d(n)}})}),s({outdent:["Decrease indent","Outdent"],indent:["Increase indent","Indent"],cut:["Cut","Cut"],copy:["Copy","Copy"],paste:["Paste","Paste"],help:["Help","mceHelp"],selectall:["Select all","SelectAll"],hr:["Insert horizontal rule","InsertHorizontalRule"],removeformat:["Clear formatting","RemoveFormat"],visualaid:["Visual aids","mceToggleVisualAid"],newdocument:["New document","mceNewDocument"]},function(t,n){e.addButton(n,{tooltip:t[0],cmd:t[1]})}),s({blockquote:["Blockquote","mceBlockQuote"],numlist:["Numbered list","InsertOrderedList"],bullist:["Bullet list","InsertUnorderedList"],subscript:["Subscript","Subscript"],superscript:["Superscript","Superscript"],alignleft:["Align left","JustifyLeft"],aligncenter:["Align center","JustifyCenter"],alignright:["Align right","JustifyRight"],alignjustify:["Justify","JustifyFull"]},function(t,n){e.addButton(n,{tooltip:t[0],cmd:t[1],onPostRender:function(){var t=this;e.formatter?e.formatter.formatChanged(n,function(e){t.active(e)}):e.on("init",function(){e.formatter.formatChanged(n,function(e){t.active(e)})})}})}),e.addButton("undo",{tooltip:"Undo",onPostRender:l,cmd:"undo"}),e.addButton("redo",{tooltip:"Redo",onPostRender:c,cmd:"redo"}),e.addMenuItem("newdocument",{text:"New document",shortcut:"Ctrl+N",icon:"newdocument",cmd:"mceNewDocument"}),e.addMenuItem("undo",{text:"Undo",icon:"undo",shortcut:"Ctrl+Z",onPostRender:l,cmd:"undo"}),e.addMenuItem("redo",{text:"Redo",icon:"redo",shortcut:"Ctrl+Y",onPostRender:c,cmd:"redo"}),e.addMenuItem("visualaid",{text:"Visual aids",selectable:!0,onPostRender:u,cmd:"mceToggleVisualAid"}),s({cut:["Cut","Cut","Ctrl+X"],copy:["Copy","Copy","Ctrl+C"],paste:["Paste","Paste","Ctrl+V"],selectall:["Select all","SelectAll","Ctrl+A"],bold:["Bold","Bold","Ctrl+B"],italic:["Italic","Italic","Ctrl+I"],underline:["Underline","Underline"],strikethrough:["Strikethrough","Strikethrough"],subscript:["Subscript","Subscript"],superscript:["Superscript","Superscript"],removeformat:["Clear formatting","RemoveFormat"]},function(t,n){e.addMenuItem(n,{text:t[0],icon:n,shortcut:t[2],cmd:t[1]})}),e.on("mousedown",function(){n.hideAll()}),e.addButton("styleselect",{type:"menubutton",text:"Formats",menu:f}),e.addButton("formatselect",function(){var n=[],i=r(e.settings.block_formats||"Paragraph=p;Address=address;Pre=pre;Heading 1=h1;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6");return s(i,function(t){n.push({text:t[0],value:t[1],textStyle:function(){return e.formatter.getCssText(t[1])}})}),{type:"listbox",text:i[0][0],values:n,fixedWidth:!0,onselect:d,onPostRender:t(n)}}),e.addButton("fontselect",function(){var n="Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",i=[],o=r(e.settings.font_formats||n);return s(o,function(e){i.push({text:{raw:e[0]},value:e[1],textStyle:-1==e[1].indexOf("dings")?"font-family:"+e[1]:""})}),{type:"listbox",text:"Font Family",tooltip:"Font Family",values:i,fixedWidth:!0,onPostRender:t(i,"fontname"),onselect:function(t){t.control.settings.value&&e.execCommand("FontName",!1,t.control.settings.value)}}}),e.addButton("fontsizeselect",function(){var n=[],r="8pt 10pt 12pt 14pt 18pt 24pt 36pt",i=e.settings.fontsize_formats||r;return s(i.split(" "),function(e){n.push({text:e,value:e})}),{type:"listbox",text:"Font Sizes",tooltip:"Font Sizes",values:n,fixedWidth:!0,onPostRender:t(n,"fontsize"),onclick:function(t){t.control.settings.value&&e.execCommand("FontSize",!1,t.control.settings.value)}}}),e.addMenuItem("formats",{text:"Formats",menu:f})}var s=r.each;i.on("AddEditor",function(t){t.editor.rtl&&(e.rtl=!0),a(t.editor)}),e.translate=function(e){return i.translate(e)},t.tooltips=!o.iOS}),r(Ft,[Ct],function(e){return e.extend({recalc:function(e){var t=e.settings,n,r,i,o,a,s,l,c,u,d,f,p,h,m,g,v,y,b,C,x,w,_,N=[],E=[],S,k,T,R;for(t=e.settings,i=e.items().filter(":visible"),o=e.layoutRect(),r=t.columns||Math.ceil(Math.sqrt(i.length)),n=Math.ceil(i.length/r),y=t.spacingH||t.spacing||0,b=t.spacingV||t.spacing||0,C=t.alignH||t.align,x=t.alignV||t.align,g=e._paddingBox,C&&"string"==typeof C&&(C=[C]),x&&"string"==typeof x&&(x=[x]),d=0;r>d;d++)N.push(0);for(f=0;n>f;f++)E.push(0);for(f=0;n>f;f++)for(d=0;r>d&&(u=i[f*r+d],u);d++)c=u.layoutRect(),S=c.minW,k=c.minH,N[d]=S>N[d]?S:N[d],E[f]=k>E[f]?k:E[f];for(T=o.innerW-g.left-g.right,w=0,d=0;r>d;d++)w+=N[d]+(d>0?y:0),T-=(d>0?y:0)+N[d];for(R=o.innerH-g.top-g.bottom,_=0,f=0;n>f;f++)_+=E[f]+(f>0?b:0),R-=(f>0?b:0)+E[f];if(w+=g.left+g.right,_+=g.top+g.bottom,l={},l.minW=w+(o.w-o.innerW),l.minH=_+(o.h-o.innerH),l.contentW=l.minW-o.deltaW,l.contentH=l.minH-o.deltaH,l.minW=Math.min(l.minW,o.maxW),l.minH=Math.min(l.minH,o.maxH),l.minW=Math.max(l.minW,o.startMinWidth),l.minH=Math.max(l.minH,o.startMinHeight),!o.autoResize||l.minW==o.minW&&l.minH==o.minH){o.autoResize&&(l=e.layoutRect(l),l.contentW=l.minW-o.deltaW,l.contentH=l.minH-o.deltaH);var A;A="start"==t.packV?0:R>0?Math.floor(R/n):0;var B=0,D=t.flexWidths;if(D)for(d=0;dd;d++)N[d]+=D?D[d]*L:L;for(h=g.top,f=0;n>f;f++){for(p=g.left,s=E[f]+A,d=0;r>d&&(u=i[f*r+d],u);d++)m=u.settings,c=u.layoutRect(),a=Math.max(N[d],c.startMinWidth),c.x=p,c.y=h,v=m.alignH||(C?C[d]||C[0]:null),"center"==v?c.x=p+a/2-c.w/2:"right"==v?c.x=p+a-c.w:"stretch"==v&&(c.w=a),v=m.alignV||(x?x[d]||x[0]:null),"center"==v?c.y=h+s/2-c.h/2:"bottom"==v?c.y=h+s-c.h:"stretch"==v&&(c.h=s),u.layoutRect(c),p+=a+y,u.recalc&&u.recalc();h+=s+b}}else if(l.w=l.minW,l.h=l.minH,e.layoutRect(l),this.recalc(e),null===e._lastRect){var M=e.parent();M&&(M._lastRect=null,M.recalc())}}})}),r(zt,[wt],function(e){return e.extend({renderHtml:function(){var e=this;return e.addClass("iframe"),e.canFocus=!1,''},src:function(e){this.getEl().src=e},html:function(e,t){var n=this,r=this.getEl().contentWindow.document.body;return r?(r.innerHTML=e,t&&t()):setTimeout(function(){n.html(e)},0),this}})}),r(Wt,[wt,q],function(e,t){return e.extend({init:function(e){var t=this;t._super(e),t.addClass("widget"),t.addClass("label"),t.canFocus=!1,e.multiline&&t.addClass("autoscroll"),e.strong&&t.addClass("strong")},initLayoutRect:function(){var e=this,n=e._super();if(e.settings.multiline){var r=t.getSize(e.getEl());r.width>n.maxW&&(n.minW=n.maxW,e.addClass("multiline")),e.getEl().style.width=n.minW+"px",n.startMinH=n.h=n.minH=Math.min(n.maxH,t.getSize(e.getEl()).height)}return n},repaint:function(){var e=this;return e.settings.multiline||(e.getEl().style.lineHeight=e.layoutRect().h+"px"),e._super()},text:function(e){var t=this;return t._rendered&&e&&this.innerHtml(t.encode(e)),t._super(e)},renderHtml:function(){var e=this,t=e.settings.forId;return'"}})}),r(Vt,[G],function(e){return e.extend({Defaults:{role:"toolbar",layout:"flow"},init:function(e){var t=this;t._super(e),t.addClass("toolbar")},postRender:function(){var e=this;return e.items().addClass("toolbar-item"),e._super()}})}),r(Ut,[Vt],function(e){return e.extend({Defaults:{role:"menubar",containerCls:"menubar",ariaRoot:!0,defaults:{type:"menubutton"}}})}),r(qt,[_t,j,Ut],function(e,t,n){function r(e,t){for(;e;){if(t===e)return!0;e=e.parentNode}return!1}var i=e.extend({init:function(e){var t=this;t._renderOpen=!0,t._super(e),t.addClass("menubtn"),e.fixedWidth&&t.addClass("fixed-width"),t.aria("haspopup",!0),t.hasPopup=!0},showMenu:function(){var e=this,n=e.settings,r;return e.menu&&e.menu.visible()?e.hideMenu():(e.menu||(r=n.menu||[],r.length?r={type:"menu",items:r}:r.type=r.type||"menu",e.menu=t.create(r).parent(e).renderTo(),e.fire("createmenu"),e.menu.reflow(),e.menu.on("cancel",function(t){t.control.parent()===e.menu&&(t.stopPropagation(),e.focus(),e.hideMenu())}),e.menu.on("select",function(){e.focus()}),e.menu.on("show hide",function(t){t.control==e.menu&&e.activeMenu("show"==t.type),e.aria("expanded","show"==t.type)}).fire("show")),e.menu.show(),e.menu.layoutRect({w:e.layoutRect().w}),void e.menu.moveRel(e.getEl(),e.isRtl()?["br-tr","tr-br"]:["bl-tl","tl-bl"]))},hideMenu:function(){var e=this;e.menu&&(e.menu.items().each(function(e){e.hideMenu&&e.hideMenu()}),e.menu.hide())},activeMenu:function(e){this.toggleClass("active",e)},renderHtml:function(){var e=this,t=e._id,r=e.classPrefix,i=e.settings.icon?r+"ico "+r+"i-"+e.settings.icon:"";return e.aria("role",e.parent()instanceof n?"menuitem":"button"),'
    '},postRender:function(){var e=this;return e.on("click",function(t){t.control===e&&r(t.target,e.getEl())&&(e.showMenu(),t.aria&&e.menu.items()[0].focus())}),e.on("mouseenter",function(t){var n=t.control,r=e.parent(),o;n&&r&&n instanceof i&&n.parent()==r&&(r.items().filter("MenuButton").each(function(e){e.hideMenu&&e!=n&&(e.menu&&e.menu.visible()&&(o=!0),e.hideMenu())}),o&&(n.focus(),n.showMenu()))}),e._super()},text:function(e){var t=this,n,r;if(t._rendered)for(r=t.getEl("open").getElementsByTagName("span"),n=0;n0&&(o=n[0].text,t._value=n[0].value),e.menu=n}e.text=e.text||o||n[0].text,t._super(e),t.addClass("listbox"),t.on("select",function(n){var r=n.control;a&&(n.lastControl=a),e.multiple?r.active(!r.active()):t.value(n.control.settings.value),a=r})},value:function(e){function t(e,n){e.items().each(function(e){r=e.value()===n,r&&(i=i||e.text()),e.active(r),e.menu&&t(e.menu,n)})}var n=this,r,i,o,a;if("undefined"!=typeof e){if(n.menu)t(n.menu,e);else for(o=n.settings.menu,a=0;a'+("-"!==o?'\xa0":"")+("-"!==o?''+o+"":"")+(l?'
    '+l+"
    ":"")+(r.menu?'
    ':"")+""},postRender:function(){var e=this,t=e.settings,n=t.textStyle;if("function"==typeof n&&(n=n.call(this)),n){var r=e.getEl("text");r&&r.setAttribute("style",n)}return e.on("mouseenter click",function(n){n.control===e&&(t.menu||"click"!==n.type?(e.showMenu(),n.aria&&e.menu.focus(!0)):(e.fire("select"),e.parent().hideAll()))}),e._super(),e},active:function(e){return"undefined"!=typeof e&&this.aria("checked",e),this._super(e)},remove:function(){this._super(),this.menu&&this.menu.remove()}})}),r(Kt,[et,jt,p],function(e,t,n){var r=e.extend({Defaults:{defaultType:"menuitem",border:1,layout:"stack",role:"application",bodyRole:"menu",ariaRoot:!0},init:function(e){var t=this;if(e.autohide=!0,e.constrainToViewport=!0,e.itemDefaults)for(var r=e.items,i=r.length;i--;)r[i]=n.extend({},e.itemDefaults,r[i]);t._super(e),t.addClass("menu")},repaint:function(){return this.toggleClass("menu-align",!0),this._super(),this.getEl().style.height="",this.getEl("body").style.height="",this},cancel:function(){var e=this;e.hideAll(),e.fire("select")},hideAll:function(){var e=this;return this.find("menuitem").exec("hideMenu"),e._super()},preRender:function(){var e=this;return e.items().each(function(t){var n=t.settings;return n.icon||n.selectable?(e._hasIcons=!0,!1):void 0}),e._super()}});return r}),r(Gt,[Et],function(e){return e.extend({Defaults:{classes:"radio",role:"radio"}})}),r(Yt,[wt,Y],function(e,t){return e.extend({renderHtml:function(){var e=this,t=e.classPrefix;return e.addClass("resizehandle"),"both"==e.settings.direction&&e.addClass("resizehandle-both"),e.canFocus=!1,'
    '},postRender:function(){var e=this;e._super(),e.resizeDragHelper=new t(this._id,{start:function(){e.fire("ResizeStart")},drag:function(t){"both"!=e.settings.direction&&(t.deltaX=0),e.fire("Resize",t)},stop:function(){e.fire("ResizeEnd")}})},remove:function(){return this.resizeDragHelper&&this.resizeDragHelper.destroy(),this._super()}})}),r(Xt,[wt],function(e){return e.extend({renderHtml:function(){var e=this;return e.addClass("spacer"),e.canFocus=!1,'
    '}})}),r(Jt,[qt,q],function(e,t){return e.extend({Defaults:{classes:"widget btn splitbtn",role:"button"},repaint:function(){var e=this,n=e.getEl(),r=e.layoutRect(),i,o;return e._super(),i=n.firstChild,o=n.lastChild,t.css(i,{width:r.w-t.getSize(o).width,height:r.h-2}),t.css(o,{height:r.h-2}),e},activeMenu:function(e){var n=this;t.toggleClass(n.getEl().lastChild,n.classPrefix+"active",e)},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.settings.icon?n+"ico "+n+"i-"+e.settings.icon:"";return'
    '},postRender:function(){var e=this,t=e.settings.onclick;return e.on("click",function(e){var n=e.target;if(e.control==this)for(;n;){if(e.aria&&"down"!=e.aria.key||"BUTTON"==n.nodeName&&-1==n.className.indexOf("open"))return e.stopImmediatePropagation(),void t.call(this,e);n=n.parentNode}}),delete e.settings.onclick,e._super()}})}),r(Qt,[Ot],function(e){return e.extend({Defaults:{containerClass:"stack-layout",controlClass:"stack-layout-item",endClass:"break"}})}),r(Zt,[J,q],function(e,t){return e.extend({lastIdx:0,Defaults:{layout:"absolute",defaults:{type:"panel"}},activateTab:function(e){var n;this.activeTabId&&(n=this.getEl(this.activeTabId),t.removeClass(n,this.classPrefix+"active"),n.setAttribute("aria-selected","false")),this.activeTabId="t"+e,n=this.getEl("t"+e),n.setAttribute("aria-selected","true"),t.addClass(n,this.classPrefix+"active"),e!=this.lastIdx&&(this.items()[this.lastIdx].hide(),this.lastIdx=e),this.items()[e].show().fire("showtab"),this.reflow()},renderHtml:function(){var e=this,t=e._layout,n="",r=e.classPrefix;return e.preRender(),t.preRender(e),e.items().each(function(t,i){var o=e._id+"-t"+i;t.aria("role","tabpanel"),t.aria("labelledby",o),n+='"}),'
    '+n+'
    '+t.renderHtml(e)+"
    "},postRender:function(){var e=this;e._super(),e.settings.activeTab=e.settings.activeTab||0,e.activateTab(e.settings.activeTab),this.on("click",function(t){var n=t.target.parentNode;if(t.target.parentNode.id==e._id+"-head")for(var r=n.childNodes.length;r--;)n.childNodes[r]==t.target&&e.activateTab(r)})},initLayoutRect:function(){var e=this,n,r,i;r=t.getSize(e.getEl("head")).width,r=0>r?0:r,i=0,e.items().each(function(t,n){r=Math.max(r,t.layoutRect().minW),i=Math.max(i,t.layoutRect().minH),e.settings.activeTab!=n&&t.hide()}),e.items().each(function(e){e.settings.x=0,e.settings.y=0,e.settings.w=r,e.settings.h=i,e.layoutRect({x:0,y:0,w:r,h:i})});var o=t.getSize(e.getEl("head")).height;return e.settings.minWidth=r,e.settings.minHeight=i+o,n=e._super(),n.deltaH+=o,n.innerH=n.h-n.deltaH,n}})}),r(en,[wt,q],function(e,t){return e.extend({init:function(e){var t=this;t._super(e),t._value=e.value||"",t.addClass("textbox"),e.multiline?t.addClass("multiline"):t.on("keydown",function(e){13==e.keyCode&&t.parents().reverse().each(function(t){return e.preventDefault(),t.hasEventListeners("submit")&&t.toJSON?(t.fire("submit",{data:t.toJSON()}),!1):void 0})})},disabled:function(e){var t=this;return t._rendered&&"undefined"!=typeof e&&(t.getEl().disabled=e),t._super(e)},value:function(e){var t=this;return"undefined"!=typeof e?(t._value=e,t._rendered&&(t.getEl().value=e),t):t._rendered?t.getEl().value:t._value},repaint:function(){var e=this,t,n,r,i=0,o=0,a;t=e.getEl().style,n=e._layoutRect,a=e._lastRepaintRect||{};var s=document;return!e.settings.multiline&&s.all&&(!s.documentMode||s.documentMode<=8)&&(t.lineHeight=n.h-o+"px"),r=e._borderBox,i=r.left+r.right+8,o=r.top+r.bottom+(e.settings.multiline?8:0),n.x!==a.x&&(t.left=n.x+"px",a.x=n.x),n.y!==a.y&&(t.top=n.y+"px",a.y=n.y),n.w!==a.w&&(t.width=n.w-i+"px",a.w=n.w),n.h!==a.h&&(t.height=n.h-o+"px",a.h=n.h),e._lastRepaintRect=a,e.fire("repaint",{},!1),e},renderHtml:function(){var e=this,t=e._id,n=e.settings,r=e.encode(e._value,!1),i="";return"spellcheck"in n&&(i+=' spellcheck="'+n.spellcheck+'"'),n.maxLength&&(i+=' maxlength="'+n.maxLength+'"'),n.size&&(i+=' size="'+n.size+'"'),n.subtype&&(i+=' type="'+n.subtype+'"'),e.disabled()&&(i+=' disabled="disabled"'),n.multiline?'":'"},postRender:function(){var e=this;return t.on(e.getEl(),"change",function(t){e.fire("change",t)}),e._super()},remove:function(){t.off(this.getEl()),this._super()}})}),r(tn,[q,$],function(e,t){return function(n,r){var i=this,o,a=t.classPrefix;i.show=function(t){return i.hide(),o=!0,window.setTimeout(function(){o&&n.appendChild(e.createFragment('
    '))},t||0),i},i.hide=function(){var e=n.lastChild;return e&&-1!=e.className.indexOf("throbber")&&e.parentNode.removeChild(e),o=!1,i}}}),a([l,c,u,d,f,p,h,m,g,v,y,b,C,x,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O,I,F,z,W,V,U,q,$,j,K,G,Y,X,J,Q,Z,et,tt,nt,rt,it,ot,at,st,lt,ct,ut,dt,ft,pt,ht,mt,gt,vt,yt,bt,Ct,xt,wt,_t,Nt,Et,St,kt,Tt,Rt,At,Bt,Dt,Lt,Mt,Ht,Pt,Ot,It,Ft,zt,Wt,Vt,Ut,qt,$t,jt,Kt,Gt,Yt,Xt,Jt,Qt,Zt,en,tn])}(this);tinymce.PluginManager.add("advlist",function(t){function e(t,e){var n=[];return tinymce.each(e.split(/[ ,]/),function(t){n.push({text:t.replace(/\-/g," ").replace(/\b\w/g,function(t){return t.toUpperCase()}),data:"default"==t?"":t})}),n}function n(e,n){var o,l=t.dom,a=t.selection;o=l.getParent(a.getNode(),"ol,ul"),o&&o.nodeName==e&&n!==!1||t.execCommand("UL"==e?"InsertUnorderedList":"InsertOrderedList"),n=n===!1?i[e]:n,i[e]=n,o=l.getParent(a.getNode(),"ol,ul"),o&&(l.setStyle(o,"listStyleType",n),o.removeAttribute("data-mce-style")),t.focus()}function o(e){var n=t.dom.getStyle(t.dom.getParent(t.selection.getNode(),"ol,ul"),"listStyleType")||"";e.control.items().each(function(t){t.active(t.settings.data===n)})}var l,a,i={};l=e("OL",t.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman")),a=e("UL",t.getParam("advlist_bullet_styles","default,circle,disc,square")),t.addButton("numlist",{type:"splitbutton",tooltip:"Numbered list",menu:l,onshow:o,onselect:function(t){n("OL",t.control.settings.data)},onclick:function(){n("OL",!1)}}),t.addButton("bullist",{type:"splitbutton",tooltip:"Bullet list",menu:a,onshow:o,onselect:function(t){n("UL",t.control.settings.data)},onclick:function(){n("UL",!1)}})});tinymce.PluginManager.add("anchor",function(n){function e(){var e=n.selection.getNode();n.windowManager.open({title:"Anchor",body:{type:"textbox",name:"name",size:40,label:"Name",value:e.name||e.id},onsubmit:function(e){n.execCommand("mceInsertContent",!1,n.dom.createHTML("a",{id:e.data.name}))}})}n.addButton("anchor",{icon:"anchor",tooltip:"Anchor",onclick:e,stateSelector:"a:not([href])"}),n.addMenuItem("anchor",{icon:"anchor",text:"Anchor",context:"insert",onclick:e})});tinymce.PluginManager.add("autolink",function(t){function n(t){o(t,-1,"(",!0)}function e(t){o(t,0,"",!0)}function i(t){o(t,-1,"",!1)}function o(t,n,e){function i(t,n){if(0>n&&(n=0),3==t.nodeType){var e=t.data.length;n>e&&(n=e)}return n}function o(t,n){f.setStart(t,i(t,n))}function r(t,n){f.setEnd(t,i(t,n))}var f,d,a,s,c,l,u,g,h;if(f=t.selection.getRng(!0).cloneRange(),f.startOffset<5){if(g=f.endContainer.previousSibling,!g){if(!f.endContainer.firstChild||!f.endContainer.firstChild.nextSibling)return;g=f.endContainer.firstChild.nextSibling}if(h=g.length,o(g,h),r(g,h),f.endOffset<5)return;d=f.endOffset,s=g}else{if(s=f.endContainer,3!=s.nodeType&&s.firstChild){for(;3!=s.nodeType&&s.firstChild;)s=s.firstChild;3==s.nodeType&&(o(s,0),r(s,s.nodeValue.length))}d=1==f.endOffset?2:f.endOffset-1-n}a=d;do o(s,d>=2?d-2:0),r(s,d>=1?d-1:0),d-=1;while(" "!=f.toString()&&""!==f.toString()&&160!=f.toString().charCodeAt(0)&&d-2>=0&&f.toString()!=e);f.toString()==e||160==f.toString().charCodeAt(0)?(o(s,d),r(s,a),d+=1):0===f.startOffset?(o(s,0),r(s,a)):(o(s,d),r(s,a)),l=f.toString(),"."==l.charAt(l.length-1)&&r(s,a-1),l=f.toString(),u=l.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i),u&&("www."==u[1]?u[1]="http://www.":/@$/.test(u[1])&&!/^mailto:/.test(u[1])&&(u[1]="mailto:"+u[1]),c=t.selection.getBookmark(),t.selection.setRng(f),t.execCommand("createlink",!1,u[1]+u[2]),t.selection.moveToBookmark(c),t.nodeChanged())}var r;return t.on("keydown",function(n){return 13==n.keyCode?i(t):void 0}),tinymce.Env.ie?void t.on("focus",function(){if(!r){r=!0;try{t.execCommand("AutoUrlDetect",!1,!0)}catch(n){}}}):(t.on("keypress",function(e){return 41==e.keyCode?n(t):void 0}),void t.on("keyup",function(n){return 32==n.keyCode?e(t):void 0}))});tinymce.PluginManager.add("autoresize",function(e){function t(){return e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen()}function i(n){var s,r,g,u,l,m,h,d,f=tinymce.DOM;if(r=e.getDoc()){if(g=r.body,u=r.documentElement,l=o.autoresize_min_height,!g||n&&"setcontent"===n.type&&n.initial||t())return void(g&&u&&(g.style.overflowY="auto",u.style.overflowY="auto"));h=e.dom.getStyle(g,"margin-top",!0),d=e.dom.getStyle(g,"margin-bottom",!0),m=g.offsetHeight+parseInt(h,10)+parseInt(d,10),(isNaN(m)||0>=m)&&(m=tinymce.Env.ie?g.scrollHeight:tinymce.Env.webkit&&0===g.clientHeight?0:g.offsetHeight),m>o.autoresize_min_height&&(l=m),o.autoresize_max_height&&m>o.autoresize_max_height?(l=o.autoresize_max_height,g.style.overflowY="auto",u.style.overflowY="auto"):(g.style.overflowY="hidden",u.style.overflowY="hidden",g.scrollTop=0),l!==a&&(s=l-a,f.setStyle(f.get(e.id+"_ifr"),"height",l+"px"),a=l,tinymce.isWebKit&&0>s&&i(n))}}function n(e,t,o){setTimeout(function(){i({}),e--?n(e,t,o):o&&o()},t)}var o=e.settings,a=0;e.settings.inline||(o.autoresize_min_height=parseInt(e.getParam("autoresize_min_height",e.getElement().offsetHeight),10),o.autoresize_max_height=parseInt(e.getParam("autoresize_max_height",0),10),e.on("init",function(){var t=e.getParam("autoresize_overflow_padding",1);e.dom.setStyles(e.getBody(),{paddingBottom:e.getParam("autoresize_bottom_margin",50),paddingLeft:t,paddingRight:t})}),e.on("nodechange setcontent keyup FullscreenStateChanged",i),e.getParam("autoresize_on_init",!0)&&e.on("init",function(){n(20,100,function(){n(5,1e3)})}),e.addCommand("mceAutoResize",i))});tinymce.PluginManager.add("autosave",function(e){function t(e,t){var n={s:1e3,m:6e4};return e=/^(\d+)([ms]?)$/.exec(""+(e||t)),(e[2]?n[e[2]]:1)*parseInt(e,10)}function n(){var e=parseInt(l.getItem(d+"time"),10)||0;return(new Date).getTime()-e>v.autosave_retention?(a(!1),!1):!0}function a(t){l.removeItem(d+"draft"),l.removeItem(d+"time"),t!==!1&&e.fire("RemoveDraft")}function r(){!c()&&e.isDirty()&&(l.setItem(d+"draft",e.getContent({format:"raw",no_events:!0})),l.setItem(d+"time",(new Date).getTime()),e.fire("StoreDraft"))}function o(){n()&&(e.setContent(l.getItem(d+"draft"),{format:"raw"}),e.fire("RestoreDraft"))}function i(){m||(setInterval(function(){e.removed||r()},v.autosave_interval),m=!0)}function s(){var t=this;t.disabled(!n()),e.on("StoreDraft RestoreDraft RemoveDraft",function(){t.disabled(!n())}),i()}function u(){e.undoManager.beforeChange(),o(),a(),e.undoManager.add()}function f(){var e;return tinymce.each(tinymce.editors,function(t){t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&t.getParam("autosave_ask_before_unload",!0)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))}),e}function c(t){var n=e.settings.forced_root_block;return t=tinymce.trim("undefined"==typeof t?e.getBody().innerHTML:t),""===t||new RegExp("^<"+n+"[^>]*>(( | |[ ]|]*>)+?|)|
    $","i").test(t)}var d,m,v=e.settings,l=tinymce.util.LocalStorage;d=v.autosave_prefix||"tinymce-autosave-{path}{query}-{id}-",d=d.replace(/\{path\}/g,document.location.pathname),d=d.replace(/\{query\}/g,document.location.search),d=d.replace(/\{id\}/g,e.id),v.autosave_interval=t(v.autosave_interval,"30s"),v.autosave_retention=t(v.autosave_retention,"20m"),e.addButton("restoredraft",{title:"Restore last draft",onclick:u,onPostRender:s}),e.addMenuItem("restoredraft",{text:"Restore last draft",onclick:u,onPostRender:s,context:"file"}),e.settings.autosave_restore_when_empty!==!1&&(e.on("init",function(){n()&&c()&&o()}),e.on("saveContent",function(){a()})),window.onbeforeunload=f,this.hasDraft=n,this.storeDraft=r,this.restoreDraft=o,this.removeDraft=a,this.isEmpty=c});!function(){tinymce.create("tinymce.plugins.BBCodePlugin",{init:function(o){var e=this,t=o.getParam("bbcode_dialect","punbb").toLowerCase();o.on("beforeSetContent",function(o){o.content=e["_"+t+"_bbcode2html"](o.content)}),o.on("postProcess",function(o){o.set&&(o.content=e["_"+t+"_bbcode2html"](o.content)),o.get&&(o.content=e["_"+t+"_html2bbcode"](o.content))})},getInfo:function(){return{longname:"BBCode Plugin",author:"Moxiecode Systems AB",authorurl:"http://www.tinymce.com",infourl:"http://www.tinymce.com/wiki.php/Plugin:bbcode"}},_punbb_html2bbcode:function(o){function e(e,t){o=o.replace(e,t)}return o=tinymce.trim(o),e(/(.*?)<\/a>/gi,"[url=$1]$2[/url]"),e(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),e(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),e(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),e(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),e(/(.*?)<\/span>/gi,"[color=$1]$2[/color]"),e(/(.*?)<\/font>/gi,"[color=$1]$2[/color]"),e(/(.*?)<\/span>/gi,"[size=$1]$2[/size]"),e(/(.*?)<\/font>/gi,"$1"),e(//gi,"[img]$1[/img]"),e(/(.*?)<\/span>/gi,"[code]$1[/code]"),e(/(.*?)<\/span>/gi,"[quote]$1[/quote]"),e(/(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"),e(/(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"),e(/(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"),e(/(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"),e(/(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"),e(/(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"),e(/<\/(strong|b)>/gi,"[/b]"),e(/<(strong|b)>/gi,"[b]"),e(/<\/(em|i)>/gi,"[/i]"),e(/<(em|i)>/gi,"[i]"),e(/<\/u>/gi,"[/u]"),e(/(.*?)<\/span>/gi,"[u]$1[/u]"),e(//gi,"[u]"),e(/]*>/gi,"[quote]"),e(/<\/blockquote>/gi,"[/quote]"),e(/
    /gi,"\n"),e(//gi,"\n"),e(/
    /gi,"\n"),e(/

    /gi,""),e(/<\/p>/gi,"\n"),e(/ |\u00a0/gi," "),e(/"/gi,'"'),e(/</gi,"<"),e(/>/gi,">"),e(/&/gi,"&"),o},_punbb_bbcode2html:function(o){function e(e,t){o=o.replace(e,t)}return o=tinymce.trim(o),e(/\n/gi,"
    "),e(/\[b\]/gi,""),e(/\[\/b\]/gi,""),e(/\[i\]/gi,""),e(/\[\/i\]/gi,""),e(/\[u\]/gi,""),e(/\[\/u\]/gi,""),e(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'$2'),e(/\[url\](.*?)\[\/url\]/gi,'$1'),e(/\[img\](.*?)\[\/img\]/gi,''),e(/\[color=(.*?)\](.*?)\[\/color\]/gi,'$2'),e(/\[code\](.*?)\[\/code\]/gi,'$1 '),e(/\[quote.*?\](.*?)\[\/quote\]/gi,'$1 '),o}}),tinymce.PluginManager.add("bbcode",tinymce.plugins.BBCodePlugin)}();tinymce.PluginManager.add("charmap",function(e){function a(){function a(e){for(;e;){if("TD"==e.nodeName)return e;e=e.parentNode}}var t,r,o,n;t='';var l=25;for(o=0;10>o;o++){for(t+="",r=0;l>r;r++){var s=i[o*l+r];t+='"}t+=""}t+="";var c={type:"container",html:t,onclick:function(a){var i=a.target;"TD"==i.tagName&&(i=i.firstChild),"DIV"==i.tagName&&(e.execCommand("mceInsertContent",!1,i.firstChild.data),a.ctrlKey||n.close())},onmouseover:function(e){var i=a(e.target);i&&n.find("#preview").text(i.firstChild.firstChild.data)}};n=e.windowManager.open({title:"Special character",spacing:10,padding:10,items:[c,{type:"label",name:"preview",text:" ",style:"font-size: 40px; text-align: center",border:1,minWidth:100,minHeight:80}],buttons:[{text:"Close",onclick:function(){n.close()}}]})}var i=[["160","no-break space"],["38","ampersand"],["34","quotation mark"],["162","cent sign"],["8364","euro sign"],["163","pound sign"],["165","yen sign"],["169","copyright sign"],["174","registered sign"],["8482","trade mark sign"],["8240","per mille sign"],["181","micro sign"],["183","middle dot"],["8226","bullet"],["8230","three dot leader"],["8242","minutes / feet"],["8243","seconds / inches"],["167","section sign"],["182","paragraph sign"],["223","sharp s / ess-zed"],["8249","single left-pointing angle quotation mark"],["8250","single right-pointing angle quotation mark"],["171","left pointing guillemet"],["187","right pointing guillemet"],["8216","left single quotation mark"],["8217","right single quotation mark"],["8220","left double quotation mark"],["8221","right double quotation mark"],["8218","single low-9 quotation mark"],["8222","double low-9 quotation mark"],["60","less-than sign"],["62","greater-than sign"],["8804","less-than or equal to"],["8805","greater-than or equal to"],["8211","en dash"],["8212","em dash"],["175","macron"],["8254","overline"],["164","currency sign"],["166","broken bar"],["168","diaeresis"],["161","inverted exclamation mark"],["191","turned question mark"],["710","circumflex accent"],["732","small tilde"],["176","degree sign"],["8722","minus sign"],["177","plus-minus sign"],["247","division sign"],["8260","fraction slash"],["215","multiplication sign"],["185","superscript one"],["178","superscript two"],["179","superscript three"],["188","fraction one quarter"],["189","fraction one half"],["190","fraction three quarters"],["402","function / florin"],["8747","integral"],["8721","n-ary sumation"],["8734","infinity"],["8730","square root"],["8764","similar to"],["8773","approximately equal to"],["8776","almost equal to"],["8800","not equal to"],["8801","identical to"],["8712","element of"],["8713","not an element of"],["8715","contains as member"],["8719","n-ary product"],["8743","logical and"],["8744","logical or"],["172","not sign"],["8745","intersection"],["8746","union"],["8706","partial differential"],["8704","for all"],["8707","there exists"],["8709","diameter"],["8711","backward difference"],["8727","asterisk operator"],["8733","proportional to"],["8736","angle"],["180","acute accent"],["184","cedilla"],["170","feminine ordinal indicator"],["186","masculine ordinal indicator"],["8224","dagger"],["8225","double dagger"],["192","A - grave"],["193","A - acute"],["194","A - circumflex"],["195","A - tilde"],["196","A - diaeresis"],["197","A - ring above"],["198","ligature AE"],["199","C - cedilla"],["200","E - grave"],["201","E - acute"],["202","E - circumflex"],["203","E - diaeresis"],["204","I - grave"],["205","I - acute"],["206","I - circumflex"],["207","I - diaeresis"],["208","ETH"],["209","N - tilde"],["210","O - grave"],["211","O - acute"],["212","O - circumflex"],["213","O - tilde"],["214","O - diaeresis"],["216","O - slash"],["338","ligature OE"],["352","S - caron"],["217","U - grave"],["218","U - acute"],["219","U - circumflex"],["220","U - diaeresis"],["221","Y - acute"],["376","Y - diaeresis"],["222","THORN"],["224","a - grave"],["225","a - acute"],["226","a - circumflex"],["227","a - tilde"],["228","a - diaeresis"],["229","a - ring above"],["230","ligature ae"],["231","c - cedilla"],["232","e - grave"],["233","e - acute"],["234","e - circumflex"],["235","e - diaeresis"],["236","i - grave"],["237","i - acute"],["238","i - circumflex"],["239","i - diaeresis"],["240","eth"],["241","n - tilde"],["242","o - grave"],["243","o - acute"],["244","o - circumflex"],["245","o - tilde"],["246","o - diaeresis"],["248","o slash"],["339","ligature oe"],["353","s - caron"],["249","u - grave"],["250","u - acute"],["251","u - circumflex"],["252","u - diaeresis"],["253","y - acute"],["254","thorn"],["255","y - diaeresis"],["913","Alpha"],["914","Beta"],["915","Gamma"],["916","Delta"],["917","Epsilon"],["918","Zeta"],["919","Eta"],["920","Theta"],["921","Iota"],["922","Kappa"],["923","Lambda"],["924","Mu"],["925","Nu"],["926","Xi"],["927","Omicron"],["928","Pi"],["929","Rho"],["931","Sigma"],["932","Tau"],["933","Upsilon"],["934","Phi"],["935","Chi"],["936","Psi"],["937","Omega"],["945","alpha"],["946","beta"],["947","gamma"],["948","delta"],["949","epsilon"],["950","zeta"],["951","eta"],["952","theta"],["953","iota"],["954","kappa"],["955","lambda"],["956","mu"],["957","nu"],["958","xi"],["959","omicron"],["960","pi"],["961","rho"],["962","final sigma"],["963","sigma"],["964","tau"],["965","upsilon"],["966","phi"],["967","chi"],["968","psi"],["969","omega"],["8501","alef symbol"],["982","pi symbol"],["8476","real part symbol"],["978","upsilon - hook symbol"],["8472","Weierstrass p"],["8465","imaginary part"],["8592","leftwards arrow"],["8593","upwards arrow"],["8594","rightwards arrow"],["8595","downwards arrow"],["8596","left right arrow"],["8629","carriage return"],["8656","leftwards double arrow"],["8657","upwards double arrow"],["8658","rightwards double arrow"],["8659","downwards double arrow"],["8660","left right double arrow"],["8756","therefore"],["8834","subset of"],["8835","superset of"],["8836","not a subset of"],["8838","subset of or equal to"],["8839","superset of or equal to"],["8853","circled plus"],["8855","circled times"],["8869","perpendicular"],["8901","dot operator"],["8968","left ceiling"],["8969","right ceiling"],["8970","left floor"],["8971","right floor"],["9001","left-pointing angle bracket"],["9002","right-pointing angle bracket"],["9674","lozenge"],["9824","black spade suit"],["9827","black club suit"],["9829","black heart suit"],["9830","black diamond suit"],["8194","en space"],["8195","em space"],["8201","thin space"],["8204","zero width non-joiner"],["8205","zero width joiner"],["8206","left-to-right mark"],["8207","right-to-left mark"],["173","soft hyphen"]];e.addButton("charmap",{icon:"charmap",tooltip:"Special character",onclick:a}),e.addMenuItem("charmap",{icon:"charmap",text:"Special character",onclick:a,context:"insert"})});tinymce.PluginManager.add("code",function(e){function o(){e.windowManager.open({title:"Source code",body:{type:"textbox",name:"code",multiline:!0,minWidth:e.getParam("code_dialog_width",600),minHeight:e.getParam("code_dialog_height",Math.min(tinymce.DOM.getViewPort().h-200,500)),value:e.getContent({source_view:!0}),spellcheck:!1,style:"direction: ltr; text-align: left"},onSubmit:function(o){e.focus(),e.undoManager.transact(function(){e.setContent(o.data.code)}),e.selection.setCursorLocation(),e.nodeChanged()}})}e.addCommand("mceCodeEditor",o),e.addButton("code",{icon:"code",tooltip:"Source code",onclick:o}),e.addMenuItem("code",{icon:"code",text:"Source code",context:"tools",onclick:o})});tinymce.PluginManager.add("contextmenu",function(e){var n,t=e.settings.contextmenu_never_use_native;e.on("contextmenu",function(i){var o;if(!i.ctrlKey||t){if(i.preventDefault(),o=e.settings.contextmenu||"link image inserttable | cell row column deletetable",n)n.show();else{var c=[];tinymce.each(o.split(/[ ,]/),function(n){var t=e.menuItems[n];"|"==n&&(t={text:n}),t&&(t.shortcut="",c.push(t))});for(var a=0;a'}),t+=""}),t+=""}var i=[["cool","cry","embarassed","foot-in-mouth"],["frown","innocent","kiss","laughing"],["money-mouth","sealed","smile","surprised"],["tongue-out","undecided","wink","yell"]];t.addButton("emoticons",{type:"panelbutton",panel:{role:"application",autohide:!0,html:a,onclick:function(e){var a=t.dom.getParent(e.target,"a");a&&(t.insertContent(''+a.getAttribute('),this.hide())}},tooltip:"Emoticons"})});tinymce.PluginManager.add("fullpage",function(e){function t(){var t=n();e.windowManager.open({title:"Document properties",data:t,defaults:{type:"textbox",size:40},body:[{name:"title",label:"Title"},{name:"keywords",label:"Keywords"},{name:"description",label:"Description"},{name:"robots",label:"Robots"},{name:"author",label:"Author"},{name:"docencoding",label:"Encoding"}],onSubmit:function(e){l(tinymce.extend(t,e.data))}})}function n(){function t(e,t){var n=e.attr(t);return n||""}var n,l,a=i(),r={};return r.fontface=e.getParam("fullpage_default_fontface",""),r.fontsize=e.getParam("fullpage_default_fontsize",""),n=a.firstChild,7==n.type&&(r.xml_pi=!0,l=/encoding="([^"]+)"/.exec(n.value),l&&(r.docencoding=l[1])),n=a.getAll("#doctype")[0],n&&(r.doctype=""),n=a.getAll("title")[0],n&&n.firstChild&&(r.title=n.firstChild.value),s(a.getAll("meta"),function(e){var t,n=e.attr("name"),l=e.attr("http-equiv");n?r[n.toLowerCase()]=e.attr("content"):"Content-Type"==l&&(t=/charset\s*=\s*(.*)\s*/gi.exec(e.attr("content")),t&&(r.docencoding=t[1]))}),n=a.getAll("html")[0],n&&(r.langcode=t(n,"lang")||t(n,"xml:lang")),r.stylesheets=[],tinymce.each(a.getAll("link"),function(e){"stylesheet"==e.attr("rel")&&r.stylesheets.push(e.attr("href"))}),n=a.getAll("body")[0],n&&(r.langdir=t(n,"dir"),r.style=t(n,"style"),r.visited_color=t(n,"vlink"),r.link_color=t(n,"link"),r.active_color=t(n,"alink")),r}function l(t){function n(e,t,n){e.attr(t,n?n:void 0)}function l(e){r.firstChild?r.insert(e,r.firstChild):r.append(e)}var a,r,o,c,u,f=e.dom;a=i(),r=a.getAll("head")[0],r||(c=a.getAll("html")[0],r=new m("head",1),c.firstChild?c.insert(r,c.firstChild,!0):c.append(r)),c=a.firstChild,t.xml_pi?(u='version="1.0"',t.docencoding&&(u+=' encoding="'+t.docencoding+'"'),7!=c.type&&(c=new m("xml",7),a.insert(c,a.firstChild,!0)),c.value=u):c&&7==c.type&&c.remove(),c=a.getAll("#doctype")[0],t.doctype?(c||(c=new m("#doctype",10),t.xml_pi?a.insert(c,a.firstChild):l(c)),c.value=t.doctype.substring(9,t.doctype.length-1)):c&&c.remove(),c=null,s(a.getAll("meta"),function(e){"Content-Type"==e.attr("http-equiv")&&(c=e)}),t.docencoding?(c||(c=new m("meta",1),c.attr("http-equiv","Content-Type"),c.shortEnded=!0,l(c)),c.attr("content","text/html; charset="+t.docencoding)):c.remove(),c=a.getAll("title")[0],t.title?(c?c.empty():(c=new m("title",1),l(c)),c.append(new m("#text",3)).value=t.title):c&&c.remove(),s("keywords,description,author,copyright,robots".split(","),function(e){var n,i,r=a.getAll("meta"),o=t[e];for(n=0;n"))}function i(){return new tinymce.html.DomParser({validate:!1,root_name:"#document"}).parse(d)}function a(t){function n(e){return e.replace(/<\/?[A-Z]+/g,function(e){return e.toLowerCase()})}var l,a,o,m,u=t.content,f="",g=e.dom;if(!t.selection&&!("raw"==t.format&&d||t.source_view&&e.getParam("fullpage_hide_in_source_view"))){u=u.replace(/<(\/?)BODY/gi,"<$1body"),l=u.indexOf("",l),d=n(u.substring(0,l+1)),a=u.indexOf("\n"),o=i(),s(o.getAll("style"),function(e){e.firstChild&&(f+=e.firstChild.value)}),m=o.getAll("body")[0],m&&g.setAttribs(e.getBody(),{style:m.attr("style")||"",dir:m.attr("dir")||"",vLink:m.attr("vlink")||"",link:m.attr("link")||"",aLink:m.attr("alink")||""}),g.remove("fullpage_styles");var y=e.getDoc().getElementsByTagName("head")[0];f&&(g.add(y,"style",{id:"fullpage_styles"},f),m=g.get("fullpage_styles"),m.styleSheet&&(m.styleSheet.cssText=f));var h={};tinymce.each(y.getElementsByTagName("link"),function(e){"stylesheet"==e.rel&&e.getAttribute("data-mce-fullpage")&&(h[e.href]=e)}),tinymce.each(o.getAll("link"),function(e){var t=e.attr("href");h[t]||"stylesheet"!=e.attr("rel")||g.add(y,"link",{rel:"stylesheet",text:"text/css",href:t,"data-mce-fullpage":"1"}),delete h[t]}),tinymce.each(h,function(e){e.parentNode.removeChild(e)})}}function r(){var t,n="",l="";return e.getParam("fullpage_default_xml_pi")&&(n+='\n'),n+=e.getParam("fullpage_default_doctype",""),n+="\n\n\n",(t=e.getParam("fullpage_default_title"))&&(n+=""+t+"\n"),(t=e.getParam("fullpage_default_encoding"))&&(n+='\n'),(t=e.getParam("fullpage_default_font_family"))&&(l+="font-family: "+t+";"),(t=e.getParam("fullpage_default_font_size"))&&(l+="font-size: "+t+";"),(t=e.getParam("fullpage_default_text_color"))&&(l+="color: "+t+";"),n+="\n\n"}function o(t){t.selection||t.source_view&&e.getParam("fullpage_hide_in_source_view")||(t.content=tinymce.trim(d)+"\n"+tinymce.trim(t.content)+"\n"+tinymce.trim(c))}var d,c,s=tinymce.each,m=tinymce.html.Node;e.addCommand("mceFullPageProperties",t),e.addButton("fullpage",{title:"Document properties",cmd:"mceFullPageProperties"}),e.addMenuItem("fullpage",{text:"Document properties",cmd:"mceFullPageProperties",context:"file"}),e.on("BeforeSetContent",a),e.on("GetContent",o)});tinymce.PluginManager.add("fullscreen",function(e){function t(){var e,t,n=window,i=document,l=i.body;return l.offsetWidth&&(e=l.offsetWidth,t=l.offsetHeight),n.innerWidth&&n.innerHeight&&(e=n.innerWidth,t=n.innerHeight),{w:e,h:t}}function n(){function n(){d.setStyle(a,"height",t().h-(h.clientHeight-a.clientHeight))}var u,h,a,f,m=document.body,g=document.documentElement;s=!s,h=e.getContainer(),u=h.style,a=e.getContentAreaContainer().firstChild,f=a.style,s?(i=f.width,l=f.height,f.width=f.height="100%",c=u.width,o=u.height,u.width=u.height="",d.addClass(m,"mce-fullscreen"),d.addClass(g,"mce-fullscreen"),d.addClass(h,"mce-fullscreen"),d.bind(window,"resize",n),n(),r=n):(f.width=i,f.height=l,c&&(u.width=c),o&&(u.height=o),d.removeClass(m,"mce-fullscreen"),d.removeClass(g,"mce-fullscreen"),d.removeClass(h,"mce-fullscreen"),d.unbind(window,"resize",r)),e.fire("FullscreenStateChanged",{state:s})}var i,l,r,c,o,s=!1,d=tinymce.DOM;return e.settings.inline?void 0:(e.on("init",function(){e.addShortcut("Ctrl+Alt+F","",n)}),e.on("remove",function(){r&&d.unbind(window,"resize",r)}),e.addCommand("mceFullScreen",n),e.addMenuItem("fullscreen",{text:"Fullscreen",shortcut:"Ctrl+Alt+F",selectable:!0,onClick:n,onPostRender:function(){var t=this;e.on("FullscreenStateChanged",function(e){t.active(e.state)})},context:"view"}),e.addButton("fullscreen",{tooltip:"Fullscreen",shortcut:"Ctrl+Alt+F",onClick:n,onPostRender:function(){var t=this;e.on("FullscreenStateChanged",function(e){t.active(e.state)})}}),{isFullscreen:function(){return s}})});tinymce.PluginManager.add("hr",function(n){n.addCommand("InsertHorizontalRule",function(){n.execCommand("mceInsertContent",!1,"


    ")}),n.addButton("hr",{icon:"hr",tooltip:"Horizontal line",cmd:"InsertHorizontalRule"}),n.addMenuItem("hr",{icon:"hr",text:"Horizontal line",cmd:"InsertHorizontalRule",context:"insert"})});tinymce.PluginManager.add("image",function(e){function t(e,t){function i(e,i){n.parentNode&&n.parentNode.removeChild(n),t({width:e,height:i})}var n=document.createElement("img");n.onload=function(){i(n.clientWidth,n.clientHeight)},n.onerror=function(){i()};var a=n.style;a.visibility="hidden",a.position="fixed",a.bottom=a.left=0,a.width=a.height="auto",document.body.appendChild(n),n.src=e}function i(t){return tinymce.each(t,function(t){t.textStyle=function(){return e.formatter.getCssText({inline:"img",classes:[t.value]})}}),t}function n(t){return function(){var i=e.settings.image_list;"string"==typeof i?tinymce.util.XHR.send({url:i,success:function(e){t(tinymce.util.JSON.parse(e))}}):"function"==typeof i?i(t):t(i)}}function a(n){function a(t,i,n){var a,l=[];return tinymce.each(e.settings[t]||n,function(e){var t={text:e.text||e.title,value:e.value};l.push(t),(f[i]===e.value||!a&&e.selected)&&(a=t)}),a&&!f[i]&&(f[i]=a.value,a.selected=!0),l}function l(){var t=[{text:"None",value:""}];return tinymce.each(n,function(i){t.push({text:i.text||i.title,value:e.convertURL(i.value||i.url,"src"),menu:i.menu})}),t}function o(){var e,t,i,n;e=u.find("#width")[0],t=u.find("#height")[0],i=e.value(),n=t.value(),u.find("#constrain")[0].checked()&&g&&h&&i&&n&&(g!=i?(n=Math.round(i/g*n),t.value(n)):(i=Math.round(n/h*i),e.value(i))),g=i,h=n}function s(){function t(t){function i(){t.onload=t.onerror=null,e.selection.select(t),e.nodeChanged()}t.onload=function(){f.width||f.height||y.setAttribs(t,{width:t.clientWidth,height:t.clientHeight}),i()},t.onerror=i}d(),o(),f=tinymce.extend(f,u.toJSON()),f.alt||(f.alt=""),""===f.width&&(f.width=null),""===f.height&&(f.height=null),f.style||(f.style=null),f={src:f.src,alt:f.alt,width:f.width,height:f.height,style:f.style,"class":f["class"]},f["class"]||delete f["class"],e.undoManager.transact(function(){return f.src?(v?y.setAttribs(v,f):(f.id="__mcenew",e.focus(),e.selection.setContent(y.createHTML("img",f)),v=y.get("__mcenew"),y.setAttrib(v,"id",null)),void t(v)):void(v&&(y.remove(v),e.focus(),e.nodeChanged()))})}function r(e){return e&&(e=e.replace(/px$/,"")),e}function c(){m&&m.value(e.convertURL(this.value(),"src")),t(this.value(),function(e){e.width&&e.height&&(g=e.width,h=e.height,u.find("#width").value(g),u.find("#height").value(h))})}function d(){function t(e){return e.length>0&&/^[0-9]+$/.test(e)&&(e+="px"),e}if(e.settings.image_advtab){var i=u.toJSON(),n=y.parseStyle(i.style);delete n.margin,n["margin-top"]=n["margin-bottom"]=t(i.vspace),n["margin-left"]=n["margin-right"]=t(i.hspace),n["border-width"]=t(i.border),u.find("#style").value(y.serializeStyle(y.parseStyle(y.serializeStyle(n))))}}var u,g,h,m,p,f={},y=e.dom,v=e.selection.getNode();g=y.getAttrib(v,"width"),h=y.getAttrib(v,"height"),"IMG"!=v.nodeName||v.getAttribute("data-mce-object")||v.getAttribute("data-mce-placeholder")?v=null:f={src:y.getAttrib(v,"src"),alt:y.getAttrib(v,"alt"),"class":y.getAttrib(v,"class"),width:g,height:h},n&&(m={type:"listbox",label:"Image list",values:l(),value:f.src&&e.convertURL(f.src,"src"),onselect:function(e){var t=u.find("#alt");(!t.value()||e.lastControl&&t.value()==e.lastControl.text())&&t.value(e.control.text()),u.find("#src").value(e.control.value())},onPostRender:function(){m=this}}),e.settings.image_class_list&&(p={name:"class",type:"listbox",label:"Class",values:i(a("image_class_list","class"))});var b=[{name:"src",type:"filepicker",filetype:"image",label:"Source",autofocus:!0,onchange:c},m];e.settings.image_description!==!1&&b.push({name:"alt",type:"textbox",label:"Image description"}),e.settings.image_dimensions!==!1&&b.push({type:"container",label:"Dimensions",layout:"flex",direction:"row",align:"center",spacing:5,items:[{name:"width",type:"textbox",maxLength:5,size:3,onchange:o,ariaLabel:"Width"},{type:"label",text:"x"},{name:"height",type:"textbox",maxLength:5,size:3,onchange:o,ariaLabel:"Height"},{name:"constrain",type:"checkbox",checked:!0,text:"Constrain proportions"}]}),b.push(p),e.settings.image_advtab?(v&&(f.hspace=r(v.style.marginLeft||v.style.marginRight),f.vspace=r(v.style.marginTop||v.style.marginBottom),f.border=r(v.style.borderWidth),f.style=e.dom.serializeStyle(e.dom.parseStyle(e.dom.getAttrib(v,"style")))),u=e.windowManager.open({title:"Insert/edit image",data:f,bodyType:"tabpanel",body:[{title:"General",type:"form",items:b},{title:"Advanced",type:"form",pack:"start",items:[{label:"Style",name:"style",type:"textbox"},{type:"form",layout:"grid",packV:"start",columns:2,padding:0,alignH:["left","right"],defaults:{type:"textbox",maxWidth:50,onchange:d},items:[{label:"Vertical space",name:"vspace"},{label:"Horizontal space",name:"hspace"},{label:"Border",name:"border"}]}]}],onSubmit:s})):u=e.windowManager.open({title:"Insert/edit image",data:f,body:b,onSubmit:s})}e.addButton("image",{icon:"image",tooltip:"Insert/edit image",onclick:n(a),stateSelector:"img:not([data-mce-object],[data-mce-placeholder])"}),e.addMenuItem("image",{icon:"image",text:"Insert image",onclick:n(a),context:"insert",prependToContext:!0})});tinymce.PluginManager.add("importcss",function(t){function e(t){return"string"==typeof t?function(e){return-1!==e.indexOf(t)}:t instanceof RegExp?function(e){return t.test(e)}:t}function n(e,n){function i(t,e){var c,o=t.href;if(o&&n(o,e)){s(t.imports,function(t){i(t,!0)});try{c=t.cssRules||t.rules}catch(a){}s(c,function(t){t.styleSheet?i(t.styleSheet,!0):t.selectorText&&s(t.selectorText.split(","),function(t){r.push(tinymce.trim(t))})})}}var r=[],c={};s(t.contentCSS,function(t){c[t]=!0}),n||(n=function(t,e){return e||c[t]});try{s(e.styleSheets,function(t){i(t)})}catch(o){}return r}function i(e){var n,i=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(e);if(i){var r=i[1],s=i[2].substr(1).split(".").join(" "),c=tinymce.makeMap("a,img");return i[1]?(n={title:e},t.schema.getTextBlockElements()[r]?n.block=r:t.schema.getBlockElements()[r]||c[r.toLowerCase()]?n.selector=r:n.inline=r):i[2]&&(n={inline:"span",title:e.substr(1),classes:s}),t.settings.importcss_merge_classes!==!1?n.classes=s:n.attributes={"class":s},n}}var r=this,s=tinymce.each;t.on("renderFormatsMenu",function(c){var o=t.settings,a={},l=o.importcss_selector_converter||i,f=e(o.importcss_selector_filter),m=c.control;t.settings.importcss_append||m.items().remove();var u=[];tinymce.each(o.importcss_groups,function(t){t=tinymce.extend({},t),t.filter=e(t.filter),u.push(t)}),s(n(c.doc||t.getDoc(),e(o.importcss_file_filter)),function(e){if(-1===e.indexOf(".mce-")&&!a[e]&&(!f||f(e))){var n,i=l.call(r,e);if(i){var s=i.name||tinymce.DOM.uniqueId();if(u)for(var c=0;c'+n+"";var i=e.dom.getParent(e.selection.getStart(),"time");if(i)return void e.dom.setOuterHTML(i,n)}e.insertContent(n)}var n,r,i="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),d="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),c="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),m="January February March April May June July August September October November December".split(" "),u=[];e.addCommand("mceInsertDate",function(){a(e.getParam("insertdatetime_dateformat",e.translate("%Y-%m-%d")))}),e.addCommand("mceInsertTime",function(){a(e.getParam("insertdatetime_timeformat",e.translate("%H:%M:%S")))}),e.addButton("insertdatetime",{type:"splitbutton",title:"Insert date/time",onclick:function(){a(n||r)},menu:u}),tinymce.each(e.settings.insertdatetime_formats||["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"],function(e){r||(r=e),u.push({text:t(e),onclick:function(){n=e,a(e)}})}),e.addMenuItem("insertdatetime",{icon:"date",text:"Insert date/time",menu:u,context:"insert"})});!function(e){e.on("AddEditor",function(e){e.editor.settings.inline_styles=!1}),e.PluginManager.add("legacyoutput",function(t){t.on("init",function(){var i="p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",n=e.explode(t.settings.font_size_style_values),l=t.schema;t.formatter.register({alignleft:{selector:i,attributes:{align:"left"}},aligncenter:{selector:i,attributes:{align:"center"}},alignright:{selector:i,attributes:{align:"right"}},alignjustify:{selector:i,attributes:{align:"justify"}},bold:[{inline:"b",remove:"all"},{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}}],italic:[{inline:"i",remove:"all"},{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}}],underline:[{inline:"u",remove:"all"},{inline:"span",styles:{textDecoration:"underline"},exact:!0}],strikethrough:[{inline:"strike",remove:"all"},{inline:"span",styles:{textDecoration:"line-through"},exact:!0}],fontname:{inline:"font",attributes:{face:"%value"}},fontsize:{inline:"font",attributes:{size:function(t){return e.inArray(n,t.value)+1}}},forecolor:{inline:"font",attributes:{color:"%value"}},hilitecolor:{inline:"font",styles:{backgroundColor:"%value"}}}),e.each("b,i,u,strike".split(","),function(e){l.addValidElements(e+"[*]")}),l.getElementRule("font")||l.addValidElements("font[face|size|color|style]"),e.each(i.split(","),function(e){var t=l.getElementRule(e);t&&(t.attributes.align||(t.attributes.align={},t.attributesOrder.push("align")))})})})}(tinymce);tinymce.PluginManager.add("link",function(t){function e(e){return function(){var n=t.settings.link_list;"string"==typeof n?tinymce.util.XHR.send({url:n,success:function(t){e(tinymce.util.JSON.parse(t))}}):"function"==typeof n?n(e):e(n)}}function n(e){function n(t){var e=d.find("#text");(!e.value()||t.lastControl&&e.value()==t.lastControl.text())&&e.value(t.control.text()),d.find("#href").value(t.control.value())}function l(){var n=[{text:"None",value:""}];return tinymce.each(e,function(e){n.push({text:e.text||e.title,value:t.convertURL(e.value||e.url,"href"),menu:e.menu})}),n}function i(e){return tinymce.each(e,function(e){e.textStyle=function(){return t.formatter.getCssText({inline:"a",classes:[e.value]})}}),e}function a(e,n,l){var i,a=[];return tinymce.each(t.settings[e]||l,function(t){var e={text:t.text||t.title,value:t.value};a.push(e),(b[n]===t.value||!i&&t.selected)&&(i=e)}),i&&!b[n]&&(b[n]=i.value,i.selected=!0),a}function r(e){var l=[];return tinymce.each(t.dom.select("a:not([href])"),function(t){var n=t.name||t.id;n&&l.push({text:n,value:"#"+n,selected:-1!=e.indexOf("#"+n)})}),l.length?(l.unshift({text:"None",value:""}),{name:"anchor",type:"listbox",label:"Anchors",values:l,onselect:n}):void 0}function o(){h&&h.value(t.convertURL(this.value(),"href")),!f&&0===b.text.length&&x&&this.parent().parent().find("#text")[0].value(this.value())}function s(t){var e=k.getContent();if(/]+>[^<]+<\/a>$/.test(e)||-1==e.indexOf("href=")))return!1;if(t){var n,l=t.childNodes;if(0===l.length)return!1;for(n=l.length-1;n>=0;n--)if(3!=l[n].nodeType)return!1}return!0}var u,c,f,d,x,v,h,g,m,p,y,b={},k=t.selection,w=t.dom;u=k.getNode(),c=w.getParent(u,"a[href]"),x=s(),b.text=f=c?c.innerText||c.textContent:k.getContent({format:"text"}),b.href=c?w.getAttrib(c,"href"):"",b.target=c?w.getAttrib(c,"target"):t.settings.default_link_target||null,b.rel=c?w.getAttrib(c,"rel"):null,b["class"]=c?w.getAttrib(c,"class"):null,b.title=c?w.getAttrib(c,"title"):"",x&&(v={name:"text",type:"textbox",size:40,label:"Text to display",onchange:function(){b.text=this.value()}}),e&&(h={type:"listbox",label:"Link list",values:l(),onselect:n,value:t.convertURL(b.href,"href"),onPostRender:function(){h=this}}),t.settings.target_list!==!1&&(m={name:"target",type:"listbox",label:"Target",values:a("target_list","target",[{text:"None",value:""},{text:"New window",value:"_blank"}])}),t.settings.rel_list&&(g={name:"rel",type:"listbox",label:"Rel",values:a("rel_list","rel",[{text:"None",value:""}])}),t.settings.link_class_list&&(p={name:"class",type:"listbox",label:"Class",values:i(a("link_class_list","class"))}),t.settings.link_title!==!1&&(y={name:"title",type:"textbox",label:"Title",value:b.title}),d=t.windowManager.open({title:"Insert link",data:b,body:[{name:"href",type:"filepicker",filetype:"file",size:40,autofocus:!0,label:"Url",onchange:o,onkeyup:o},v,y,r(b.href),h,g,m,p],onSubmit:function(e){function n(e,n){var l=t.selection.getRng();window.setTimeout(function(){t.windowManager.confirm(e,function(e){t.selection.setRng(l),n(e)})},0)}function l(){var e={href:i,target:b.target?b.target:null,rel:b.rel?b.rel:null,"class":b["class"]?b["class"]:null,title:b.title?b.title:null};c?(t.focus(),x&&b.text!=f&&("innerText"in c?c.innerText=b.text:c.textContent=b.text),w.setAttribs(c,e),k.select(c),t.undoManager.add()):x?t.insertContent(w.createHTML("a",e,w.encode(b.text))):t.execCommand("mceInsertLink",!1,e)}var i;return b=tinymce.extend(b,e.data),(i=b.href)?i.indexOf("@")>0&&-1==i.indexOf("//")&&-1==i.indexOf("mailto:")?void n("The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",function(t){t&&(i="mailto:"+i),l()}):/^\s*www\./i.test(i)?void n("The URL you entered seems to be an external link. Do you want to add the required http:// prefix?",function(t){t&&(i="http://"+i),l()}):void l():void t.execCommand("unlink")}})}t.addButton("link",{icon:"link",tooltip:"Insert/edit link",shortcut:"Ctrl+K",onclick:e(n),stateSelector:"a[href]"}),t.addButton("unlink",{icon:"unlink",tooltip:"Remove link",cmd:"unlink",stateSelector:"a[href]"}),t.addShortcut("Ctrl+K","",e(n)),this.showDialog=n,t.addMenuItem("link",{icon:"link",text:"Insert link",shortcut:"Ctrl+K",onclick:e(n),stateSelector:"a[href]",context:"insert",prependToContext:!0})});tinymce.PluginManager.add("lists",function(e){function t(e){return e&&/^(OL|UL)$/.test(e.nodeName)}function n(e){return e.parentNode.firstChild==e}function r(e){return e.parentNode.lastChild==e}function o(t){return t&&!!e.schema.getTextBlockElements()[t.nodeName]}function i(e){return e&&"SPAN"===e.nodeName&&"bookmark"===e.getAttribute("data-mce-type")}var a=this;e.on("init",function(){function d(e){function t(t){var r,o,i;o=e[t?"startContainer":"endContainer"],i=e[t?"startOffset":"endOffset"],1==o.nodeType&&(r=b.create("span",{"data-mce-type":"bookmark"}),o.hasChildNodes()?(i=Math.min(i,o.childNodes.length-1),t?o.insertBefore(r,o.childNodes[i]):b.insertAfter(r,o.childNodes[i])):o.appendChild(r),o=r,i=0),n[t?"startContainer":"endContainer"]=o,n[t?"startOffset":"endOffset"]=i}var n={};return t(!0),e.collapsed||t(),n}function s(e){function t(t){function n(e){for(var t=e.parentNode.firstChild,n=0;t;){if(t==e)return n;(1!=t.nodeType||"bookmark"!=t.getAttribute("data-mce-type"))&&n++,t=t.nextSibling}return-1}var r,o,i;r=i=e[t?"startContainer":"endContainer"],o=e[t?"startOffset":"endOffset"],r&&(1==r.nodeType&&(o=n(r),r=r.parentNode,b.remove(i)),e[t?"startContainer":"endContainer"]=r,e[t?"startOffset":"endOffset"]=o)}t(!0),t();var n=b.createRng();n.setStart(e.startContainer,e.startOffset),e.endContainer&&n.setEnd(e.endContainer,e.endOffset),k.setRng(n)}function f(t,n){var r,o,i,a=b.createFragment(),d=e.schema.getBlockElements();if(e.settings.forced_root_block&&(n=n||e.settings.forced_root_block),n&&(o=b.create(n),o.tagName===e.settings.forced_root_block&&b.setAttribs(o,e.settings.forced_root_block_attrs),a.appendChild(o)),t)for(;r=t.firstChild;){var s=r.nodeName;i||"SPAN"==s&&"bookmark"==r.getAttribute("data-mce-type")||(i=!0),d[s]?(a.appendChild(r),o=null):n?(o||(o=b.create(n),a.appendChild(o)),o.appendChild(r)):a.appendChild(r)}return e.settings.forced_root_block?i||tinymce.Env.ie&&!(tinymce.Env.ie>10)||o.appendChild(b.create("br",{"data-mce-bogus":"1"})):a.appendChild(b.create("br")),a}function l(){return tinymce.grep(k.getSelectedBlocks(),function(e){return"LI"==e.nodeName})}function c(e,t,n){var r,o,i=b.select('span[data-mce-type="bookmark"]',e);n=n||f(t),r=b.createRng(),r.setStartAfter(t),r.setEndAfter(e),o=r.extractContents(),b.isEmpty(o)||b.insertAfter(o,e),b.insertAfter(n,e),b.isEmpty(t.parentNode)&&(tinymce.each(i,function(e){t.parentNode.parentNode.insertBefore(e,t.parentNode)}),b.remove(t.parentNode)),b.remove(t)}function p(e){var n,r;if(n=e.nextSibling,n&&t(n)&&n.nodeName==e.nodeName){for(;r=n.firstChild;)e.appendChild(r);b.remove(n)}if(n=e.previousSibling,n&&t(n)&&n.nodeName==e.nodeName){for(;r=n.firstChild;)e.insertBefore(r,e.firstChild);b.remove(n)}}function u(e){tinymce.each(tinymce.grep(b.select("ol,ul",e)),function(e){var n,r=e.parentNode;"LI"==r.nodeName&&r.firstChild==e&&(n=r.previousSibling,n&&"LI"==n.nodeName&&(n.appendChild(e),b.isEmpty(r)&&b.remove(r))),t(r)&&(n=r.previousSibling,n&&"LI"==n.nodeName&&n.appendChild(e))})}function m(e){function o(e){b.isEmpty(e)&&b.remove(e)}var i,a=e.parentNode,d=a.parentNode;return n(e)&&r(e)?("LI"==d.nodeName?(b.insertAfter(e,d),o(d),b.remove(a)):t(d)?b.remove(a,!0):(d.insertBefore(f(e),a),b.remove(a)),!0):n(e)?("LI"==d.nodeName?(b.insertAfter(e,d),e.appendChild(a),o(d)):t(d)?d.insertBefore(e,a):(d.insertBefore(f(e),a),b.remove(e)),!0):r(e)?("LI"==d.nodeName?b.insertAfter(e,d):t(d)?b.insertAfter(e,a):(b.insertAfter(f(e),a),b.remove(e)),!0):("LI"==d.nodeName?(a=d,i=f(e,"LI")):i=t(d)?f(e,"LI"):f(e),c(a,e,i),u(a.parentNode),!0)}function h(e){function n(n,r){var o;if(t(n)){for(;o=e.lastChild.firstChild;)r.appendChild(o);b.remove(n)}}var r,o;return r=e.previousSibling,r&&t(r)?(r.appendChild(e),!0):r&&"LI"==r.nodeName&&t(r.lastChild)?(r.lastChild.appendChild(e),n(e.lastChild,r.lastChild),!0):(r=e.nextSibling,r&&t(r)?(r.insertBefore(e,r.firstChild),!0):r&&"LI"==r.nodeName&&t(e.lastChild)?!1:(r=e.previousSibling,r&&"LI"==r.nodeName?(o=b.create(e.parentNode.nodeName),r.appendChild(o),o.appendChild(e),n(e.lastChild,o),!0):!1))}function v(){var t=l();if(t.length){for(var n=d(k.getRng(!0)),r=0;r0))return n;for(var o=new tinymce.dom.TreeWalker(e.startContainer);n=o[t?"next":"prev"]();)if(3==n.nodeType&&n.data.length>0)return n}function r(e,n){var r,o,i=e.parentNode;for(t(n.lastChild)&&(o=n.lastChild),r=n.lastChild,r&&"BR"==r.nodeName&&e.hasChildNodes()&&b.remove(r);r=e.firstChild;)n.appendChild(r);o&&n.appendChild(o),b.remove(e),b.isEmpty(i)&&b.remove(i)}if(k.isCollapsed()){var o=b.getParent(k.getStart(),"LI");if(o){var i=k.getRng(!0),a=b.getParent(n(i,e),"LI");if(a&&a!=o){var f=d(i);return e?r(a,o):r(o,a),s(f),!0}if(!a&&!e&&N(o.parentNode.nodeName))return!0}}},e.addCommand("Indent",function(){return v()?void 0:!0}),e.addCommand("Outdent",function(){return C()?void 0:!0}),e.addCommand("InsertUnorderedList",function(){y("UL")}),e.addCommand("InsertOrderedList",function(){y("OL")}),e.on("keydown",function(t){9==t.keyCode&&e.dom.getParent(e.selection.getStart(),"LI")&&(t.preventDefault(),t.shiftKey?C():v())})}),e.addButton("indent",{icon:"indent",title:"Increase indent",cmd:"Indent",onPostRender:function(){var t=this;e.on("nodechange",function(){for(var r=e.selection.getSelectedBlocks(),o=!1,i=0,a=r.length;!o&&a>i;i++){var d=r[i].nodeName;o="LI"==d&&n(r[i])||"UL"==d||"OL"==d}t.disabled(o)})}}),e.on("keydown",function(e){e.keyCode==tinymce.util.VK.BACKSPACE?a.backspaceDelete()&&e.preventDefault():e.keyCode==tinymce.util.VK.DELETE&&a.backspaceDelete(!0)&&e.preventDefault()})});tinymce.PluginManager.add("media",function(e,t){function i(e){return-1!=e.indexOf(".mp3")?"audio/mpeg":-1!=e.indexOf(".wav")?"audio/wav":-1!=e.indexOf(".mp4")?"video/mp4":-1!=e.indexOf(".webm")?"video/webm":-1!=e.indexOf(".ogg")?"video/ogg":-1!=e.indexOf(".swf")?"application/x-shockwave-flash":""}function r(t){var i=e.settings.media_scripts;if(i)for(var r=0;r':"application/x-shockwave-flash"==o.source1mime?(a+='',o.poster&&(a+=''),a+=""):-1!=o.source1mime.indexOf("audio")?e.settings.audio_template_callback?a=e.settings.audio_template_callback(o):a+='":"script"==o.type?a+='':a=e.settings.video_template_callback?e.settings.video_template_callback(o):'"}return a}function s(e){var t={};return new tinymce.html.SaxParser({validate:!1,allow_conditional_comments:!0,special:"script,noscript",start:function(e,i){if(t.source1||"param"!=e||(t.source1=i.map.movie),("iframe"==e||"object"==e||"embed"==e||"video"==e||"audio"==e)&&(t.type||(t.type=e),t=tinymce.extend(i.map,t)),"script"==e){var o=r(i.map.src);if(!o)return;t={type:"script",source1:i.map.src,width:o.width,height:o.height}}"source"==e&&(t.source1?t.source2||(t.source2=i.map.src):t.source1=i.map.src),"img"!=e||t.poster||(t.poster=i.map.src)}}).parse(e),t.source1=t.source1||t.src||t.data,t.source2=t.source2||"",t.poster=t.poster||"",t}function n(t){return t.getAttribute("data-mce-object")?s(e.serializer.serialize(t,{selection:!0})):{}}function m(e,t,i){function r(e,t){var i,r,o,a;for(i in t)if(o=""+t[i],e.map[i])for(r=e.length;r--;)a=e[r],a.name==i&&(o?(e.map[i]=o,a.value=o):(delete e.map[i],e.splice(r,1)));else o&&(e.push({name:i,value:o}),e.map[i]=o)}var o,a=new tinymce.html.Writer,c=0;return new tinymce.html.SaxParser({validate:!1,allow_conditional_comments:!0,special:"script,noscript",comment:function(e){a.comment(e)},cdata:function(e){a.cdata(e)},text:function(e,t){a.text(e,t)},start:function(e,s,n){switch(e){case"video":case"object":case"embed":case"img":case"iframe":r(s,{width:t.width,height:t.height})}if(i)switch(e){case"video":r(s,{poster:t.poster,src:""}),t.source2&&r(s,{src:""});break;case"iframe":r(s,{src:t.source1});break;case"source":if(c++,2>=c&&(r(s,{src:t["source"+c],type:t["source"+c+"mime"]}),!t["source"+c]))return;break;case"img":if(!t.poster)return;o=!0}a.start(e,s,n)},end:function(e){if("video"==e&&i)for(var s=1;2>=s;s++)if(t["source"+s]){var n=[];n.map={},s>c&&(r(n,{src:t["source"+s],type:t["source"+s+"mime"]}),a.start("source",n,!0))}if(t.poster&&"object"==e&&i&&!o){var m=[];m.map={},r(m,{src:t.poster,width:t.width,height:t.height}),a.start("img",m,!0)}a.end(e)}},new tinymce.html.Schema({})).parse(e),a.getContent()}var u=[{regex:/youtu\.be\/([\w\-.]+)/,type:"iframe",w:425,h:350,url:"//www.youtube.com/embed/$1"},{regex:/youtube\.com(.+)v=([^&]+)/,type:"iframe",w:425,h:350,url:"//www.youtube.com/embed/$2"},{regex:/vimeo\.com\/([0-9]+)/,type:"iframe",w:425,h:350,url:"//player.vimeo.com/video/$1?title=0&byline=0&portrait=0&color=8dc7dc"},{regex:/maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/,type:"iframe",w:425,h:350,url:'//maps.google.com/maps/ms?msid=$2&output=embed"'}];e.on("ResolveName",function(e){var t;1==e.target.nodeType&&(t=e.target.getAttribute("data-mce-object"))&&(e.name=t)}),e.on("preInit",function(){var t=e.schema.getSpecialElements();tinymce.each("video audio iframe object".split(" "),function(e){t[e]=new RegExp("]*>","gi")});var i=e.schema.getBoolAttrs();tinymce.each("webkitallowfullscreen mozallowfullscreen allowfullscreen".split(" "),function(e){i[e]={}}),e.parser.addNodeFilter("iframe,video,audio,object,embed,script",function(t,i){for(var o,a,c,s,n,m,u,d,l=t.length;l--;)if(a=t[l],a.parent&&("script"!=a.name||(d=r(a.attr("src"))))){for(c=new tinymce.html.Node("img",1),c.shortEnded=!0,d&&(d.width&&a.attr("width",d.width.toString()),d.height&&a.attr("height",d.height.toString())),m=a.attributes,o=m.length;o--;)s=m[o].name,n=m[o].value,"width"!==s&&"height"!==s&&"style"!==s&&(("data"==s||"src"==s)&&(n=e.convertURL(n,s)),c.attr("data-mce-p-"+s,n));u=a.firstChild&&a.firstChild.value,u&&(c.attr("data-mce-html",escape(u)),c.firstChild=null),c.attr({width:a.attr("width")||"300",height:a.attr("height")||("audio"==i?"30":"150"),style:a.attr("style"),src:tinymce.Env.transparentSrc,"data-mce-object":i,"class":"mce-object mce-object-"+i}),a.replace(c)}}),e.serializer.addAttributeFilter("data-mce-object",function(e,t){for(var i,r,o,a,c,s,n,m=e.length;m--;)if(i=e[m],i.parent){for(n=i.attr(t),r=new tinymce.html.Node(n,1),"audio"!=n&&"script"!=n&&r.attr({width:i.attr("width"),height:i.attr("height")}),r.attr({style:i.attr("style")}),a=i.attributes,o=a.length;o--;){var u=a[o].name;0===u.indexOf("data-mce-p-")&&r.attr(u.substr(11),a[o].value)}"script"==n&&r.attr("type","text/javascript"),c=i.attr("data-mce-html"),c&&(s=new tinymce.html.Node("#text",3),s.raw=!0,s.value=unescape(c),r.append(s)),i.replace(r)}})}),e.on("ObjectSelected",function(e){var t=e.target.getAttribute("data-mce-object");("audio"==t||"script"==t)&&e.preventDefault()}),e.on("objectResized",function(e){var t,i=e.target;i.getAttribute("data-mce-object")&&(t=i.getAttribute("data-mce-html"),t&&(t=unescape(t),i.setAttribute("data-mce-html",escape(m(t,{width:e.width,height:e.height})))))}),e.addButton("media",{tooltip:"Insert/edit video",onclick:o,stateSelector:["img[data-mce-object=video]","img[data-mce-object=iframe]"]}),e.addMenuItem("media",{icon:"media",text:"Insert video",onclick:o,context:"insert",prependToContext:!0})});tinymce.PluginManager.add("nonbreaking",function(n){var e=n.getParam("nonbreaking_force_tab");if(n.addCommand("mceNonBreaking",function(){n.insertContent(n.plugins.visualchars&&n.plugins.visualchars.state?' ':" "),n.dom.setAttrib(n.dom.select("span.mce-nbsp"),"data-mce-bogus","1")}),n.addButton("nonbreaking",{title:"Insert nonbreaking space",cmd:"mceNonBreaking"}),n.addMenuItem("nonbreaking",{text:"Nonbreaking space",cmd:"mceNonBreaking",context:"insert"}),e){var a=+e>1?+e:3;n.on("keydown",function(e){if(9==e.keyCode){if(e.shiftKey)return;e.preventDefault();for(var t=0;a>t;t++)n.execCommand("mceNonBreaking")}})}});tinymce.PluginManager.add("noneditable",function(e){function t(e){var t;if(1===e.nodeType){if(t=e.getAttribute(u),t&&"inherit"!==t)return t;if(t=e.contentEditable,"inherit"!==t)return t}return null}function n(e){for(var n;e;){if(n=t(e))return"false"===n?e:null;e=e.parentNode}}function r(){function r(e){for(;e;){if(e.id===g)return e;e=e.parentNode}}function a(e){var t;if(e)for(t=new f(e,e),e=t.current();e;e=t.next())if(3===e.nodeType)return e}function i(n,r){var a,i;return"false"===t(n)&&u.isBlock(n)?void s.select(n):(i=u.createRng(),"true"===t(n)&&(n.firstChild||n.appendChild(e.getDoc().createTextNode(" ")),n=n.firstChild,r=!0),a=u.create("span",{id:g,"data-mce-bogus":!0},m),r?n.parentNode.insertBefore(a,n):u.insertAfter(a,n),i.setStart(a.firstChild,1),i.collapse(!0),s.setRng(i),a)}function o(e){var t,n,i,o;if(e)t=s.getRng(!0),t.setStartBefore(e),t.setEndBefore(e),n=a(e),n&&n.nodeValue.charAt(0)==m&&(n=n.deleteData(0,1)),u.remove(e,!0),s.setRng(t);else for(i=r(s.getStart());(e=u.get(g))&&e!==o;)i!==e&&(n=a(e),n&&n.nodeValue.charAt(0)==m&&(n=n.deleteData(0,1)),u.remove(e,!0)),o=e}function l(){function e(e,n){var r,a,i,o,l;if(r=d.startContainer,a=d.startOffset,3==r.nodeType){if(l=r.nodeValue.length,a>0&&l>a||(n?a==l:0===a))return}else{if(!(a0?a-1:a;r=r.childNodes[u],r.hasChildNodes()&&(r=r.firstChild)}for(i=new f(r,e);o=i[n?"prev":"next"]();){if(3===o.nodeType&&o.nodeValue.length>0)return;if("true"===t(o))return o}return e}var r,a,l,d,u;o(),l=s.isCollapsed(),r=n(s.getStart()),a=n(s.getEnd()),(r||a)&&(d=s.getRng(!0),l?(r=r||a,(u=e(r,!0))?i(u,!0):(u=e(r,!1))?i(u,!1):s.select(r)):(d=s.getRng(!0),r&&d.setStartBefore(r),a&&d.setEndAfter(a),s.setRng(d)))}function d(a){function i(e,t){for(;e=e[t?"previousSibling":"nextSibling"];)if(3!==e.nodeType||e.nodeValue.length>0)return e}function d(e,t){s.select(e),s.collapse(t)}function g(a){function i(e){for(var t=d;t;){if(t===e)return;t=t.parentNode}u.remove(e),l()}function o(){var r,o,l=e.schema.getNonEmptyElements();for(o=new tinymce.dom.TreeWalker(d,e.getBody());(r=a?o.prev():o.next())&&!l[r.nodeName.toLowerCase()]&&!(3===r.nodeType&&tinymce.trim(r.nodeValue).length>0);)if("false"===t(r))return i(r),!0;return n(r)?!0:!1}var f,d,c,g;if(s.isCollapsed()){if(f=s.getRng(!0),d=f.startContainer,c=f.startOffset,d=r(d)||d,g=n(d))return i(g),!1;if(3==d.nodeType&&(a?c>0:ch||h>124)&&h!=c.DELETE&&h!=c.BACKSPACE){if((tinymce.isMac?a.metaKey:a.ctrlKey)&&(67==h||88==h||86==h))return;if(a.preventDefault(),h==c.LEFT||h==c.RIGHT){var y=h==c.LEFT;if(e.dom.isBlock(m)){var T=y?m.previousSibling:m.nextSibling,C=new f(T,T),b=y?C.prev():C.next();d(b,!y)}else d(m,y)}}else if(h==c.LEFT||h==c.RIGHT||h==c.BACKSPACE||h==c.DELETE){if(p=r(v)){if(h==c.LEFT||h==c.BACKSPACE)if(m=i(p,!0),m&&"false"===t(m)){if(a.preventDefault(),h!=c.LEFT)return void u.remove(m);d(m,!0)}else o(p);if(h==c.RIGHT||h==c.DELETE)if(m=i(p),m&&"false"===t(m)){if(a.preventDefault(),h!=c.RIGHT)return void u.remove(m);d(m,!1)}else o(p)}if((h==c.BACKSPACE||h==c.DELETE)&&!g(h==c.BACKSPACE))return a.preventDefault(),!1}}var u=e.dom,s=e.selection,g="mce_noneditablecaret",m="";e.on("mousedown",function(n){var r=e.selection.getNode();"false"===t(r)&&r==n.target&&l()}),e.on("mouseup keyup",l),e.on("keydown",d)}function a(t){var n=l.length,r=t.content,a=tinymce.trim(o);if("raw"!=t.format){for(;n--;)r=r.replace(l[n],function(t){var n=arguments,i=n[n.length-2];return i>0&&'"'==r.charAt(i-1)?t:''+e.dom.encode("string"==typeof n[1]?n[1]:n[0])+""});t.content=r}}var i,o,l,f=tinymce.dom.TreeWalker,d="contenteditable",u="data-mce-"+d,c=tinymce.util.VK;i=" "+tinymce.trim(e.getParam("noneditable_editable_class","mceEditable"))+" ",o=" "+tinymce.trim(e.getParam("noneditable_noneditable_class","mceNonEditable"))+" ",l=e.getParam("noneditable_regexp"),l&&!l.length&&(l=[l]),e.on("PreInit",function(){r(),l&&e.on("BeforeSetContent",a),e.parser.addAttributeFilter("class",function(e){for(var t,n,r=e.length;r--;)n=e[r],t=" "+n.attr("class")+" ",-1!==t.indexOf(i)?n.attr(u,"true"):-1!==t.indexOf(o)&&n.attr(u,"false")}),e.serializer.addAttributeFilter(u,function(e){for(var t,n=e.length;n--;)t=e[n],l&&t.attr("data-mce-content")?(t.name="#text",t.type=3,t.raw=!0,t.value=t.attr("data-mce-content")):(t.attr(d,null),t.attr(u,null))}),e.parser.addAttributeFilter(d,function(e){for(var t,n=e.length;n--;)t=e[n],t.attr(u,t.attr(d)),t.attr(d,null)})}),e.on("drop",function(e){n(e.target)&&e.preventDefault()})});tinymce.PluginManager.add("pagebreak",function(e){var a="mce-pagebreak",t=e.getParam("pagebreak_separator",""),n=new RegExp(t.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(e){return"\\"+e}),"gi"),r='';e.addCommand("mcePageBreak",function(){e.insertContent(e.settings.pagebreak_split_block?"

    "+r+"

    ":r)}),e.addButton("pagebreak",{title:"Page break",cmd:"mcePageBreak"}),e.addMenuItem("pagebreak",{text:"Page break",icon:"pagebreak",cmd:"mcePageBreak",context:"insert"}),e.on("ResolveName",function(t){"IMG"==t.target.nodeName&&e.dom.hasClass(t.target,a)&&(t.name="pagebreak")}),e.on("click",function(t){t=t.target,"IMG"===t.nodeName&&e.dom.hasClass(t,a)&&e.selection.select(t)}),e.on("BeforeSetContent",function(e){e.content=e.content.replace(n,r)}),e.on("PreInit",function(){e.serializer.addNodeFilter("img",function(a){for(var n,r,c=a.length;c--;)if(n=a[c],r=n.attr("class"),r&&-1!==r.indexOf("mce-pagebreak")){var o=n.parent;if(e.schema.getBlockElements()[o.name]&&e.settings.pagebreak_split_block){o.type=3,o.value=t,o.raw=!0,n.remove();continue}n.type=3,n.value=t,n.raw=!0}})})});!function(e,t){"use strict";function n(e,t){for(var n,i=[],r=0;r"),t&&/^(PRE|DIV)$/.test(t.nodeName)||!o?e=n.filter(e,[[/\n/g,"
    "]]):(e=n.filter(e,[[/\n\n/g,"

    "+a],[/^(.*<\/p>)(

    )$/,a+"$1"],[/\n/g,"
    "]]),-1!=e.indexOf("

    ")&&(e=a+e)),r(e)}function a(){var t=i.dom,n=i.getBody(),r=i.dom.getViewPort(i.getWin()),o=r.y,a=20,s;if(v=i.selection.getRng(),i.inline&&(s=i.selection.getScrollContainer(),s&&s.scrollTop>0&&(o=s.scrollTop)),v.getClientRects){var l=v.getClientRects();if(l.length)a=o+(l[0].top-t.getPos(n).y);else{a=o;var c=v.startContainer;c&&(3==c.nodeType&&c.parentNode!=n&&(c=c.parentNode),1==c.nodeType&&(a=t.getPos(c,s||n).y))}}h=t.add(i.getBody(),"div",{id:"mcepastebin",contentEditable:!0,"data-mce-bogus":"1",style:"position: absolute; top: "+a+"px;width: 10px; height: 10px; overflow: hidden; opacity: 0"},y),(e.ie||e.gecko)&&t.setStyle(h,"left","rtl"==t.getStyle(n,"direction",!0)?65535:-65535),t.bind(h,"beforedeactivate focusin focusout",function(e){e.stopPropagation()}),h.focus(),i.selection.select(h,!0)}function s(){if(h){for(var e;e=i.dom.get("mcepastebin");)i.dom.remove(e),i.dom.unbind(e);v&&i.selection.setRng(v)}x=!1,h=v=null}function l(){var e=y,t,n;for(t=i.dom.select("div[id=mcepastebin]"),n=t.length;n--;){var r=t[n].innerHTML;e==y&&(e=""),r.length>e.length&&(e=r)}return e}function c(e){var t={};if(e&&e.types){var n=e.getData("Text");n&&n.length>0&&(t["text/plain"]=n);for(var i=0;i')},t.readAsDataURL(e.getAsFile()),!0}}if(!(!i.settings.paste_data_images||"text/html"in t||"text/plain"in t)&&e.clipboardData){var o=e.clipboardData.items;if(o)for(var a=0;a0}function p(){i.on("keydown",function(n){if(!n.isDefaultPrevented()&&(t.metaKeyPressed(n)&&86==n.keyCode||n.shiftKey&&45==n.keyCode)){if(x=n.shiftKey&&86==n.keyCode,n.stopImmediatePropagation(),b=(new Date).getTime(),e.ie&&x)return n.preventDefault(),void i.fire("paste",{ieFake:!0});s(),a()}}),i.on("paste",function(t){var c=d(t),f=(new Date).getTime()-b<1e3,p="text"==g.pasteFormat||x;return t.isDefaultPrevented()?void s():u(t,c)?void s():(f||t.preventDefault(),!e.ie||f&&!t.ieFake||(a(),i.dom.bind(h,"paste",function(e){e.stopPropagation()}),i.getDoc().execCommand("Paste",!1,null),c["text/html"]=l()),void setTimeout(function(){var e=l();return h&&h.firstChild&&"mcepastebin"===h.firstChild.id&&(p=!0),s(),!p&&f&&e&&e!=y&&(c["text/html"]=e),e!=y&&f||(e=c["text/html"]||c["text/plain"]||y,e!=y)?(!m(c,"text/html")&&m(c,"text/plain")&&(p=!0),void(p?o(c["text/plain"]||n.innerText(e)):r(e))):void(f||i.windowManager.alert("Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents."))},0))}),i.on("dragstart",function(e){if(e.dataTransfer.types)try{e.dataTransfer.setData("mce-internal",i.selection.getContent())}catch(t){}}),i.on("drop",function(e){var t=f(e);if(t&&!e.isDefaultPrevented()){var n=c(e.dataTransfer),a=n["mce-internal"]||n["text/html"]||n["text/plain"];a&&(e.preventDefault(),i.undoManager.transact(function(){n["mce-internal"]&&i.execCommand("Delete"),i.selection.setRng(t),n["text/html"]?r(a):o(a)}))}})}var g=this,h,v,b=0,y="%MCEPASTEBIN%",x;g.pasteHtml=r,g.pasteText=o,i.on("preInit",function(){p(),i.parser.addNodeFilter("img",function(t){if(!i.settings.paste_data_images)for(var n=t.length;n--;){var r=t[n].attributes.map.src;r&&0===r.indexOf("data:image")&&(t[n].attr("data-mce-object")||r===e.transparentSrc||t[n].remove())}})}),i.on("PreProcess",function(){i.dom.remove(i.dom.get("mcepastebin"))})}}),i(g,[c,d,u,h,v,l],function(e,t,n,i,r,o){function a(e){return/l?n&&(n=n.parent.parent):(i=n,n=null)),n&&n.name==a?n.append(e):(i=i||n,n=new r(a,1),s>1&&n.attr("start",""+s),e.wrap(n)),e.name="li",t.value="";var c=t.next;c&&3==c.type&&(c.value=c.value.replace(/^\u00a0+/,"")),l>o&&i&&i.lastChild.append(n),o=l}for(var n,i,o=1,a=e.getAll("p"),s=0;s/gi,/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,[/<(\/?)s>/gi,"<$1strike>"],[/ /gi,"\xa0"],[/([\s\u00a0]*)<\/span>/gi,function(e,t){return t.length>0?t.replace(/./," ").slice(Math.floor(t.length/2)).split("").join("\xa0"):""}]]);var g=l.paste_word_valid_elements;g||(g="-strong/b,-em/i,-span,-p,-ol,-ul,-li,-h1,-h2,-h3,-h4,-h5,-h6,-p/div,-table[width],-tr,-td[colspan|rowspan|width],-th,-thead,-tfoot,-tbody,-a[href|name],sub,sup,strike,br,del");var h=new n({valid_elements:g,valid_children:"-li[p]"});e.each(h.elements,function(e){e.attributes["class"]||(e.attributes["class"]={},e.attributesOrder.push("class")),e.attributes.style||(e.attributes.style={},e.attributesOrder.push("style"))});var v=new t({},h);v.addAttributeFilter("style",function(e){for(var t=e.length,n;t--;)n=e[t],n.attr("style",u(n,n.attr("style"))),"span"==n.name&&n.parent&&!n.attributes.length&&n.unwrap()}),v.addAttributeFilter("class",function(e){for(var t=e.length,n,i;t--;)n=e[t],i=n.attr("class"),/^(MsoCommentReference|MsoCommentText|msoDel)$/i.test(i)&&n.remove(),n.attr("class",null)}),v.addNodeFilter("del",function(e){for(var t=e.length;t--;)e[t].remove()}),v.addNodeFilter("a",function(e){for(var t=e.length,n,i,r;t--;)if(n=e[t],i=n.attr("href"),r=n.attr("name"),i&&-1!=i.indexOf("#_msocom_"))n.remove();else if(i&&0===i.indexOf("file://")&&(i=i.split("#")[1],i&&(i="#"+i)),i||r){if(r&&!/^_?(?:toc|edn|ftn)/i.test(r)){n.unwrap();continue}n.attr({href:i,name:r})}else n.unwrap()});var b=v.parse(f);d(b),c.content=new i({},h).serialize(b)}})}return s.isWordContent=a,s}),i(b,[m,c,g,l],function(e,t,n,i){return function(r){function o(e){r.on("BeforePastePreProcess",function(t){t.content=e(t.content)})}function a(e){return e=i.filter(e,[/^[\s\S]*]*>\s*|\s*<\/body[^>]*>[\s\S]*$/g,/|/g,[/\u00a0<\/span>/g,"\xa0"],/
    $/i])}function s(e){if(!n.isWordContent(e))return e;var o=[];t.each(r.schema.getBlockElements(),function(e,t){o.push(t)});var a=new RegExp("(?:
     [\\s\\r\\n]+|
    )*(<\\/?("+o.join("|")+")[^>]*>)(?:
     [\\s\\r\\n]+|
    )*","g");return e=i.filter(e,[[a,"$1"]]),e=i.filter(e,[[/

    /g,"

    "],[/
    /g," "],[/

    /g,"
    "]])}function l(e){if(n.isWordContent(e))return e;var t=r.settings.paste_webkit_styles;if(r.settings.paste_remove_styles_if_webkit===!1||"all"==t)return e;if(t&&(t=t.split(/[, ]/)),t){var i=r.dom,o=r.selection.getNode();e=e.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi,function(e,n,r,a){var s=i.parseStyle(r,"span"),l={};if("none"===t)return n+a;for(var c=0;c]+) style="([^"]*)"([^>]*>)/gi,"$1$3");return e=e.replace(/(<[^>]+) data-mce-style="([^"]+)"([^>]*>)/gi,function(e,t,n,i){return t+' style="'+n+'"'+i})}e.webkit&&(o(l),o(a)),e.ie&&o(s)}}),i(y,[x,f,g,b],function(e,t,n,i){var r;e.add("paste",function(e){function o(){"text"==s.pasteFormat?(this.active(!1),s.pasteFormat="html"):(s.pasteFormat="text",this.active(!0),r||(e.windowManager.alert("Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off."),r=!0))}var a=this,s,l=e.settings;a.clipboard=s=new t(e),a.quirks=new i(e),a.wordFilter=new n(e),e.settings.paste_as_text&&(a.clipboard.pasteFormat="text"),l.paste_preprocess&&e.on("PastePreProcess",function(e){l.paste_preprocess.call(a,a,e)}),l.paste_postprocess&&e.on("PastePostProcess",function(e){l.paste_postprocess.call(a,a,e)}),e.addCommand("mceInsertClipboardContent",function(e,t){t.content&&a.clipboard.pasteHtml(t.content),t.text&&a.clipboard.pasteText(t.text)}),e.paste_block_drop&&e.on("dragend dragover draggesture dragdrop drop drag",function(e){e.preventDefault(),e.stopPropagation()}),e.settings.paste_data_images||e.on("drop",function(e){var t=e.dataTransfer;t&&t.files&&t.files.length>0&&e.preventDefault()}),e.addButton("pastetext",{icon:"pastetext",tooltip:"Paste as text",onclick:o,active:"text"==a.clipboard.pasteFormat}),e.addMenuItem("pastetext",{text:"Paste as text",selectable:!0,active:s.pasteFormat,onclick:o})})}),a([l,f,g,b,y])}(this);tinymce.PluginManager.add("preview",function(e){var t=e.settings,i=!tinymce.Env.ie;e.addCommand("mcePreview",function(){e.windowManager.open({title:"Preview",width:parseInt(e.getParam("plugin_preview_width","650"),10),height:parseInt(e.getParam("plugin_preview_height","500"),10),html:'",buttons:{text:"Close",onclick:function(){this.parent().parent().close()}},onPostRender:function(){var n,a="";a+='',tinymce.each(e.contentCSS,function(t){a+=''});var r=t.body_id||"tinymce";-1!=r.indexOf("=")&&(r=e.getParam("body_id","","hash"),r=r[e.id]||r);var d=t.body_class||"";-1!=d.indexOf("=")&&(d=e.getParam("body_class","","hash"),d=d[e.id]||"");var o=e.settings.directionality?' dir="'+e.settings.directionality+'"':"";if(n=""+a+'"+e.getContent()+"",i)this.getEl("body").firstChild.src="data:text/html;charset=utf-8,"+encodeURIComponent(n);else{var s=this.getEl("body").firstChild.contentWindow.document;s.open(),s.write(n),s.close()}}})}),e.addButton("preview",{title:"Preview",cmd:"mcePreview"}),e.addMenuItem("preview",{text:"Preview",cmd:"mcePreview",context:"view"})});tinymce.PluginManager.add("print",function(t){t.addCommand("mcePrint",function(){t.getWin().print()}),t.addButton("print",{title:"Print",cmd:"mcePrint"}),t.addShortcut("Ctrl+P","","mcePrint"),t.addMenuItem("print",{text:"Print",cmd:"mcePrint",icon:"print",shortcut:"Ctrl+P",context:"file"})});tinymce.PluginManager.add("save",function(e){function a(){var a;return a=tinymce.DOM.getParent(e.id,"form"),!e.getParam("save_enablewhendirty",!0)||e.isDirty()?(tinymce.triggerSave(),e.getParam("save_onsavecallback")?void(e.execCallback("save_onsavecallback",e)&&(e.startContent=tinymce.trim(e.getContent({format:"raw"})),e.nodeChanged())):void(a?(e.isNotDirty=!0,(!a.onsubmit||a.onsubmit())&&("function"==typeof a.submit?a.submit():e.windowManager.alert("Error: Form submit field collision.")),e.nodeChanged()):e.windowManager.alert("Error: No form element found."))):void 0}function n(){var a=tinymce.trim(e.startContent);return e.getParam("save_oncancelcallback")?void e.execCallback("save_oncancelcallback",e):(e.setContent(a),e.undoManager.clear(),void e.nodeChanged())}function t(){var a=this;e.on("nodeChange",function(){a.disabled(e.getParam("save_enablewhendirty",!0)&&!e.isDirty())})}e.addCommand("mceSave",a),e.addCommand("mceCancel",n),e.addButton("save",{icon:"save",text:"Save",cmd:"mceSave",disabled:!0,onPostRender:t}),e.addButton("cancel",{text:"Cancel",icon:!1,cmd:"mceCancel",disabled:!0,onPostRender:t}),e.addShortcut("ctrl+s","","mceSave")});!function(){function e(e,t,n,a,r){function i(e,t){if(t=t||0,!e[0])throw"findAndReplaceDOMText cannot handle zero-length matches";var n=e.index;if(t>0){var a=e[t];if(!a)throw"Invalid capture group";n+=e[0].indexOf(a),e[0]=a}return[n,n+e[0].length,[e[0]]]}function d(e){var t;if(3===e.nodeType)return e.data;if(h[e.nodeName]&&!u[e.nodeName])return"";if(t="",(u[e.nodeName]||m[e.nodeName])&&(t+="\n"),e=e.firstChild)do t+=d(e);while(e=e.nextSibling);return t}function o(e,t,n){var a,r,i,d,o=[],l=0,c=e,s=t.shift(),f=0;e:for(;;){if((u[c.nodeName]||m[c.nodeName])&&l++,3===c.nodeType&&(!r&&c.length+l>=s[1]?(r=c,d=s[1]-l):a&&o.push(c),!a&&c.length+l>s[0]&&(a=c,i=s[0]-l),l+=c.length),a&&r){if(c=n({startNode:a,startNodeIndex:i,endNode:r,endNodeIndex:d,innerNodes:o,match:s[2],matchIndex:f}),l-=r.length-d,a=null,r=null,o=[],s=t.shift(),f++,!s)break}else{if((!h[c.nodeName]||u[c.nodeName])&&c.firstChild){c=c.firstChild;continue}if(c.nextSibling){c=c.nextSibling;continue}}for(;;){if(c.nextSibling){c=c.nextSibling;break}if(c.parentNode===e)break e;c=c.parentNode}}}function l(e){var t;if("function"!=typeof e){var n=e.nodeType?e:f.createElement(e);t=function(e,t){var a=n.cloneNode(!1);return a.setAttribute("data-mce-index",t),e&&a.appendChild(f.createTextNode(e)),a}}else t=e;return function(e){var n,a,r,i=e.startNode,d=e.endNode,o=e.matchIndex;if(i===d){var l=i;r=l.parentNode,e.startNodeIndex>0&&(n=f.createTextNode(l.data.substring(0,e.startNodeIndex)),r.insertBefore(n,l));var c=t(e.match[0],o);return r.insertBefore(c,l),e.endNodeIndexh;++h){var g=e.innerNodes[h],p=t(g.data,o);g.parentNode.replaceChild(p,g),u.push(p)}var x=t(d.data.substring(0,e.endNodeIndex),o);return r=i.parentNode,r.insertBefore(n,i),r.insertBefore(s,i),r.removeChild(i),r=d.parentNode,r.insertBefore(x,d),r.insertBefore(a,d),r.removeChild(d),x}}var c,s,f,u,h,m,g=[],p=0;if(f=t.ownerDocument,u=r.getBlockElements(),h=r.getWhiteSpaceElements(),m=r.getShortEndedElements(),s=d(t)){if(e.global)for(;c=e.exec(s);)g.push(i(c,a));else c=s.match(e),g.push(i(c,a));return g.length&&(p=g.length,o(t,g,l(n))),p}}function t(t){function n(){function e(){r.statusbar.find("#next").disabled(!d(s+1).length),r.statusbar.find("#prev").disabled(!d(s-1).length)}function n(){tinymce.ui.MessageBox.alert("Could not find the specified string.",function(){r.find("#find")[0].focus()})}var a={},r=tinymce.ui.Factory.create({type:"window",layout:"flex",pack:"center",align:"center",onClose:function(){t.focus(),c.done()},onSubmit:function(t){var i,o,l,f;return t.preventDefault(),o=r.find("#case").checked(),f=r.find("#words").checked(),l=r.find("#find").value(),l.length?a.text==l&&a.caseState==o&&a.wholeWord==f?0===d(s+1).length?void n():(c.next(),void e()):(i=c.find(l,o,f),i||n(),r.statusbar.items().slice(1).disabled(0===i),e(),void(a={text:l,caseState:o,wholeWord:f})):(c.done(!1),void r.statusbar.items().slice(1).disabled(!0))},buttons:[{text:"Find",onclick:function(){r.submit()}},{text:"Replace",disabled:!0,onclick:function(){c.replace(r.find("#replace").value())||(r.statusbar.items().slice(1).disabled(!0),s=-1,a={})}},{text:"Replace all",disabled:!0,onclick:function(){c.replace(r.find("#replace").value(),!0,!0),r.statusbar.items().slice(1).disabled(!0),a={}}},{type:"spacer",flex:1},{text:"Prev",name:"prev",disabled:!0,onclick:function(){c.prev(),e()}},{text:"Next",name:"next",disabled:!0,onclick:function(){c.next(),e()}}],title:"Find and replace",items:{type:"form",padding:20,labelGap:30,spacing:10,items:[{type:"textbox",name:"find",size:40,label:"Find",value:t.selection.getNode().src},{type:"textbox",name:"replace",size:40,label:"Replace with"},{type:"checkbox",name:"case",text:"Match case",label:" "},{type:"checkbox",name:"words",text:"Whole words",label:" "}]}}).renderTo().reflow()}function a(e){var t=e.getAttribute("data-mce-index");return"number"==typeof t?""+t:t}function r(n){var a,r;return r=t.dom.create("span",{"data-mce-bogus":1}),r.className="mce-match-marker",a=t.getBody(),c.done(!1),e(n,a,r,!1,t.schema)}function i(e){var t=e.parentNode;e.firstChild&&t.insertBefore(e.firstChild,e),e.parentNode.removeChild(e)}function d(e){var n,r=[];if(n=tinymce.toArray(t.getBody().getElementsByTagName("span")),n.length)for(var i=0;is&&f[o].setAttribute("data-mce-index",m-1)}return t.undoManager.add(),s=p,n?(g=d(p+1).length>0,c.next()):(g=d(p-1).length>0,c.prev()),!r&&g},c.done=function(e){var n,r,d,o;for(r=tinymce.toArray(t.getBody().getElementsByTagName("span")),n=0;n=d.end?(r=c,a=d.end-s):o&&l.push(c),!o&&c.length+s>d.start&&(o=c,i=d.start-s),s+=c.length),o&&r){if(c=n({startNode:o,startNodeIndex:i,endNode:r,endNodeIndex:a,innerNodes:l,match:d.text,matchIndex:u}),s-=r.length-a,o=null,r=null,l=[],d=t.shift(),u++,!d)break}else{if((!P[c.nodeName]||S[c.nodeName])&&c.firstChild){c=c.firstChild;continue}if(c.nextSibling){c=c.nextSibling;continue}}for(;;){if(c.nextSibling){c=c.nextSibling;break}if(c.parentNode===e)break e;c=c.parentNode}}}function i(e){function t(t,n){var o=w[n];o.stencil||(o.stencil=e(o));var r=o.stencil.cloneNode(!1);return r.setAttribute("data-mce-index",n),t&&r.appendChild(k.doc.createTextNode(t)),r}return function(e){var n,o,r,i=e.startNode,a=e.endNode,l=e.matchIndex,s=k.doc;if(i===a){var c=i;r=c.parentNode,e.startNodeIndex>0&&(n=s.createTextNode(c.data.substring(0,e.startNodeIndex)),r.insertBefore(n,c));var d=t(e.match,l);return r.insertBefore(d,c),e.endNodeIndexm;++m){var g=e.innerNodes[m],h=t(g.data,l);g.parentNode.replaceChild(h,g),f.push(h)}var v=t(a.data.substring(0,e.endNodeIndex),l);return r=i.parentNode,r.insertBefore(n,i),r.insertBefore(u,i),r.removeChild(i),r=a.parentNode,r.insertBefore(v,a),r.insertBefore(o,a),r.removeChild(a),v}}function a(e){var t=e.parentNode;t.insertBefore(e.firstChild,e),e.parentNode.removeChild(e)}function l(t){var n=e.getElementsByTagName("*"),o=[];t="number"==typeof t?""+t:null;for(var r=0;rt&&e(w[t],t)!==!1;t++);return this}function u(t){return w.length&&r(e,w,i(t)),this}function f(e,t){if(C&&e.global)for(;x=e.exec(C);)w.push(n(x,t));return this}function m(e){var t,n=l(e?s(e):null);for(t=n.length;t--;)a(n[t]);return this}function p(e){return w[e.getAttribute("data-mce-index")]}function g(e){return l(s(e))[0]}function h(e,t,n){return w.push({start:e,end:e+t,text:C.substr(e,t),data:n}),this}function v(e){var n=l(s(e)),o=t.dom.createRng();return o.setStartBefore(n[0]),o.setEndAfter(n[n.length-1]),o}function b(e,n){var o=v(e);return o.deleteContents(),n.length>0&&o.insertNode(t.dom.doc.createTextNode(n)),o}function y(){return w.splice(0,w.length),m(),this}var x,w=[],C,k=t.dom,S,P,N;return S=t.schema.getBlockElements(),P=t.schema.getWhiteSpaceElements(),N=t.schema.getShortEndedElements(),C=o(e),{text:C,matches:w,each:d,filter:c,reset:y,matchFromElement:p,elementFromMatch:g,find:f,add:h,wrap:u,unwrap:m,replace:b,rangeFromMatch:v,indexOf:s}}}),o(c,[s,d,u,f,m,p,g,h],function(e,t,n,o,r,i,a,l){t.add("spellchecker",function(t,s){function c(){return C.textMatcher||(C.textMatcher=new e(t.getBody(),t)),C.textMatcher}function d(e,t){var o=[];return n.each(t,function(e){o.push({selectable:!0,text:e.name,data:e.value})}),o}function u(e){for(var t in e)return!1;return!0}function f(e,i){var a=[],l=k[e];n.each(l,function(e){a.push({text:e,onclick:function(){t.insertContent(t.dom.encode(e)),t.dom.remove(i),g()}})}),a.push.apply(a,[{text:"-"},{text:"Ignore",onclick:function(){h(e,i)}},{text:"Ignore all",onclick:function(){h(e,i,!0)}},{text:"Finish",onclick:v}]),P=new o({items:a,context:"contextmenu",onautohide:function(e){-1!=e.target.className.indexOf("spellchecker")&&e.preventDefault()},onhide:function(){P.remove(),P=null}}),P.renderTo(document.body);var s=r.DOM.getPos(t.getContentAreaContainer()),c=t.dom.getPos(i[0]),d=t.dom.getRoot();"BODY"==d.nodeName?(c.x-=d.ownerDocument.documentElement.scrollLeft||d.scrollLeft,c.y-=d.ownerDocument.documentElement.scrollTop||d.scrollTop):(c.x-=d.scrollLeft,c.y-=d.scrollTop),s.x+=c.x,s.y+=c.y,P.moveTo(s.x,s.y+i[0].offsetHeight)}function m(){return t.getParam("spellchecker_wordchar_pattern")||new RegExp('[^\\s!"#$%&()*+,-./:;<=>?@[\\]^_{|}`\xa7\xa9\xab\xae\xb1\xb6\xb7\xb8\xbb\xbc\xbd\xbe\xbf\xd7\xf7\xa4\u201d\u201c\u201e]+',"g")}function p(){function e(e){return t.setProgressState(!1),u(e)?(t.windowManager.alert("No misspellings found"),void(S=!1)):(k=e,c().find(m()).filter(function(t){return!!e[t.text]}).wrap(function(e){return t.dom.create("span",{"class":"mce-spellchecker-word","data-mce-bogus":1,"data-mce-word":e.text})}),void t.fire("SpellcheckStart"))}function n(e){t.windowManager.alert(e),t.setProgressState(!1),v()}function o(e,t,o){i.send({url:new a(s).toAbsolute(N.spellchecker_rpc_url),type:"post",content_type:"application/x-www-form-urlencoded",data:"text="+encodeURIComponent(t)+"&lang="+N.spellchecker_language,success:function(e){e=l.parse(e),e?e.error?n(e.error):o(e.words):n("Sever response wasn't proper JSON.")},error:function(e,t){n("Spellchecker request error: "+t.status)}})}if(S)return void v();v(),S=!0,t.setProgressState(!0);var r=N.spellchecker_callback||o;r.call(C,"spellcheck",c().text,e,n),t.focus()}function g(){t.dom.select("span.mce-spellchecker-word").length||v()}function h(e,o,r){t.selection.collapse(),r?n.each(t.dom.select("span.mce-spellchecker-word"),function(n){n.getAttribute("data-mce-word")==e&&t.dom.remove(n,!0)}):t.dom.remove(o,!0),g()}function v(){c().reset(),C.textMatcher=null,S&&(S=!1,t.fire("SpellcheckEnd"))}function b(e){var t=e.getAttribute("data-mce-index");return"number"==typeof t?""+t:t}function y(e){var o,r=[];if(o=n.toArray(t.getBody().getElementsByTagName("span")),o.length)for(var i=0;i0){var r=t.dom.createRng();r.setStartBefore(o[0]),r.setEndAfter(o[o.length-1]),t.selection.setRng(r),f(n.getAttribute("data-mce-word"),o)}}}),t.addMenuItem("spellchecker",{text:"Spellcheck",context:"tools",onclick:p,selectable:!0,onPostRender:function(){var e=this;t.on("SpellcheckStart SpellcheckEnd",function(){e.active(S)})}});var T={tooltip:"Spellcheck",onclick:p,onPostRender:function(){var e=this;t.on("SpellcheckStart SpellcheckEnd",function(){e.active(S)})}};w.length>1&&(T.type="splitbutton",T.menu=w,T.onshow=x,T.onselect=function(e){N.spellchecker_language=e.control.settings.data}),t.addButton("spellchecker",T),t.addCommand("mceSpellCheck",p),t.on("remove",function(){P&&(P.remove(),P=null)}),t.on("change",g),this.getTextMatcher=c,this.getWordCharPattern=m,this.getLanguage=function(){return N.spellchecker_language},N.spellchecker_language=N.spellchecker_language||N.language||"en"})}),a([s,c])}(this);tinymce.PluginManager.add("tabfocus",function(e){function n(e){9!==e.keyCode||e.ctrlKey||e.altKey||e.metaKey||e.preventDefault()}function t(n){function t(n){function t(e){return"BODY"===e.nodeName||"hidden"!=e.type&&"none"!=e.style.display&&"hidden"!=e.style.visibility&&t(e.parentNode)}function r(e){return e.tabIndex||"INPUT"==e.nodeName||"TEXTAREA"==e.nodeName}function c(e){return!r(e)&&"-1"!=e.getAttribute("tabindex")&&t(e)}if(u=i.select(":input:enabled,*[tabindex]:not(iframe)"),o(u,function(n,t){return n.id==e.id?(a=t,!1):void 0}),n>0){for(d=a+1;d=0;d--)if(c(u[d]))return u[d];return null}var a,u,c,d;if(!(9!==n.keyCode||n.ctrlKey||n.altKey||n.metaKey)&&(c=r(e.getParam("tab_focus",e.getParam("tabfocus_elements",":prev,:next"))),1==c.length&&(c[1]=c[0],c[0]=":prev"),u=n.shiftKey?":prev"==c[0]?t(-1):i.get(c[0]):":next"==c[1]?t(1):i.get(c[1]))){var y=tinymce.get(u.id||u.name);u.id&&y?y.focus():window.setTimeout(function(){tinymce.Env.webkit||window.focus(),u.focus()},10),n.preventDefault()}}var i=tinymce.DOM,o=tinymce.each,r=tinymce.explode;e.on("init",function(){e.inline&&tinymce.DOM.setAttrib(e.getBody(),"tabIndex",null)}),e.on("keyup",n),tinymce.Env.gecko?e.on("keypress keydown",t):e.on("keydown",t)});!function(e,t){"use strict";function n(e,t){for(var n,o=[],i=0;i "+t+" tr",a);i(n,function(n,r){r+=e,i(I.select("> td, > th",n),function(e,n){var i,a,l,s;if(A[r])for(;A[r][n];)n++;for(l=o(e,"rowspan"),s=o(e,"colspan"),a=r;r+l>a;a++)for(A[a]||(A[a]=[]),i=n;n+s>i;i++)A[a][i]={part:t,real:a==r&&i==n,elm:e,rowspan:l,colspan:s}})}),e+=n.length})}function s(e,t){return e=e.cloneNode(t),e.removeAttribute("id"),e}function c(e,t){var n;return n=A[t],n?n[e]:void 0}function d(e,t,n){e&&(n=parseInt(n,10),1===n?e.removeAttribute(t,1):e.setAttribute(t,n,1))}function u(e){return e&&(I.hasClass(e.elm,"mce-item-selected")||e==M)}function f(){var e=[];return i(a.rows,function(t){i(t.cells,function(n){return I.hasClass(n,"mce-item-selected")||M&&n==M.elm?(e.push(t),!1):void 0})}),e}function m(){var e=I.createRng();e.setStartAfter(a),e.setEndAfter(a),E.setRng(e),I.remove(a)}function p(t){var o,a={};return r.settings.table_clone_elements!==!1&&(a=e.makeMap((r.settings.table_clone_elements||"strong em b i span font h1 h2 h3 h4 h5 h6 p div").toUpperCase(),/[ ,]/)),e.walk(t,function(e){var r;return 3==e.nodeType?(i(I.getParents(e.parentNode,null,t).reverse(),function(e){a[e.nodeName]&&(e=s(e,!1),o?r&&r.appendChild(e):o=r=e,r=e)}),r&&(r.innerHTML=n.ie?" ":'
    '),!1):void 0},"childNodes"),t=s(t,!1),d(t,"rowSpan",1),d(t,"colSpan",1),o?t.appendChild(o):n.ie||(t.innerHTML='
    '),t}function g(){var e=I.createRng(),t;return i(I.select("tr",a),function(e){0===e.cells.length&&I.remove(e)}),0===I.select("tr",a).length?(e.setStartBefore(a),e.setEndBefore(a),E.setRng(e),void I.remove(a)):(i(I.select("thead,tbody,tfoot",a),function(e){0===e.rows.length&&I.remove(e)}),l(),void(B&&(t=A[Math.min(A.length-1,B.y)],t&&(E.select(t[Math.min(t.length-1,B.x)].elm,!0),E.collapse(!0)))))}function h(e,t,n,o){var i,r,a,l,s;for(i=A[t][e].elm.parentNode,a=1;n>=a;a++)if(i=I.getNext(i,"tr")){for(r=e;r>=0;r--)if(s=A[t+a][r].elm,s.parentNode==i){for(l=1;o>=l;l++)I.insertAfter(p(s),s);break}if(-1==r)for(l=1;o>=l;l++)i.insertBefore(p(i.cells[0]),i.cells[0])}}function v(){i(A,function(e,t){i(e,function(e,n){var i,r,a;if(u(e)&&(e=e.elm,i=o(e,"colspan"),r=o(e,"rowspan"),i>1||r>1)){for(d(e,"rowSpan",1),d(e,"colSpan",1),a=0;i-1>a;a++)I.insertAfter(p(e),e);h(n,t,r-1,i)}})})}function b(t,n,o){var r,a,s,f,m,p,h,b,y,w,x;if(t?(r=T(t),a=r.x,s=r.y,f=a+(n-1),m=s+(o-1)):(B=D=null,i(A,function(e,t){i(e,function(e,n){u(e)&&(B||(B={x:n,y:t}),D={x:n,y:t})})}),B&&(a=B.x,s=B.y,f=D.x,m=D.y)),b=c(a,s),y=c(f,m),b&&y&&b.part==y.part){for(v(),l(),b=c(a,s).elm,d(b,"colSpan",f-a+1),d(b,"rowSpan",m-s+1),h=s;m>=h;h++)for(p=a;f>=p;p++)A[h]&&A[h][p]&&(t=A[h][p].elm,t!=b&&(w=e.grep(t.childNodes),i(w,function(e){b.appendChild(e)}),w.length&&(w=e.grep(b.childNodes),x=0,i(w,function(e){"BR"==e.nodeName&&I.getAttrib(e,"data-mce-bogus")&&x++0&&A[n-1][l]&&(g=A[n-1][l].elm,h=o(g,"rowSpan"),h>1)){d(g,"rowSpan",h+1);continue}}else if(h=o(r,"rowspan"),h>1){d(r,"rowSpan",h+1);continue}m=p(r),d(m,"colSpan",r.colSpan),f.appendChild(m),a=r}f.hasChildNodes()&&(e?c.parentNode.insertBefore(f,c):I.insertAfter(f,c))}}function w(e){var t,n;i(A,function(n){return i(n,function(n,o){return u(n)&&(t=o,e)?!1:void 0}),e?!t:void 0}),i(A,function(i,r){var a,l,s;i[t]&&(a=i[t].elm,a!=n&&(s=o(a,"colspan"),l=o(a,"rowspan"),1==s?e?(a.parentNode.insertBefore(p(a),a),h(t,r,l-1,s)):(I.insertAfter(p(a),a),h(t,r,l-1,s)):d(a,"colSpan",a.colSpan+1),n=a))})}function x(){var t=[];i(A,function(n){i(n,function(n,r){u(n)&&-1===e.inArray(t,r)&&(i(A,function(e){var t=e[r].elm,n;n=o(t,"colSpan"),n>1?d(t,"colSpan",n-1):I.remove(t)}),t.push(r))})}),g()}function C(){function e(e){var t,n,r;t=I.getNext(e,"tr"),i(e.cells,function(e){var t=o(e,"rowSpan");t>1&&(d(e,"rowSpan",t-1),n=T(e),h(n.x,n.y,1,1))}),n=T(e.cells[0]),i(A[n.y],function(e){var t;e=e.elm,e!=r&&(t=o(e,"rowSpan"),1>=t?I.remove(e):d(e,"rowSpan",t-1),r=e)})}var t;t=f(),i(t.reverse(),function(t){e(t)}),g()}function P(){var e=f();return I.remove(e),g(),e}function S(){var e=f();return i(e,function(t,n){e[n]=s(t,!0)}),e}function R(e,t){var n=f(),o=n[t?0:n.length-1],r=o.cells.length;e&&(i(A,function(e){var t;return r=0,i(e,function(e){e.real&&(r+=e.colspan),e.elm.parentNode==o&&(t=1)}),t?!1:void 0}),t||e.reverse(),i(e,function(e){var n,i=e.cells.length,a;for(n=0;i>n;n++)a=e.cells[n],d(a,"colSpan",1),d(a,"rowSpan",1);for(n=i;r>n;n++)e.appendChild(p(e.cells[i-1]));for(n=r;i>n;n++)I.remove(e.cells[n]);t?o.parentNode.insertBefore(e,o):I.insertAfter(e,o)}),I.removeClass(I.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"))}function T(e){var t;return i(A,function(n,o){return i(n,function(n,i){return n.elm==e?(t={x:i,y:o},!1):void 0}),!t}),t}function k(e){B=T(e)}function N(){var e,t;return e=t=0,i(A,function(n,o){i(n,function(n,i){var r,a;u(n)&&(n=A[o][i],i>e&&(e=i),o>t&&(t=o),n.real&&(r=n.colspan-1,a=n.rowspan-1,r&&i+r>e&&(e=i+r),a&&o+a>t&&(t=o+a)))})}),{x:e,y:t}}function _(e){var t,n,o,i,r,a,l,s,c,d;if(D=T(e),B&&D){for(t=Math.min(B.x,D.x),n=Math.min(B.y,D.y),o=Math.max(B.x,D.x),i=Math.max(B.y,D.y),r=o,a=i,d=n;a>=d;d++)e=A[d][t],e.real||t-(e.colspan-1)=c;c++)e=A[n][c],e.real||n-(e.rowspan-1)=d;d++)for(c=t;o>=c;c++)e=A[d][c],e.real&&(l=e.colspan-1,s=e.rowspan-1,l&&c+l>r&&(r=c+l),s&&d+s>a&&(a=d+s));for(I.removeClass(I.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"),d=n;a>=d;d++)for(c=t;r>=c;c++)A[d][c]&&I.addClass(A[d][c].elm,"mce-item-selected")}}var A,B,D,M,E=r.selection,I=E.dom;a=a||I.getParent(E.getStart(),"table"),l(),M=I.getParent(E.getStart(),"th,td"),M&&(B=T(M),D=N(),M=c(B.x,B.y)),e.extend(this,{deleteTable:m,split:v,merge:b,insertRow:y,insertCol:w,deleteCols:x,deleteRows:C,cutRows:P,copyRows:S,pasteRows:R,getPos:T,setStartCell:k,setEndCell:_})}}),o(u,[f,d,c],function(e,t,n){function o(e,t){return parseInt(e.getAttribute(t)||1,10)}var i=n.each;return function(n){function r(){function t(t){function r(e,o){var i=e?"previousSibling":"nextSibling",r=n.dom.getParent(o,"tr"),l=r[i];if(l)return h(n,o,l,e),t.preventDefault(),!0;var d=n.dom.getParent(r,"table"),u=r.parentNode,f=u.nodeName.toLowerCase();if("tbody"===f||f===(e?"tfoot":"thead")){var m=a(e,d,u,"tbody");if(null!==m)return s(e,m,o)}return c(e,r,i,d)}function a(e,t,o,i){var r=n.dom.select(">"+i,t),a=r.indexOf(o);if(e&&0===a||!e&&a===r.length-1)return l(e,t);if(-1===a){var s="thead"===o.tagName.toLowerCase()?0:r.length-1;return r[s]}return r[a+(e?-1:1)]}function l(e,t){var o=e?"thead":"tfoot",i=n.dom.select(">"+o,t);return 0!==i.length?i[0]:null}function s(e,o,i){var r=d(o,e);return r&&h(n,i,r,e),t.preventDefault(),!0}function c(e,o,i,a){var l=a[i];if(l)return u(l),!0;var s=n.dom.getParent(a,"td,th");if(s)return r(e,s,t);var c=d(o,!e);return u(c),t.preventDefault(),!1}function d(e,t){var o=e&&e[t?"lastChild":"firstChild"];return o&&"BR"===o.nodeName?n.dom.getParent(o,"td,th"):o}function u(e){n.selection.setCursorLocation(e,0)}function f(){return y==e.UP||y==e.DOWN}function m(e){var t=e.selection.getNode(),n=e.dom.getParent(t,"tr");return null!==n}function p(e){for(var t=0,n=e;n.previousSibling;)n=n.previousSibling,t+=o(n,"colspan");return t}function g(e,t){var n=0,r=0;return i(e.children,function(e,i){return n+=o(e,"colspan"),r=i,n>t?!1:void 0}),r}function h(e,t,o,i){var r=p(n.dom.getParent(t,"td,th")),a=g(o,r),l=o.childNodes[a],s=d(l,i);u(s||l)}function v(e){var t=n.selection.getNode(),o=n.dom.getParent(t,"td,th"),i=n.dom.getParent(e,"td,th");return o&&o!==i&&b(o,i)}function b(e,t){return n.dom.getParent(e,"TABLE")===n.dom.getParent(t,"TABLE")}var y=t.keyCode;if(f()&&m(n)){var w=n.selection.getNode();setTimeout(function(){v(w)&&r(!t.shiftKey&&y===e.UP,w,t)},0)}}n.on("KeyDown",function(e){t(e)})}function a(){function e(e,t){var n=t.ownerDocument,o=n.createRange(),i;return o.setStartBefore(t),o.setEnd(e.endContainer,e.endOffset),i=n.createElement("body"),i.appendChild(o.cloneContents()),0===i.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi,"-").replace(/<[^>]+>/g,"").length}n.on("KeyDown",function(t){var o,i,r=n.dom;(37==t.keyCode||38==t.keyCode)&&(o=n.selection.getRng(),i=r.getParent(o.startContainer,"table"),i&&n.getBody().firstChild==i&&e(o,i)&&(o=r.createRng(),o.setStartBefore(i),o.setEndBefore(i),n.selection.setRng(o),t.preventDefault()))})}function l(){n.on("KeyDown SetContent VisualAid",function(){var e;for(e=n.getBody().lastChild;e;e=e.previousSibling)if(3==e.nodeType){if(e.nodeValue.length>0)break}else if(1==e.nodeType&&!e.getAttribute("data-mce-bogus"))break;e&&"TABLE"==e.nodeName&&(n.settings.forced_root_block?n.dom.add(n.getBody(),n.settings.forced_root_block,n.settings.forced_root_block_attrs,t.ie&&t.ie<11?" ":'
    '):n.dom.add(n.getBody(),"br",{"data-mce-bogus":"1"}))}),n.on("PreProcess",function(e){var t=e.node.lastChild;t&&("BR"==t.nodeName||1==t.childNodes.length&&("BR"==t.firstChild.nodeName||"\xa0"==t.firstChild.nodeValue))&&t.previousSibling&&"TABLE"==t.previousSibling.nodeName&&n.dom.remove(t)})}function s(){function e(e,t,n,o){var i=3,r=e.dom.getParent(t.startContainer,"TABLE"),a,l,s;return r&&(a=r.parentNode),l=t.startContainer.nodeType==i&&0===t.startOffset&&0===t.endOffset&&o&&("TR"==n.nodeName||n==a),s=("TD"==n.nodeName||"TH"==n.nodeName)&&!o,l||s}function t(){var t=n.selection.getRng(),o=n.selection.getNode(),i=n.dom.getParent(t.startContainer,"TD,TH");if(e(n,t,o,i)){i||(i=o);for(var r=i.lastChild;r.lastChild;)r=r.lastChild;t.setEnd(r,r.nodeValue.length),n.selection.setRng(t)}}n.on("KeyDown",function(){t()}),n.on("MouseDown",function(e){2!=e.button&&t()})}function c(){n.on("keydown",function(t){if((t.keyCode==e.DELETE||t.keyCode==e.BACKSPACE)&&!t.isDefaultPrevented()){var o=n.dom.getParent(n.selection.getStart(),"table");if(o){for(var i=n.dom.select("td,th",o),r=i.length;r--;)if(!n.dom.hasClass(i[r],"mce-item-selected"))return;t.preventDefault(),n.execCommand("mceTableDelete")}}})}c(),t.webkit&&(r(),s()),t.gecko&&(a(),l()),t.ie>10&&(a(),l())}}),o(m,[s,p,c],function(e,t,n){return function(o){function i(){o.getBody().style.webkitUserSelect="",d&&(o.dom.removeClass(o.dom.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"),d=!1)}function r(t){var n,i,r=t.target;if(s&&(l||r!=s)&&("TD"==r.nodeName||"TH"==r.nodeName)){i=a.getParent(r,"table"),i==c&&(l||(l=new e(o,i),l.setStartCell(s),o.getBody().style.webkitUserSelect="none"),l.setEndCell(r),d=!0),n=o.selection.getSel();try{n.removeAllRanges?n.removeAllRanges():n.empty()}catch(u){}t.preventDefault()}}var a=o.dom,l,s,c,d=!0;return o.on("MouseDown",function(e){2!=e.button&&(i(),s=a.getParent(e.target,"td,th"),c=a.getParent(s,"table"))}),o.on("mouseover",r),o.on("remove",function(){a.unbind(o.getDoc(),"mouseover",r)}),o.on("MouseUp",function(){function e(e,o){var r=new t(e,e);do{if(3==e.nodeType&&0!==n.trim(e.nodeValue).length)return void(o?i.setStart(e,0):i.setEnd(e,e.nodeValue.length));if("BR"==e.nodeName)return void(o?i.setStartBefore(e):i.setEndBefore(e))}while(e=o?r.next():r.prev())}var i,r=o.selection,d,u,f,m,p;if(s){if(l&&(o.getBody().style.webkitUserSelect=""),d=a.select("td.mce-item-selected,th.mce-item-selected"),d.length>0){i=a.createRng(),f=d[0],p=d[d.length-1],i.setStartBefore(f),i.setEndAfter(f),e(f,1),u=new t(f,a.getParent(d[0],"table"));do if("TD"==f.nodeName||"TH"==f.nodeName){if(!a.hasClass(f,"mce-item-selected"))break;m=f}while(f=u.next());e(m),r.setRng(i)}o.nodeChanged(),s=l=c=null}}),o.on("KeyUp Drop",function(){i(),s=l=c=null}),{clear:i}}}),o(g,[s,u,m,c,p,d,h],function(e,t,n,o,i,r,a){function l(o){function i(e){return e?e.replace(/px$/,""):""}function a(e){return/^[0-9]+$/.test(e)&&(e+="px"),e}function l(e){s("left center right".split(" "),function(t){o.formatter.remove("align"+t,{},e)})}function c(e){s("top middle bottom".split(" "),function(t){o.formatter.remove("valign"+t,{},e)})}function d(){var e=o.dom,t,n,c,d;t=e.getParent(o.selection.getStart(),"table"),d={width:i(e.getStyle(t,"width")||e.getAttrib(t,"width")),height:i(e.getStyle(t,"height")||e.getAttrib(t,"height")),cellspacing:t?e.getAttrib(t,"cellspacing"):"",cellpadding:t?e.getAttrib(t,"cellpadding"):"",border:t?e.getAttrib(t,"border"):"",caption:!!e.select("caption",t)[0]},s("left center right".split(" "),function(e){o.formatter.matchNode(t,"align"+e)&&(d.align=e)}),t||(n={label:"Cols",name:"cols"},c={label:"Rows",name:"rows"}),o.windowManager.open({title:"Table properties",items:{type:"form",layout:"grid",columns:2,data:d,defaults:{type:"textbox",maxWidth:50},items:[n,c,{label:"Width",name:"width"},{label:"Height",name:"height"},{label:"Cell spacing",name:"cellspacing"},{label:"Cell padding",name:"cellpadding"},{label:"Border",name:"border"},{label:"Caption",name:"caption",type:"checkbox"},{label:"Alignment",minWidth:90,name:"align",type:"listbox",text:"None",maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]}]},onsubmit:function(){var n=this.toJSON(),i;o.undoManager.transact(function(){t||(t=g(n.cols||1,n.rows||1)),o.dom.setAttribs(t,{cellspacing:n.cellspacing,cellpadding:n.cellpadding,border:n.border}),o.dom.setStyles(t,{width:a(n.width),height:a(n.height)}),i=e.select("caption",t)[0],i&&!n.caption&&e.remove(i),!i&&n.caption&&(i=e.create("caption"),i.innerHTML=r.ie?"\xa0":'
    ',t.insertBefore(i,t.firstChild)),l(t),n.align&&o.formatter.apply("align"+n.align,{},t),o.focus(),o.addVisual()})}})}function u(e,t){o.windowManager.open({title:"Merge cells",body:[{label:"Cols",name:"cols",type:"textbox",size:10},{label:"Rows",name:"rows",type:"textbox",size:10}],onsubmit:function(){var n=this.toJSON();o.undoManager.transact(function(){e.merge(t,n.cols,n.rows)})}})}function f(){var e=o.dom,t,n,r=[];r=o.dom.select("td.mce-item-selected,th.mce-item-selected"),t=o.dom.getParent(o.selection.getStart(),"td,th"),!r.length&&t&&r.push(t),t=t||r[0],t&&(n={width:i(e.getStyle(t,"width")||e.getAttrib(t,"width")),height:i(e.getStyle(t,"height")||e.getAttrib(t,"height")),scope:e.getAttrib(t,"scope")},n.type=t.nodeName.toLowerCase(),s("left center right".split(" "),function(e){o.formatter.matchNode(t,"align"+e)&&(n.align=e)}),s("top middle bottom".split(" "),function(e){o.formatter.matchNode(t,"valign"+e)&&(n.valign=e)}),o.windowManager.open({title:"Cell properties",items:{type:"form",data:n,layout:"grid",columns:2,defaults:{type:"textbox",maxWidth:50},items:[{label:"Width",name:"width"},{label:"Height",name:"height"},{label:"Cell type",name:"type",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"Cell",value:"td"},{text:"Header cell",value:"th"}]},{label:"Scope",name:"scope",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"None",value:""},{text:"Row",value:"row"},{text:"Column",value:"col"},{text:"Row group",value:"rowgroup"},{text:"Column group",value:"colgroup"}]},{label:"H Align",name:"align",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]},{label:"V Align",name:"valign",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"None",value:""},{text:"Top",value:"top"},{text:"Middle",value:"middle"},{text:"Bottom",value:"bottom"}]}]},onsubmit:function(){var t=this.toJSON();o.undoManager.transact(function(){s(r,function(n){o.dom.setAttrib(n,"scope",t.scope),o.dom.setStyles(n,{width:a(t.width),height:a(t.height)}),t.type&&n.nodeName.toLowerCase()!=t.type&&(n=e.rename(n,t.type)),l(n),t.align&&o.formatter.apply("align"+t.align,{},n),c(n),t.valign&&o.formatter.apply("valign"+t.valign,{},n)}),o.focus()})}}))}function m(){var e=o.dom,t,n,r,c,d=[];t=o.dom.getParent(o.selection.getStart(),"table"),n=o.dom.getParent(o.selection.getStart(),"td,th"),s(t.rows,function(t){s(t.cells,function(o){return e.hasClass(o,"mce-item-selected")||o==n?(d.push(t),!1):void 0})}),r=d[0],r&&(c={height:i(e.getStyle(r,"height")||e.getAttrib(r,"height")),scope:e.getAttrib(r,"scope")},c.type=r.parentNode.nodeName.toLowerCase(),s("left center right".split(" "),function(e){o.formatter.matchNode(r,"align"+e)&&(c.align=e)}),o.windowManager.open({title:"Row properties",items:{type:"form",data:c,columns:2,defaults:{type:"textbox"},items:[{type:"listbox",name:"type",label:"Row type",text:"None",maxWidth:null,values:[{text:"Header",value:"thead"},{text:"Body",value:"tbody"},{text:"Footer",value:"tfoot"}]},{type:"listbox",name:"align",label:"Alignment",text:"None",maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]},{label:"Height",name:"height"}]},onsubmit:function(){var t=this.toJSON(),n,i,r;o.undoManager.transact(function(){var c=t.type;s(d,function(s){o.dom.setAttrib(s,"scope",t.scope),o.dom.setStyles(s,{height:a(t.height)}),c!=s.parentNode.nodeName.toLowerCase()&&(n=e.getParent(s,"table"),i=s.parentNode,r=e.select(c,n)[0],r||(r=e.create(c),n.firstChild?n.insertBefore(r,n.firstChild):n.appendChild(r)),r.appendChild(s),i.hasChildNodes()||e.remove(i)),l(s),t.align&&o.formatter.apply("align"+t.align,{},s)}),o.focus()})}}))}function p(e){return function(){o.execCommand(e)}}function g(e,t){var n,i,a;for(a='',n=0;t>n;n++){for(a+="",i=0;e>i;i++)a+="";a+=""}a+="
    "+(r.ie?" ":"
    ")+"
    ",o.insertContent(a);var l=o.dom.get("__mce");return o.dom.setAttrib(l,"id",null),l}function h(e,t){function n(){e.disabled(!o.dom.getParent(o.selection.getStart(),t)),o.selection.selectorChanged(t,function(t){e.disabled(!t)})}o.initialized?n():o.on("init",n)}function v(){h(this,"table")}function b(){h(this,"td,th")}function y(){var e="";e='';for(var t=0;10>t;t++){e+="";for(var n=0;10>n;n++)e+='';e+=""}return e+="
    ",e+='

    '}function w(e,t,n){var i=n.getEl().getElementsByTagName("table")[0],r,a,l,s,c,d=n.isRtl()||"tl-tr"==n.parent().rel;for(i.nextSibling.innerHTML=e+1+" x "+(t+1),d&&(e=9-e),a=0;10>a;a++)for(r=0;10>r;r++)s=i.rows[a].childNodes[r].firstChild,c=(d?r>=e:e>=r)&&t>=a,o.dom.toggleClass(s,"mce-active",c),c&&(l=s);return l.parentNode}var x,C,P=this;o.settings.table_grid===!1?o.addMenuItem("inserttable",{text:"Insert table",icon:"table",context:"table",onclick:d}):o.addMenuItem("inserttable",{text:"Insert table",icon:"table",context:"table",ariaHideMenu:!0,onclick:function(e){e.aria&&(this.parent().hideAll(),e.stopImmediatePropagation(),d())},onshow:function(){w(0,0,this.menu.items()[0])},onhide:function(){var e=this.menu.items()[0].getEl().getElementsByTagName("a");o.dom.removeClass(e,"mce-active"),o.dom.addClass(e[0],"mce-active")},menu:[{type:"container",html:y(),onPostRender:function(){this.lastX=this.lastY=0},onmousemove:function(e){var t=e.target,n,o;"A"==t.tagName.toUpperCase()&&(n=parseInt(t.getAttribute("data-mce-x"),10),o=parseInt(t.getAttribute("data-mce-y"),10),(this.isRtl()||"tl-tr"==this.parent().rel)&&(n=9-n),(n!==this.lastX||o!==this.lastY)&&(w(n,o,e.control),this.lastX=n,this.lastY=o))},onkeydown:function(e){var t=this.lastX,n=this.lastY,o;switch(e.keyCode){case 37:t>0&&(t--,o=!0);break;case 39:o=!0,9>t&&t++;break;case 38:o=!0,n>0&&n--;break;case 40:o=!0,9>n&&n++}o&&(e.preventDefault(),e.stopPropagation(),w(t,n,e.control).focus(),this.lastX=t,this.lastY=n)},onclick:function(e){"A"==e.target.tagName.toUpperCase()&&(e.preventDefault(),e.stopPropagation(),this.parent().cancel(),g(this.lastX+1,this.lastY+1))}}]}),o.addMenuItem("tableprops",{text:"Table properties",context:"table",onPostRender:v,onclick:d}),o.addMenuItem("deletetable",{text:"Delete table",context:"table",onPostRender:v,cmd:"mceTableDelete"}),o.addMenuItem("cell",{separator:"before",text:"Cell",context:"table",menu:[{text:"Cell properties",onclick:p("mceTableCellProps"),onPostRender:b},{text:"Merge cells",onclick:p("mceTableMergeCells"),onPostRender:b},{text:"Split cell",onclick:p("mceTableSplitCells"),onPostRender:b}]}),o.addMenuItem("row",{text:"Row",context:"table",menu:[{text:"Insert row before",onclick:p("mceTableInsertRowBefore"),onPostRender:b},{text:"Insert row after",onclick:p("mceTableInsertRowAfter"),onPostRender:b},{text:"Delete row",onclick:p("mceTableDeleteRow"),onPostRender:b},{text:"Row properties",onclick:p("mceTableRowProps"),onPostRender:b},{text:"-"},{text:"Cut row",onclick:p("mceTableCutRow"),onPostRender:b},{text:"Copy row",onclick:p("mceTableCopyRow"),onPostRender:b},{text:"Paste row before",onclick:p("mceTablePasteRowBefore"),onPostRender:b},{text:"Paste row after",onclick:p("mceTablePasteRowAfter"),onPostRender:b}]}),o.addMenuItem("column",{text:"Column",context:"table",menu:[{text:"Insert column before",onclick:p("mceTableInsertColBefore"),onPostRender:b},{text:"Insert column after",onclick:p("mceTableInsertColAfter"),onPostRender:b},{text:"Delete column",onclick:p("mceTableDeleteCol"),onPostRender:b}]});var S=[];s("inserttable tableprops deletetable | cell row column".split(" "),function(e){S.push("|"==e?{text:"-"}:o.menuItems[e])}),o.addButton("table",{type:"menubutton",title:"Table",menu:S}),r.isIE||o.on("click",function(e){e=e.target,"TABLE"===e.nodeName&&(o.selection.select(e),o.nodeChanged())}),P.quirks=new t(o),o.on("Init",function(){x=o.windowManager,P.cellSelection=new n(o)}),s({mceTableSplitCells:function(e){e.split()},mceTableMergeCells:function(e){var t,n,i;i=o.dom.getParent(o.selection.getStart(),"th,td"),i&&(t=i.rowSpan,n=i.colSpan),o.dom.select("td.mce-item-selected,th.mce-item-selected").length?e.merge():u(e,i)},mceTableInsertRowBefore:function(e){e.insertRow(!0)},mceTableInsertRowAfter:function(e){e.insertRow()},mceTableInsertColBefore:function(e){e.insertCol(!0)},mceTableInsertColAfter:function(e){e.insertCol()},mceTableDeleteCol:function(e){e.deleteCols()},mceTableDeleteRow:function(e){e.deleteRows()},mceTableCutRow:function(e){C=e.cutRows()},mceTableCopyRow:function(e){C=e.copyRows()},mceTablePasteRowBefore:function(e){e.pasteRows(C,!0)},mceTablePasteRowAfter:function(e){e.pasteRows(C)},mceTableDelete:function(e){e.deleteTable()}},function(t,n){o.addCommand(n,function(){var n=new e(o);n&&(t(n),o.execCommand("mceRepaint"),P.cellSelection.clear())})}),s({mceInsertTable:function(){d()},mceTableRowProps:m,mceTableCellProps:f},function(e,t){o.addCommand(t,function(t,n){e(n)})})}var s=o.each;a.add("table",l)}),a([s,u,m,g])}(this);tinymce.PluginManager.add("template",function(e){function t(t){return function(){var a=e.settings.templates;"string"==typeof a?tinymce.util.XHR.send({url:a,success:function(e){t(tinymce.util.JSON.parse(e))}}):t(a)}}function a(t){function a(t){function a(t){if(-1==t.indexOf("")){var a="";tinymce.each(e.contentCSS,function(t){a+=''}),t=""+a+""+t+""}t=r(t,"template_preview_replace_values");var l=n.find("iframe")[0].getEl().contentWindow.document;l.open(),l.write(t),l.close()}var c=t.control.value();c.url?tinymce.util.XHR.send({url:c.url,success:function(e){l=e,a(l)}}):(l=c.content,a(l)),n.find("#description")[0].text(t.control.value().description)}var n,l,i=[];return t&&0!==t.length?(tinymce.each(t,function(e){i.push({selected:!i.length,text:e.title,value:{url:e.url,content:e.content,description:e.description}})}),n=e.windowManager.open({title:"Insert template",layout:"flex",direction:"column",align:"stretch",padding:15,spacing:10,items:[{type:"form",flex:0,padding:0,items:[{type:"container",label:"Templates",items:{type:"listbox",label:"Templates",name:"template",values:i,onselect:a}}]},{type:"label",name:"description",label:"Description",text:" "},{type:"iframe",flex:1,border:1}],onsubmit:function(){c(!1,l)},width:e.getParam("template_popup_width",600),height:e.getParam("template_popup_height",500)}),void n.find("listbox")[0].fire("select")):void e.windowManager.alert("No templates defined")}function n(t,a){function n(e,t){if(e=""+e,e.length0&&(o=p.create("div",null),o.appendChild(s[0].cloneNode(!0))),i(p.select("*",o),function(t){c(t,e.getParam("template_cdate_classes","cdate").replace(/\s+/g,"|"))&&(t.innerHTML=n(e.getParam("template_cdate_format",e.getLang("template.cdate_format")))),c(t,e.getParam("template_mdate_classes","mdate").replace(/\s+/g,"|"))&&(t.innerHTML=n(e.getParam("template_mdate_format",e.getLang("template.mdate_format")))),c(t,e.getParam("template_selected_content_classes","selcontent").replace(/\s+/g,"|"))&&(t.innerHTML=m)}),l(o),e.execCommand("mceInsertContent",!1,o.innerHTML),e.addVisual()}var i=tinymce.each;e.addCommand("mceInsertTemplate",c),e.addButton("template",{title:"Insert template",onclick:t(a)}),e.addMenuItem("template",{text:"Insert template",onclick:t(a),context:"insert"}),e.on("PreProcess",function(t){var a=e.dom;i(a.select("div",t.node),function(t){a.hasClass(t,"mceTmpl")&&(i(a.select("*",t),function(t){a.hasClass(t,e.getParam("template_mdate_classes","mdate").replace(/\s+/g,"|"))&&(t.innerHTML=n(e.getParam("template_mdate_format",e.getLang("template.mdate_format"))))}),l(t))})})});tinymce.PluginManager.add("textcolor",function(e){function t(){var t,o,l=[];for(o=e.settings.textcolor_map||["000000","Black","993300","Burnt orange","333300","Dark olive","003300","Dark green","003366","Dark azure","000080","Navy Blue","333399","Indigo","333333","Very dark gray","800000","Maroon","FF6600","Orange","808000","Olive","008000","Green","008080","Teal","0000FF","Blue","666699","Grayish blue","808080","Gray","FF0000","Red","FF9900","Amber","99CC00","Yellow green","339966","Sea green","33CCCC","Turquoise","3366FF","Royal blue","800080","Purple","999999","Medium gray","FF00FF","Magenta","FFCC00","Gold","FFFF00","Yellow","00FF00","Lime","00FFFF","Aqua","00CCFF","Sky blue","993366","Red violet","C0C0C0","Silver","FF99CC","Pink","FFCC99","Peach","FFFF99","Light yellow","CCFFCC","Pale green","CCFFFF","Pale cyan","99CCFF","Light sky blue","CC99FF","Plum","FFFFFF","White"],t=0;t',a=o.length-1,c=e.settings.textcolor_rows||5,i=e.settings.textcolor_cols||8,F=0;c>F;F++){for(r+="",n=0;i>n;n++)d=F*i+n,d>a?r+="":(l=o[d],r+='
    ');r+=""}return r+=""}function l(t){var o,l=this.parent();(o=t.target.getAttribute("data-mce-color"))&&(this.lastId&&document.getElementById(this.lastId).setAttribute("aria-selected",!1),t.target.setAttribute("aria-selected",!0),this.lastId=t.target.id,l.hidePanel(),o="#"+o,l.color(o),e.execCommand(l.settings.selectcmd,!1,o))}function r(){var t=this;t._color&&e.execCommand(t.settings.selectcmd,!1,t._color)}e.addButton("forecolor",{type:"colorbutton",tooltip:"Text color",selectcmd:"ForeColor",panel:{role:"application",ariaRemember:!0,html:o,onclick:l},onclick:r}),e.addButton("backcolor",{type:"colorbutton",tooltip:"Background color",selectcmd:"HiliteColor",panel:{role:"application",ariaRemember:!0,html:o,onclick:l},onclick:r})});tinymce.PluginManager.add("visualblocks",function(e,s){function o(){var s=this;s.active(a),e.on("VisualBlocks",function(){s.active(e.dom.hasClass(e.getBody(),"mce-visualblocks"))})}var l,t,a;window.NodeList&&(e.addCommand("mceVisualBlocks",function(){var o,c=e.dom;l||(l=c.uniqueId(),o=c.create("link",{id:l,rel:"stylesheet",href:s+"/css/visualblocks.css"}),e.getDoc().getElementsByTagName("head")[0].appendChild(o)),e.on("PreviewFormats AfterPreviewFormats",function(s){a&&c.toggleClass(e.getBody(),"mce-visualblocks","afterpreviewformats"==s.type)}),c.toggleClass(e.getBody(),"mce-visualblocks"),a=e.dom.hasClass(e.getBody(),"mce-visualblocks"),t&&t.active(c.hasClass(e.getBody(),"mce-visualblocks")),e.fire("VisualBlocks")}),e.addButton("visualblocks",{title:"Show blocks",cmd:"mceVisualBlocks",onPostRender:o}),e.addMenuItem("visualblocks",{text:"Show blocks",cmd:"mceVisualBlocks",onPostRender:o,selectable:!0,context:"view",prependToContext:!0}),e.on("init",function(){e.settings.visualblocks_default_state&&e.execCommand("mceVisualBlocks",!1,null,{skip_focus:!0})}),e.on("remove",function(){e.dom.removeClass(e.getBody(),"mce-visualblocks")}))});tinymce.PluginManager.add("visualchars",function(e){function a(a){var t,s,i,r,c,d,l=e.getBody(),m=e.selection;if(n=!n,o.state=n,e.fire("VisualChars",{state:n}),a&&(d=m.getBookmark()),n)for(s=[],tinymce.walk(l,function(e){3==e.nodeType&&e.nodeValue&&-1!=e.nodeValue.indexOf(" ")&&s.push(e)},"childNodes"),i=0;i$1
    '),c=e.dom.create("div",null,r);t=c.lastChild;)e.dom.insertAfter(t,s[i]);e.dom.remove(s[i])}else for(s=e.dom.select("span.mce-nbsp",l),i=s.length-1;i>=0;i--)e.dom.remove(s[i],1);m.moveToBookmark(d)}function t(){var a=this;e.on("VisualChars",function(e){a.active(e.state)})}var n,o=this;e.addCommand("mceVisualChars",a),e.addButton("visualchars",{title:"Show invisible characters",cmd:"mceVisualChars",onPostRender:t}),e.addMenuItem("visualchars",{text:"Show invisible characters",cmd:"mceVisualChars",onPostRender:t,selectable:!0,context:"view",prependToContext:!0}),e.on("beforegetcontent",function(e){n&&"raw"!=e.format&&!e.draft&&(n=!0,a(!1))})});tinymce.PluginManager.add("wordcount",function(e){function t(){e.theme.panel.find("#wordcount").text(["Words: {0}",a.getCount()])}var n,o,a=this;n=e.getParam("wordcount_countregex",/[\w\u2019\x27\-\u00C0-\u1FFF]+/g),o=e.getParam("wordcount_cleanregex",/[0-9.(),;:!?%#$?\x27\x22_+=\\\/\-]*/g),e.on("init",function(){var n=e.theme.panel&&e.theme.panel.find("#statusbar")[0];n&&window.setTimeout(function(){n.insert({type:"label",name:"wordcount",text:["Words: {0}",a.getCount()],classes:"wordcount",disabled:e.settings.readonly},0),e.on("setcontent beforeaddundo",t),e.on("keyup",function(e){32==e.keyCode&&t()})},0)}),a.getCount=function(){var t=e.getContent({format:"raw"}),a=0;if(t){t=t.replace(/\.\.\./g," "),t=t.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," "),t=t.replace(/(\w+)(&#?[a-z0-9]+;)+(\w+)/i,"$1$3").replace(/&.+?;/g," "),t=t.replace(o,"");var r=t.match(n);r&&(a=r.length)}return a}});tinymce.ThemeManager.add("modern",function(e){function t(){function t(t){var n,o=[];if(t)return d(t.split(/[ ,]/),function(t){function i(){var i=e.selection;"bullist"==r&&i.selectorChanged("ul > li",function(e,i){for(var n,o=i.parents.length;o--&&(n=i.parents[o].nodeName,"OL"!=n&&"UL"!=n););t.active(e&&"UL"==n)}),"numlist"==r&&i.selectorChanged("ol > li",function(e,i){for(var n,o=i.parents.length;o--&&(n=i.parents[o].nodeName,"OL"!=n&&"UL"!=n););t.active(e&&"OL"==n)}),t.settings.stateSelector&&i.selectorChanged(t.settings.stateSelector,function(e){t.active(e)},!0),t.settings.disabledStateSelector&&i.selectorChanged(t.settings.disabledStateSelector,function(e){t.disabled(e)})}var r;"|"==t?n=null:c.has(t)?(t={type:t},u.toolbar_items_size&&(t.size=u.toolbar_items_size),o.push(t),n=null):(n||(n={type:"buttongroup",items:[]},o.push(n)),e.buttons[t]&&(r=t,t=e.buttons[r],"function"==typeof t&&(t=t()),t.type=t.type||"button",u.toolbar_items_size&&(t.size=u.toolbar_items_size),t=c.create(t),n.items.push(t),e.initialized?i():e.on("init",i)))}),i.push({type:"toolbar",layout:"flow",items:o}),!0}var i=[];if(tinymce.isArray(u.toolbar)){if(0===u.toolbar.length)return;tinymce.each(u.toolbar,function(e,t){u["toolbar"+(t+1)]=e}),delete u.toolbar}for(var n=1;10>n&&t(u["toolbar"+n]);n++);return i.length||u.toolbar===!1||t(u.toolbar||f),i.length?{type:"panel",layout:"stack",classes:"toolbar-grp",ariaRoot:!0,ariaRemember:!0,items:i}:void 0}function i(){function t(t){var i;return"|"==t?{text:"|"}:i=e.menuItems[t]}function i(i){var n,o,r,a,s;if(s=tinymce.makeMap((u.removed_menuitems||"").split(/[ ,]/)),u.menu?(o=u.menu[i],a=!0):o=h[i],o){n={text:o.title},r=[],d((o.items||"").split(/[ ,]/),function(e){var i=t(e);i&&!s[e]&&r.push(t(e))}),a||d(e.menuItems,function(e){e.context==i&&("before"==e.separator&&r.push({text:"|"}),e.prependToContext?r.unshift(e):r.push(e),"after"==e.separator&&r.push({text:"|"}))});for(var l=0;l +
    Pressing "a" while this checkbox is + focused will remove it from the DOM.
    +
    +
    + diff --git a/node_modules/selenium-webdriver/lib/test/data/keyboard_shortcut.html b/node_modules/selenium-webdriver/lib/test/data/keyboard_shortcut.html new file mode 100644 index 0000000..741d7f4 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/keyboard_shortcut.html @@ -0,0 +1,36 @@ + + +
    CTRL + 1: red
    +
    SHIFT + 1: green
    +
    CTRL + SHIFT + 1: yellow
    +
    ALT + 1: lightblue
    +
    CTRL + ALT + 1: lightgreen
    +
    SHIFT + ALT + 1: silver
    +
    CTRL + SHIFT + ALT + 1: magenta
    + diff --git a/node_modules/selenium-webdriver/lib/test/data/linked_image.html b/node_modules/selenium-webdriver/lib/test/data/linked_image.html new file mode 100644 index 0000000..7c8df00 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/linked_image.html @@ -0,0 +1,16 @@ + + + + +Linking with an image + + +banner
    +Click here for next page
    +
    +link to other link
    +Just another link.
    +

    + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected.html b/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected.html new file mode 100644 index 0000000..42b0442 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected.html @@ -0,0 +1,13 @@ + + + Boolean Attribute Selected + + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected_html4.html b/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected_html4.html new file mode 100644 index 0000000..60cd033 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected_html4.html @@ -0,0 +1,13 @@ + + + Boolean Attribute Selected + + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/longContentPage.html b/node_modules/selenium-webdriver/lib/test/data/longContentPage.html new file mode 100644 index 0000000..99a45e7 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/longContentPage.html @@ -0,0 +1,55 @@ + + + TouchLongContent + + + +

    Touch API

    +

    Page with long content

    +
                       



    +

    Long text:                                                                                                                          This is a very long text to make the screen horizontally movable, to test the flick gesture at a long horizontal distance Normal link                                                                                                                                           at normal and fast speeds to see results of it Normal link end

    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    + Middle of the screen Normal link +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    + Bottom of the screen Normal link


    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/macbeth.html b/node_modules/selenium-webdriver/lib/test/data/macbeth.html new file mode 100644 index 0000000..9fa39d5 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/macbeth.html @@ -0,0 +1,5255 @@ + + + + Macbeth: Entire Play + + + + + + + +Quick link to last speech + +

    ACT I

    +

    SCENE I. A desert place.

    +

    +Thunder and lightning. Enter three Witches +
    + +First Witch +
    +When shall we three meet again
    +In thunder, lightning, or in rain?
    +
    + +Second Witch +
    +When the hurlyburly's done,
    +When the battle's lost and won.
    +
    + +Third Witch +
    +That will be ere the set of sun.
    +
    + +First Witch +
    +Where the place?
    +
    + +Second Witch +
    + Upon the heath.
    +
    + +Third Witch +
    +There to meet with Macbeth.
    +
    + +First Witch +
    +I come, Graymalkin!
    +
    + +Second Witch +
    +Paddock calls.
    +
    + +Third Witch +
    +Anon.
    +
    + +ALL +
    +Fair is foul, and foul is fair:
    +Hover through the fog and filthy air.
    +

    Exeunt

    +
    +

    SCENE II. A camp near Forres.

    +

    +Alarum within. Enter DUNCAN, MALCOLM, DONALBAIN, LENNOX, with Attendants, meeting a bleeding Sergeant +
    + +DUNCAN +
    +What bloody man is that? He can report,
    +As seemeth by his plight, of the revolt
    +The newest state.
    +
    + +MALCOLM +
    + This is the sergeant
    +Who like a good and hardy soldier fought
    +'Gainst my captivity. Hail, brave friend!
    +Say to the king the knowledge of the broil
    +As thou didst leave it.
    +
    + +Sergeant +
    +Doubtful it stood;
    +As two spent swimmers, that do cling together
    +And choke their art. The merciless Macdonwald--
    +Worthy to be a rebel, for to that
    +The multiplying villanies of nature
    +Do swarm upon him--from the western isles
    +Of kerns and gallowglasses is supplied;
    +And fortune, on his damned quarrel smiling,
    +Show'd like a rebel's whore: but all's too weak:
    +For brave Macbeth--well he deserves that name--
    +Disdaining fortune, with his brandish'd steel,
    +Which smoked with bloody execution,
    +Like valour's minion carved out his passage
    +Till he faced the slave;
    +Which ne'er shook hands, nor bade farewell to him,
    +Till he unseam'd him from the nave to the chaps,
    +And fix'd his head upon our battlements.
    +
    + +DUNCAN +
    +O valiant cousin! worthy gentleman!
    +
    + +Sergeant +
    +As whence the sun 'gins his reflection
    +Shipwrecking storms and direful thunders break,
    +So from that spring whence comfort seem'd to come
    +Discomfort swells. Mark, king of Scotland, mark:
    +No sooner justice had with valour arm'd
    +Compell'd these skipping kerns to trust their heels,
    +But the Norweyan lord surveying vantage,
    +With furbish'd arms and new supplies of men
    +Began a fresh assault.
    +
    + +DUNCAN +
    +Dismay'd not this
    +Our captains, Macbeth and Banquo?
    +
    + +Sergeant +
    +Yes;
    +As sparrows eagles, or the hare the lion.
    +If I say sooth, I must report they were
    +As cannons overcharged with double cracks, so they
    +Doubly redoubled strokes upon the foe:
    +Except they meant to bathe in reeking wounds,
    +Or memorise another Golgotha,
    +I cannot tell.
    +But I am faint, my gashes cry for help.
    +
    + +DUNCAN +
    +So well thy words become thee as thy wounds;
    +They smack of honour both. Go get him surgeons.
    +

    Exit Sergeant, attended

    +Who comes here?
    +

    Enter ROSS

    +
    + +MALCOLM +
    + The worthy thane of Ross.
    +
    + +LENNOX +
    +What a haste looks through his eyes! So should he look
    +That seems to speak things strange.
    +
    + +ROSS +
    +God save the king!
    +
    + +DUNCAN +
    +Whence camest thou, worthy thane?
    +
    + +ROSS +
    +From Fife, great king;
    +Where the Norweyan banners flout the sky
    +And fan our people cold. Norway himself,
    +With terrible numbers,
    +Assisted by that most disloyal traitor
    +The thane of Cawdor, began a dismal conflict;
    +Till that Bellona's bridegroom, lapp'd in proof,
    +Confronted him with self-comparisons,
    +Point against point rebellious, arm 'gainst arm.
    +Curbing his lavish spirit: and, to conclude,
    +The victory fell on us.
    +
    + +DUNCAN +
    +Great happiness!
    +
    + +ROSS +
    +That now
    +Sweno, the Norways' king, craves composition:
    +Nor would we deign him burial of his men
    +Till he disbursed at Saint Colme's inch
    +Ten thousand dollars to our general use.
    +
    + +DUNCAN +
    +No more that thane of Cawdor shall deceive
    +Our bosom interest: go pronounce his present death,
    +And with his former title greet Macbeth.
    +
    + +ROSS +
    +I'll see it done.
    +
    + +DUNCAN +
    +What he hath lost noble Macbeth hath won.
    +

    Exeunt

    +
    +

    SCENE III. A heath near Forres.

    +

    +Thunder. Enter the three Witches +
    + +First Witch +
    +Where hast thou been, sister?
    +
    + +Second Witch +
    +Killing swine.
    +
    + +Third Witch +
    +Sister, where thou?
    +
    + +First Witch +
    +A sailor's wife had chestnuts in her lap,
    +And munch'd, and munch'd, and munch'd:--
    +'Give me,' quoth I:
    +'Aroint thee, witch!' the rump-fed ronyon cries.
    +Her husband's to Aleppo gone, master o' the Tiger:
    +But in a sieve I'll thither sail,
    +And, like a rat without a tail,
    +I'll do, I'll do, and I'll do.
    +
    + +Second Witch +
    +I'll give thee a wind.
    +
    + +First Witch +
    +Thou'rt kind.
    +
    + +Third Witch +
    +And I another.
    +
    + +First Witch +
    +I myself have all the other,
    +And the very ports they blow,
    +All the quarters that they know
    +I' the shipman's card.
    +I will drain him dry as hay:
    +Sleep shall neither night nor day
    +Hang upon his pent-house lid;
    +He shall live a man forbid:
    +Weary se'nnights nine times nine
    +Shall he dwindle, peak and pine:
    +Though his bark cannot be lost,
    +Yet it shall be tempest-tost.
    +Look what I have.
    +
    + +Second Witch +
    +Show me, show me.
    +
    + +First Witch +
    +Here I have a pilot's thumb,
    +Wreck'd as homeward he did come.
    +

    Drum within

    +
    + +Third Witch +
    +A drum, a drum!
    +Macbeth doth come.
    +
    + +ALL +
    +The weird sisters, hand in hand,
    +Posters of the sea and land,
    +Thus do go about, about:
    +Thrice to thine and thrice to mine
    +And thrice again, to make up nine.
    +Peace! the charm's wound up.
    +

    Enter MACBETH and BANQUO

    +
    + +MACBETH +
    +So foul and fair a day I have not seen.
    +
    + +BANQUO +
    +How far is't call'd to Forres? What are these
    +So wither'd and so wild in their attire,
    +That look not like the inhabitants o' the earth,
    +And yet are on't? Live you? or are you aught
    +That man may question? You seem to understand me,
    +By each at once her chappy finger laying
    +Upon her skinny lips: you should be women,
    +And yet your beards forbid me to interpret
    +That you are so.
    +
    + +MACBETH +
    + Speak, if you can: what are you?
    +
    + +First Witch +
    +All hail, Macbeth! hail to thee, thane of Glamis!
    +
    + +Second Witch +
    +All hail, Macbeth, hail to thee, thane of Cawdor!
    +
    + +Third Witch +
    +All hail, Macbeth, thou shalt be king hereafter!
    +
    + +BANQUO +
    +Good sir, why do you start; and seem to fear
    +Things that do sound so fair? I' the name of truth,
    +Are ye fantastical, or that indeed
    +Which outwardly ye show? My noble partner
    +You greet with present grace and great prediction
    +Of noble having and of royal hope,
    +That he seems rapt withal: to me you speak not.
    +If you can look into the seeds of time,
    +And say which grain will grow and which will not,
    +Speak then to me, who neither beg nor fear
    +Your favours nor your hate.
    +
    + +First Witch +
    +Hail!
    +
    + +Second Witch +
    +Hail!
    +
    + +Third Witch +
    +Hail!
    +
    + +First Witch +
    +Lesser than Macbeth, and greater.
    +
    + +Second Witch +
    +Not so happy, yet much happier.
    +
    + +Third Witch +
    +Thou shalt get kings, though thou be none:
    +So all hail, Macbeth and Banquo!
    +
    + +First Witch +
    +Banquo and Macbeth, all hail!
    +
    + +MACBETH +
    +Stay, you imperfect speakers, tell me more:
    +By Sinel's death I know I am thane of Glamis;
    +But how of Cawdor? the thane of Cawdor lives,
    +A prosperous gentleman; and to be king
    +Stands not within the prospect of belief,
    +No more than to be Cawdor. Say from whence
    +You owe this strange intelligence? or why
    +Upon this blasted heath you stop our way
    +With such prophetic greeting? Speak, I charge you.
    +

    Witches vanish

    +
    + +BANQUO +
    +The earth hath bubbles, as the water has,
    +And these are of them. Whither are they vanish'd?
    +
    + +MACBETH +
    +Into the air; and what seem'd corporal melted
    +As breath into the wind. Would they had stay'd!
    +
    + +BANQUO +
    +Were such things here as we do speak about?
    +Or have we eaten on the insane root
    +That takes the reason prisoner?
    +
    + +MACBETH +
    +Your children shall be kings.
    +
    + +BANQUO +
    +You shall be king.
    +
    + +MACBETH +
    +And thane of Cawdor too: went it not so?
    +
    + +BANQUO +
    +To the selfsame tune and words. Who's here?
    +

    Enter ROSS and ANGUS

    +
    + +ROSS +
    +The king hath happily received, Macbeth,
    +The news of thy success; and when he reads
    +Thy personal venture in the rebels' fight,
    +His wonders and his praises do contend
    +Which should be thine or his: silenced with that,
    +In viewing o'er the rest o' the selfsame day,
    +He finds thee in the stout Norweyan ranks,
    +Nothing afeard of what thyself didst make,
    +Strange images of death. As thick as hail
    +Came post with post; and every one did bear
    +Thy praises in his kingdom's great defence,
    +And pour'd them down before him.
    +
    + +ANGUS +
    +We are sent
    +To give thee from our royal master thanks;
    +Only to herald thee into his sight,
    +Not pay thee.
    +
    + +ROSS +
    +And, for an earnest of a greater honour,
    +He bade me, from him, call thee thane of Cawdor:
    +In which addition, hail, most worthy thane!
    +For it is thine.
    +
    + +BANQUO +
    + What, can the devil speak true?
    +
    + +MACBETH +
    +The thane of Cawdor lives: why do you dress me
    +In borrow'd robes?
    +
    + +ANGUS +
    + Who was the thane lives yet;
    +But under heavy judgment bears that life
    +Which he deserves to lose. Whether he was combined
    +With those of Norway, or did line the rebel
    +With hidden help and vantage, or that with both
    +He labour'd in his country's wreck, I know not;
    +But treasons capital, confess'd and proved,
    +Have overthrown him.
    +
    + +MACBETH +
    +[Aside] Glamis, and thane of Cawdor!
    +The greatest is behind.
    +

    To ROSS and ANGUS

    +Thanks for your pains.
    +

    To BANQUO

    +Do you not hope your children shall be kings,
    +When those that gave the thane of Cawdor to me
    +Promised no less to them?
    +
    + +BANQUO +
    +That trusted home
    +Might yet enkindle you unto the crown,
    +Besides the thane of Cawdor. But 'tis strange:
    +And oftentimes, to win us to our harm,
    +The instruments of darkness tell us truths,
    +Win us with honest trifles, to betray's
    +In deepest consequence.
    +Cousins, a word, I pray you.
    +
    + +MACBETH +
    +[Aside] Two truths are told,
    +As happy prologues to the swelling act
    +Of the imperial theme.--I thank you, gentlemen.
    +

    Aside

    +Cannot be ill, cannot be good: if ill,
    +Why hath it given me earnest of success,
    +Commencing in a truth? I am thane of Cawdor:
    +If good, why do I yield to that suggestion
    +Whose horrid image doth unfix my hair
    +And make my seated heart knock at my ribs,
    +Against the use of nature? Present fears
    +Are less than horrible imaginings:
    +My thought, whose murder yet is but fantastical,
    +Shakes so my single state of man that function
    +Is smother'd in surmise, and nothing is
    +But what is not.
    +
    + +BANQUO +
    + Look, how our partner's rapt.
    +
    + +MACBETH +
    +[Aside] If chance will have me king, why, chance may crown me,
    +Without my stir.
    +
    + +BANQUO +
    + New horrors come upon him,
    +Like our strange garments, cleave not to their mould
    +But with the aid of use.
    +
    + +MACBETH +
    +[Aside] Come what come may,
    +Time and the hour runs through the roughest day.
    +
    + +BANQUO +
    +Worthy Macbeth, we stay upon your leisure.
    +
    + +MACBETH +
    +Give me your favour: my dull brain was wrought
    +With things forgotten. Kind gentlemen, your pains
    +Are register'd where every day I turn
    +The leaf to read them. Let us toward the king.
    +Think upon what hath chanced, and, at more time,
    +The interim having weigh'd it, let us speak
    +Our free hearts each to other.
    +
    + +BANQUO +
    +Very gladly.
    +
    + +MACBETH +
    +Till then, enough. Come, friends.
    +

    Exeunt

    +
    +

    SCENE IV. Forres. The palace.

    +

    +Flourish. Enter DUNCAN, MALCOLM, DONALBAIN, LENNOX, and Attendants +
    + +DUNCAN +
    +Is execution done on Cawdor? Are not
    +Those in commission yet return'd?
    +
    + +MALCOLM +
    +My liege,
    +They are not yet come back. But I have spoke
    +With one that saw him die: who did report
    +That very frankly he confess'd his treasons,
    +Implored your highness' pardon and set forth
    +A deep repentance: nothing in his life
    +Became him like the leaving it; he died
    +As one that had been studied in his death
    +To throw away the dearest thing he owed,
    +As 'twere a careless trifle.
    +
    + +DUNCAN +
    +There's no art
    +To find the mind's construction in the face:
    +He was a gentleman on whom I built
    +An absolute trust.
    +

    Enter MACBETH, BANQUO, ROSS, and ANGUS

    +O worthiest cousin!
    +The sin of my ingratitude even now
    +Was heavy on me: thou art so far before
    +That swiftest wing of recompense is slow
    +To overtake thee. Would thou hadst less deserved,
    +That the proportion both of thanks and payment
    +Might have been mine! only I have left to say,
    +More is thy due than more than all can pay.
    +
    + +MACBETH +
    +The service and the loyalty I owe,
    +In doing it, pays itself. Your highness' part
    +Is to receive our duties; and our duties
    +Are to your throne and state children and servants,
    +Which do but what they should, by doing every thing
    +Safe toward your love and honour.
    +
    + +DUNCAN +
    +Welcome hither:
    +I have begun to plant thee, and will labour
    +To make thee full of growing. Noble Banquo,
    +That hast no less deserved, nor must be known
    +No less to have done so, let me enfold thee
    +And hold thee to my heart.
    +
    + +BANQUO +
    +There if I grow,
    +The harvest is your own.
    +
    + +DUNCAN +
    +My plenteous joys,
    +Wanton in fulness, seek to hide themselves
    +In drops of sorrow. Sons, kinsmen, thanes,
    +And you whose places are the nearest, know
    +We will establish our estate upon
    +Our eldest, Malcolm, whom we name hereafter
    +The Prince of Cumberland; which honour must
    +Not unaccompanied invest him only,
    +But signs of nobleness, like stars, shall shine
    +On all deservers. From hence to Inverness,
    +And bind us further to you.
    +
    + +MACBETH +
    +The rest is labour, which is not used for you:
    +I'll be myself the harbinger and make joyful
    +The hearing of my wife with your approach;
    +So humbly take my leave.
    +
    + +DUNCAN +
    +My worthy Cawdor!
    +
    + +MACBETH +
    +[Aside] The Prince of Cumberland! that is a step
    +On which I must fall down, or else o'erleap,
    +For in my way it lies. Stars, hide your fires;
    +Let not light see my black and deep desires:
    +The eye wink at the hand; yet let that be,
    +Which the eye fears, when it is done, to see.
    +

    Exit

    +
    + +DUNCAN +
    +True, worthy Banquo; he is full so valiant,
    +And in his commendations I am fed;
    +It is a banquet to me. Let's after him,
    +Whose care is gone before to bid us welcome:
    +It is a peerless kinsman.
    +

    Flourish. Exeunt

    +
    +

    SCENE V. Inverness. Macbeth's castle.

    +

    +Enter LADY MACBETH, reading a letter +
    + +LADY MACBETH +
    +'They met me in the day of success: and I have
    +learned by the perfectest report, they have more in
    +them than mortal knowledge. When I burned in desire
    +to question them further, they made themselves air,
    +into which they vanished. Whiles I stood rapt in
    +the wonder of it, came missives from the king, who
    +all-hailed me 'Thane of Cawdor;' by which title,
    +before, these weird sisters saluted me, and referred
    +me to the coming on of time, with 'Hail, king that
    +shalt be!' This have I thought good to deliver
    +thee, my dearest partner of greatness, that thou
    +mightst not lose the dues of rejoicing, by being
    +ignorant of what greatness is promised thee. Lay it
    +to thy heart, and farewell.'
    +Glamis thou art, and Cawdor; and shalt be
    +What thou art promised: yet do I fear thy nature;
    +It is too full o' the milk of human kindness
    +To catch the nearest way: thou wouldst be great;
    +Art not without ambition, but without
    +The illness should attend it: what thou wouldst highly,
    +That wouldst thou holily; wouldst not play false,
    +And yet wouldst wrongly win: thou'ldst have, great Glamis,
    +That which cries 'Thus thou must do, if thou have it;
    +And that which rather thou dost fear to do
    +Than wishest should be undone.' Hie thee hither,
    +That I may pour my spirits in thine ear;
    +And chastise with the valour of my tongue
    +All that impedes thee from the golden round,
    +Which fate and metaphysical aid doth seem
    +To have thee crown'd withal.
    +

    Enter a Messenger

    +What is your tidings?
    +
    + +Messenger +
    +The king comes here to-night.
    +
    + +LADY MACBETH +
    +Thou'rt mad to say it:
    +Is not thy master with him? who, were't so,
    +Would have inform'd for preparation.
    +
    + +Messenger +
    +So please you, it is true: our thane is coming:
    +One of my fellows had the speed of him,
    +Who, almost dead for breath, had scarcely more
    +Than would make up his message.
    +
    + +LADY MACBETH +
    +Give him tending;
    +He brings great news.
    +

    Exit Messenger

    +The raven himself is hoarse
    +That croaks the fatal entrance of Duncan
    +Under my battlements. Come, you spirits
    +That tend on mortal thoughts, unsex me here,
    +And fill me from the crown to the toe top-full
    +Of direst cruelty! make thick my blood;
    +Stop up the access and passage to remorse,
    +That no compunctious visitings of nature
    +Shake my fell purpose, nor keep peace between
    +The effect and it! Come to my woman's breasts,
    +And take my milk for gall, you murdering ministers,
    +Wherever in your sightless substances
    +You wait on nature's mischief! Come, thick night,
    +And pall thee in the dunnest smoke of hell,
    +That my keen knife see not the wound it makes,
    +Nor heaven peep through the blanket of the dark,
    +To cry 'Hold, hold!'
    +

    Enter MACBETH

    +Great Glamis! worthy Cawdor!
    +Greater than both, by the all-hail hereafter!
    +Thy letters have transported me beyond
    +This ignorant present, and I feel now
    +The future in the instant.
    +
    + +MACBETH +
    +My dearest love,
    +Duncan comes here to-night.
    +
    + +LADY MACBETH +
    +And when goes hence?
    +
    + +MACBETH +
    +To-morrow, as he purposes.
    +
    + +LADY MACBETH +
    +O, never
    +Shall sun that morrow see!
    +Your face, my thane, is as a book where men
    +May read strange matters. To beguile the time,
    +Look like the time; bear welcome in your eye,
    +Your hand, your tongue: look like the innocent flower,
    +But be the serpent under't. He that's coming
    +Must be provided for: and you shall put
    +This night's great business into my dispatch;
    +Which shall to all our nights and days to come
    +Give solely sovereign sway and masterdom.
    +
    + +MACBETH +
    +We will speak further.
    +
    + +LADY MACBETH +
    +Only look up clear;
    +To alter favour ever is to fear:
    +Leave all the rest to me.
    +

    Exeunt

    +
    +

    SCENE VI. Before Macbeth's castle.

    +

    +Hautboys and torches. Enter DUNCAN, MALCOLM, DONALBAIN, BANQUO, LENNOX, MACDUFF, ROSS, ANGUS, and Attendants +
    + +DUNCAN +
    +This castle hath a pleasant seat; the air
    +Nimbly and sweetly recommends itself
    +Unto our gentle senses.
    +
    + +BANQUO +
    +This guest of summer,
    +The temple-haunting martlet, does approve,
    +By his loved mansionry, that the heaven's breath
    +Smells wooingly here: no jutty, frieze,
    +Buttress, nor coign of vantage, but this bird
    +Hath made his pendent bed and procreant cradle:
    +Where they most breed and haunt, I have observed,
    +The air is delicate.
    +

    Enter LADY MACBETH

    +
    + +DUNCAN +
    +See, see, our honour'd hostess!
    +The love that follows us sometime is our trouble,
    +Which still we thank as love. Herein I teach you
    +How you shall bid God 'ild us for your pains,
    +And thank us for your trouble.
    +
    + +LADY MACBETH +
    +All our service
    +In every point twice done and then done double
    +Were poor and single business to contend
    +Against those honours deep and broad wherewith
    +Your majesty loads our house: for those of old,
    +And the late dignities heap'd up to them,
    +We rest your hermits.
    +
    + +DUNCAN +
    +Where's the thane of Cawdor?
    +We coursed him at the heels, and had a purpose
    +To be his purveyor: but he rides well;
    +And his great love, sharp as his spur, hath holp him
    +To his home before us. Fair and noble hostess,
    +We are your guest to-night.
    +
    + +LADY MACBETH +
    +Your servants ever
    +Have theirs, themselves and what is theirs, in compt,
    +To make their audit at your highness' pleasure,
    +Still to return your own.
    +
    + +DUNCAN +
    +Give me your hand;
    +Conduct me to mine host: we love him highly,
    +And shall continue our graces towards him.
    +By your leave, hostess.
    +

    Exeunt

    +
    +

    SCENE VII. Macbeth's castle.

    +

    +Hautboys and torches. Enter a Sewer, and divers Servants with dishes and service, and pass over the stage. Then enter MACBETH +
    + +MACBETH +
    +If it were done when 'tis done, then 'twere well
    +It were done quickly: if the assassination
    +Could trammel up the consequence, and catch
    +With his surcease success; that but this blow
    +Might be the be-all and the end-all here,
    +But here, upon this bank and shoal of time,
    +We'ld jump the life to come. But in these cases
    +We still have judgment here; that we but teach
    +Bloody instructions, which, being taught, return
    +To plague the inventor: this even-handed justice
    +Commends the ingredients of our poison'd chalice
    +To our own lips. He's here in double trust;
    +First, as I am his kinsman and his subject,
    +Strong both against the deed; then, as his host,
    +Who should against his murderer shut the door,
    +Not bear the knife myself. Besides, this Duncan
    +Hath borne his faculties so meek, hath been
    +So clear in his great office, that his virtues
    +Will plead like angels, trumpet-tongued, against
    +The deep damnation of his taking-off;
    +And pity, like a naked new-born babe,
    +Striding the blast, or heaven's cherubim, horsed
    +Upon the sightless couriers of the air,
    +Shall blow the horrid deed in every eye,
    +That tears shall drown the wind. I have no spur
    +To prick the sides of my intent, but only
    +Vaulting ambition, which o'erleaps itself
    +And falls on the other.
    +

    Enter LADY MACBETH

    +How now! what news?
    +
    + +LADY MACBETH +
    +He has almost supp'd: why have you left the chamber?
    +
    + +MACBETH +
    +Hath he ask'd for me?
    +
    + +LADY MACBETH +
    +Know you not he has?
    +
    + +MACBETH +
    +We will proceed no further in this business:
    +He hath honour'd me of late; and I have bought
    +Golden opinions from all sorts of people,
    +Which would be worn now in their newest gloss,
    +Not cast aside so soon.
    +
    + +LADY MACBETH +
    +Was the hope drunk
    +Wherein you dress'd yourself? hath it slept since?
    +And wakes it now, to look so green and pale
    +At what it did so freely? From this time
    +Such I account thy love. Art thou afeard
    +To be the same in thine own act and valour
    +As thou art in desire? Wouldst thou have that
    +Which thou esteem'st the ornament of life,
    +And live a coward in thine own esteem,
    +Letting 'I dare not' wait upon 'I would,'
    +Like the poor cat i' the adage?
    +
    + +MACBETH +
    +Prithee, peace:
    +I dare do all that may become a man;
    +Who dares do more is none.
    +
    + +LADY MACBETH +
    +What beast was't, then,
    +That made you break this enterprise to me?
    +When you durst do it, then you were a man;
    +And, to be more than what you were, you would
    +Be so much more the man. Nor time nor place
    +Did then adhere, and yet you would make both:
    +They have made themselves, and that their fitness now
    +Does unmake you. I have given suck, and know
    +How tender 'tis to love the babe that milks me:
    +I would, while it was smiling in my face,
    +Have pluck'd my nipple from his boneless gums,
    +And dash'd the brains out, had I so sworn as you
    +Have done to this.
    +
    + +MACBETH +
    + If we should fail?
    +
    + +LADY MACBETH +
    +We fail!
    +But screw your courage to the sticking-place,
    +And we'll not fail. When Duncan is asleep--
    +Whereto the rather shall his day's hard journey
    +Soundly invite him--his two chamberlains
    +Will I with wine and wassail so convince
    +That memory, the warder of the brain,
    +Shall be a fume, and the receipt of reason
    +A limbeck only: when in swinish sleep
    +Their drenched natures lie as in a death,
    +What cannot you and I perform upon
    +The unguarded Duncan? what not put upon
    +His spongy officers, who shall bear the guilt
    +Of our great quell?
    +
    + +MACBETH +
    +Bring forth men-children only;
    +For thy undaunted mettle should compose
    +Nothing but males. Will it not be received,
    +When we have mark'd with blood those sleepy two
    +Of his own chamber and used their very daggers,
    +That they have done't?
    +
    + +LADY MACBETH +
    +Who dares receive it other,
    +As we shall make our griefs and clamour roar
    +Upon his death?
    +
    + +MACBETH +
    + I am settled, and bend up
    +Each corporal agent to this terrible feat.
    +Away, and mock the time with fairest show:
    +False face must hide what the false heart doth know.
    +

    Exeunt

    +

    +

    ACT II

    +

    SCENE I. Court of Macbeth's castle.

    +

    +Enter BANQUO, and FLEANCE bearing a torch before him +
    + +BANQUO +
    +How goes the night, boy?
    +
    + +FLEANCE +
    +The moon is down; I have not heard the clock.
    +
    + +BANQUO +
    +And she goes down at twelve.
    +
    + +FLEANCE +
    +I take't, 'tis later, sir.
    +
    + +BANQUO +
    +Hold, take my sword. There's husbandry in heaven;
    +Their candles are all out. Take thee that too.
    +A heavy summons lies like lead upon me,
    +And yet I would not sleep: merciful powers,
    +Restrain in me the cursed thoughts that nature
    +Gives way to in repose!
    +

    Enter MACBETH, and a Servant with a torch

    +Give me my sword.
    +Who's there?
    +
    + +MACBETH +
    +A friend.
    +
    + +BANQUO +
    +What, sir, not yet at rest? The king's a-bed:
    +He hath been in unusual pleasure, and
    +Sent forth great largess to your offices.
    +This diamond he greets your wife withal,
    +By the name of most kind hostess; and shut up
    +In measureless content.
    +
    + +MACBETH +
    +Being unprepared,
    +Our will became the servant to defect;
    +Which else should free have wrought.
    +
    + +BANQUO +
    +All's well.
    +I dreamt last night of the three weird sisters:
    +To you they have show'd some truth.
    +
    + +MACBETH +
    +I think not of them:
    +Yet, when we can entreat an hour to serve,
    +We would spend it in some words upon that business,
    +If you would grant the time.
    +
    + +BANQUO +
    +At your kind'st leisure.
    +
    + +MACBETH +
    +If you shall cleave to my consent, when 'tis,
    +It shall make honour for you.
    +
    + +BANQUO +
    +So I lose none
    +In seeking to augment it, but still keep
    +My bosom franchised and allegiance clear,
    +I shall be counsell'd.
    +
    + +MACBETH +
    +Good repose the while!
    +
    + +BANQUO +
    +Thanks, sir: the like to you!
    +

    Exeunt BANQUO and FLEANCE

    +
    + +MACBETH +
    +Go bid thy mistress, when my drink is ready,
    +She strike upon the bell. Get thee to bed.
    +

    Exit Servant

    +Is this a dagger which I see before me,
    +The handle toward my hand? Come, let me clutch thee.
    +I have thee not, and yet I see thee still.
    +Art thou not, fatal vision, sensible
    +To feeling as to sight? or art thou but
    +A dagger of the mind, a false creation,
    +Proceeding from the heat-oppressed brain?
    +I see thee yet, in form as palpable
    +As this which now I draw.
    +Thou marshall'st me the way that I was going;
    +And such an instrument I was to use.
    +Mine eyes are made the fools o' the other senses,
    +Or else worth all the rest; I see thee still,
    +And on thy blade and dudgeon gouts of blood,
    +Which was not so before. There's no such thing:
    +It is the bloody business which informs
    +Thus to mine eyes. Now o'er the one halfworld
    +Nature seems dead, and wicked dreams abuse
    +The curtain'd sleep; witchcraft celebrates
    +Pale Hecate's offerings, and wither'd murder,
    +Alarum'd by his sentinel, the wolf,
    +Whose howl's his watch, thus with his stealthy pace.
    +With Tarquin's ravishing strides, towards his design
    +Moves like a ghost. Thou sure and firm-set earth,
    +Hear not my steps, which way they walk, for fear
    +Thy very stones prate of my whereabout,
    +And take the present horror from the time,
    +Which now suits with it. Whiles I threat, he lives:
    +Words to the heat of deeds too cold breath gives.
    +

    A bell rings

    +I go, and it is done; the bell invites me.
    +Hear it not, Duncan; for it is a knell
    +That summons thee to heaven or to hell.
    +

    Exit

    +
    +

    SCENE II. The same.

    +

    +Enter LADY MACBETH +
    + +LADY MACBETH +
    +That which hath made them drunk hath made me bold;
    +What hath quench'd them hath given me fire.
    +Hark! Peace!
    +It was the owl that shriek'd, the fatal bellman,
    +Which gives the stern'st good-night. He is about it:
    +The doors are open; and the surfeited grooms
    +Do mock their charge with snores: I have drugg'd
    +their possets,
    +That death and nature do contend about them,
    +Whether they live or die.
    +
    + +MACBETH +
    +[Within] Who's there? what, ho!
    +
    + +LADY MACBETH +
    +Alack, I am afraid they have awaked,
    +And 'tis not done. The attempt and not the deed
    +Confounds us. Hark! I laid their daggers ready;
    +He could not miss 'em. Had he not resembled
    +My father as he slept, I had done't.
    +

    Enter MACBETH

    +My husband!
    +
    + +MACBETH +
    +I have done the deed. Didst thou not hear a noise?
    +
    + +LADY MACBETH +
    +I heard the owl scream and the crickets cry.
    +Did not you speak?
    +
    + +MACBETH +
    + When?
    +
    + +LADY MACBETH +
    +Now.
    +
    + +MACBETH +
    +As I descended?
    +
    + +LADY MACBETH +
    +Ay.
    +
    + +MACBETH +
    +Hark!
    +Who lies i' the second chamber?
    +
    + +LADY MACBETH +
    +Donalbain.
    +
    + +MACBETH +
    +This is a sorry sight.
    +

    Looking on his hands

    +
    + +LADY MACBETH +
    +A foolish thought, to say a sorry sight.
    +
    + +MACBETH +
    +There's one did laugh in's sleep, and one cried
    +'Murder!'
    +That they did wake each other: I stood and heard them:
    +But they did say their prayers, and address'd them
    +Again to sleep.
    +
    + +LADY MACBETH +
    + There are two lodged together.
    +
    + +MACBETH +
    +One cried 'God bless us!' and 'Amen' the other;
    +As they had seen me with these hangman's hands.
    +Listening their fear, I could not say 'Amen,'
    +When they did say 'God bless us!'
    +
    + +LADY MACBETH +
    +Consider it not so deeply.
    +
    + +MACBETH +
    +But wherefore could not I pronounce 'Amen'?
    +I had most need of blessing, and 'Amen'
    +Stuck in my throat.
    +
    + +LADY MACBETH +
    +These deeds must not be thought
    +After these ways; so, it will make us mad.
    +
    + +MACBETH +
    +Methought I heard a voice cry 'Sleep no more!
    +Macbeth does murder sleep', the innocent sleep,
    +Sleep that knits up the ravell'd sleeve of care,
    +The death of each day's life, sore labour's bath,
    +Balm of hurt minds, great nature's second course,
    +Chief nourisher in life's feast,--
    +
    + +LADY MACBETH +
    +What do you mean?
    +
    + +MACBETH +
    +Still it cried 'Sleep no more!' to all the house:
    +'Glamis hath murder'd sleep, and therefore Cawdor
    +Shall sleep no more; Macbeth shall sleep no more.'
    +
    + +LADY MACBETH +
    +Who was it that thus cried? Why, worthy thane,
    +You do unbend your noble strength, to think
    +So brainsickly of things. Go get some water,
    +And wash this filthy witness from your hand.
    +Why did you bring these daggers from the place?
    +They must lie there: go carry them; and smear
    +The sleepy grooms with blood.
    +
    + +MACBETH +
    +I'll go no more:
    +I am afraid to think what I have done;
    +Look on't again I dare not.
    +
    + +LADY MACBETH +
    +Infirm of purpose!
    +Give me the daggers: the sleeping and the dead
    +Are but as pictures: 'tis the eye of childhood
    +That fears a painted devil. If he do bleed,
    +I'll gild the faces of the grooms withal;
    +For it must seem their guilt.
    +

    Exit. Knocking within

    +
    + +MACBETH +
    +Whence is that knocking?
    +How is't with me, when every noise appals me?
    +What hands are here? ha! they pluck out mine eyes.
    +Will all great Neptune's ocean wash this blood
    +Clean from my hand? No, this my hand will rather
    +The multitudinous seas in incarnadine,
    +Making the green one red.
    +

    Re-enter LADY MACBETH

    +
    + +LADY MACBETH +
    +My hands are of your colour; but I shame
    +To wear a heart so white.
    +

    Knocking within

    +I hear a knocking
    +At the south entry: retire we to our chamber;
    +A little water clears us of this deed:
    +How easy is it, then! Your constancy
    +Hath left you unattended.
    +

    Knocking within

    +Hark! more knocking.
    +Get on your nightgown, lest occasion call us,
    +And show us to be watchers. Be not lost
    +So poorly in your thoughts.
    +
    + +MACBETH +
    +To know my deed, 'twere best not know myself.
    +

    Knocking within

    +Wake Duncan with thy knocking! I would thou couldst!
    +

    Exeunt

    +
    +

    SCENE III. The same.

    +

    +Knocking within. Enter a Porter +
    + +Porter +
    +Here's a knocking indeed! If a
    +man were porter of hell-gate, he should have
    +old turning the key.
    +

    Knocking within

    +Knock,
    +knock, knock! Who's there, i' the name of
    +Beelzebub? Here's a farmer, that hanged
    +himself on the expectation of plenty: come in
    +time; have napkins enow about you; here
    +you'll sweat for't.
    +

    Knocking within

    +Knock,
    +knock! Who's there, in the other devil's
    +name? Faith, here's an equivocator, that could
    +swear in both the scales against either scale;
    +who committed treason enough for God's sake,
    +yet could not equivocate to heaven: O, come
    +in, equivocator.
    +

    Knocking within

    +Knock,
    +knock, knock! Who's there? Faith, here's an
    +English tailor come hither, for stealing out of
    +a French hose: come in, tailor; here you may
    +roast your goose.
    +

    Knocking within

    +Knock,
    +knock; never at quiet! What are you? But
    +this place is too cold for hell. I'll devil-porter
    +it no further: I had thought to have let in
    +some of all professions that go the primrose
    +way to the everlasting bonfire.
    +

    Knocking within

    +Anon, anon! I pray you, remember the porter.
    +

    Opens the gate

    +

    Enter MACDUFF and LENNOX

    +
    + +MACDUFF +
    +Was it so late, friend, ere you went to bed,
    +That you do lie so late?
    +
    + +Porter +
    +'Faith sir, we were carousing till the
    +second cock: and drink, sir, is a great
    +provoker of three things.
    +
    + +MACDUFF +
    +What three things does drink especially provoke?
    +
    + +Porter +
    +Marry, sir, nose-painting, sleep, and
    +urine. Lechery, sir, it provokes, and unprovokes;
    +it provokes the desire, but it takes
    +away the performance: therefore, much drink
    +may be said to be an equivocator with lechery:
    +it makes him, and it mars him; it sets
    +him on, and it takes him off; it persuades him,
    +and disheartens him; makes him stand to, and
    +not stand to; in conclusion, equivocates him
    +in a sleep, and, giving him the lie, leaves him.
    +
    + +MACDUFF +
    +I believe drink gave thee the lie last night.
    +
    + +Porter +
    +That it did, sir, i' the very throat on
    +me: but I requited him for his lie; and, I
    +think, being too strong for him, though he took
    +up my legs sometime, yet I made a shift to cast
    +him.
    +
    + +MACDUFF +
    +Is thy master stirring?
    +

    Enter MACBETH

    +Our knocking has awaked him; here he comes.
    +
    + +LENNOX +
    +Good morrow, noble sir.
    +
    + +MACBETH +
    +Good morrow, both.
    +
    + +MACDUFF +
    +Is the king stirring, worthy thane?
    +
    + +MACBETH +
    +Not yet.
    +
    + +MACDUFF +
    +He did command me to call timely on him:
    +I have almost slipp'd the hour.
    +
    + +MACBETH +
    +I'll bring you to him.
    +
    + +MACDUFF +
    +I know this is a joyful trouble to you;
    +But yet 'tis one.
    +
    + +MACBETH +
    +The labour we delight in physics pain.
    +This is the door.
    +
    + +MACDUFF +
    + I'll make so bold to call,
    +For 'tis my limited service.
    +

    Exit

    +
    + +LENNOX +
    +Goes the king hence to-day?
    +
    + +MACBETH +
    +He does: he did appoint so.
    +
    + +LENNOX +
    +The night has been unruly: where we lay,
    +Our chimneys were blown down; and, as they say,
    +Lamentings heard i' the air; strange screams of death,
    +And prophesying with accents terrible
    +Of dire combustion and confused events
    +New hatch'd to the woeful time: the obscure bird
    +Clamour'd the livelong night: some say, the earth
    +Was feverous and did shake.
    +
    + +MACBETH +
    +'Twas a rough night.
    +
    + +LENNOX +
    +My young remembrance cannot parallel
    +A fellow to it.
    +

    Re-enter MACDUFF

    +
    + +MACDUFF +
    +O horror, horror, horror! Tongue nor heart
    +Cannot conceive nor name thee!
    +
    + +MACBETH + +LENNOX +
    +What's the matter.
    +
    + +MACDUFF +
    +Confusion now hath made his masterpiece!
    +Most sacrilegious murder hath broke ope
    +The Lord's anointed temple, and stole thence
    +The life o' the building!
    +
    + +MACBETH +
    +What is 't you say? the life?
    +
    + +LENNOX +
    +Mean you his majesty?
    +
    + +MACDUFF +
    +Approach the chamber, and destroy your sight
    +With a new Gorgon: do not bid me speak;
    +See, and then speak yourselves.
    +

    Exeunt MACBETH and LENNOX

    +Awake, awake!
    +Ring the alarum-bell. Murder and treason!
    +Banquo and Donalbain! Malcolm! awake!
    +Shake off this downy sleep, death's counterfeit,
    +And look on death itself! up, up, and see
    +The great doom's image! Malcolm! Banquo!
    +As from your graves rise up, and walk like sprites,
    +To countenance this horror! Ring the bell.
    +

    Bell rings

    +

    Enter LADY MACBETH

    +
    + +LADY MACBETH +
    +What's the business,
    +That such a hideous trumpet calls to parley
    +The sleepers of the house? speak, speak!
    +
    + +MACDUFF +
    +O gentle lady,
    +'Tis not for you to hear what I can speak:
    +The repetition, in a woman's ear,
    +Would murder as it fell.
    +

    Enter BANQUO

    +O Banquo, Banquo,
    +Our royal master 's murder'd!
    +
    + +LADY MACBETH +
    +Woe, alas!
    +What, in our house?
    +
    + +BANQUO +
    +Too cruel any where.
    +Dear Duff, I prithee, contradict thyself,
    +And say it is not so.
    +

    Re-enter MACBETH and LENNOX, with ROSS

    +
    + +MACBETH +
    +Had I but died an hour before this chance,
    +I had lived a blessed time; for, from this instant,
    +There 's nothing serious in mortality:
    +All is but toys: renown and grace is dead;
    +The wine of life is drawn, and the mere lees
    +Is left this vault to brag of.
    +

    Enter MALCOLM and DONALBAIN

    +
    + +DONALBAIN +
    +What is amiss?
    +
    + +MACBETH +
    + You are, and do not know't:
    +The spring, the head, the fountain of your blood
    +Is stopp'd; the very source of it is stopp'd.
    +
    + +MACDUFF +
    +Your royal father 's murder'd.
    +
    + +MALCOLM +
    +O, by whom?
    +
    + +LENNOX +
    +Those of his chamber, as it seem'd, had done 't:
    +Their hands and faces were an badged with blood;
    +So were their daggers, which unwiped we found
    +Upon their pillows:
    +They stared, and were distracted; no man's life
    +Was to be trusted with them.
    +
    + +MACBETH +
    +O, yet I do repent me of my fury,
    +That I did kill them.
    +
    + +MACDUFF +
    +Wherefore did you so?
    +
    + +MACBETH +
    +Who can be wise, amazed, temperate and furious,
    +Loyal and neutral, in a moment? No man:
    +The expedition my violent love
    +Outrun the pauser, reason. Here lay Duncan,
    +His silver skin laced with his golden blood;
    +And his gash'd stabs look'd like a breach in nature
    +For ruin's wasteful entrance: there, the murderers,
    +Steep'd in the colours of their trade, their daggers
    +Unmannerly breech'd with gore: who could refrain,
    +That had a heart to love, and in that heart
    +Courage to make 's love kno wn?
    +
    + +LADY MACBETH +
    +Help me hence, ho!
    +
    + +MACDUFF +
    +Look to the lady.
    +
    + +MALCOLM +
    +[Aside to DONALBAIN] Why do we hold our tongues,
    +That most may claim this argument for ours?
    +
    + +DONALBAIN +
    +[Aside to MALCOLM] What should be spoken here,
    +where our fate,
    +Hid in an auger-hole, may rush, and seize us?
    +Let 's away;
    +Our tears are not yet brew'd.
    +
    + +MALCOLM +
    +[Aside to DONALBAIN] Nor our strong sorrow
    +Upon the foot of motion.
    +
    + +BANQUO +
    +Look to the lady:
    +

    LADY MACBETH is carried out

    +And when we have our naked frailties hid,
    +That suffer in exposure, let us meet,
    +And question this most bloody piece of work,
    +To know it further. Fears and scruples shake us:
    +In the great hand of God I stand; and thence
    +Against the undivulged pretence I fight
    +Of treasonous malice.
    +
    + +MACDUFF +
    +And so do I.
    +
    + +ALL +
    +So all.
    +
    + +MACBETH +
    +Let's briefly put on manly readiness,
    +And meet i' the hall together.
    +
    + +ALL +
    +Well contented.
    +

    Exeunt all but Malcolm and Donalbain.

    +
    + +MALCOLM +
    +What will you do? Let's not consort with them:
    +To show an unfelt sorrow is an office
    +Which the false man does easy. I'll to England.
    +
    + +DONALBAIN +
    +To Ireland, I; our separated fortune
    +Shall keep us both the safer: where we are,
    +There's daggers in men's smiles: the near in blood,
    +The nearer bloody.
    +
    + +MALCOLM +
    + This murderous shaft that's shot
    +Hath not yet lighted, and our safest way
    +Is to avoid the aim. Therefore, to horse;
    +And let us not be dainty of leave-taking,
    +But shift away: there's warrant in that theft
    +Which steals itself, when there's no mercy left.
    +

    Exeunt

    +
    +

    SCENE IV. Outside Macbeth's castle.

    +

    +Enter ROSS and an old Man +
    + +Old Man +
    +Threescore and ten I can remember well:
    +Within the volume of which time I have seen
    +Hours dreadful and things strange; but this sore night
    +Hath trifled former knowings.
    +
    + +ROSS +
    +Ah, good father,
    +Thou seest, the heavens, as troubled with man's act,
    +Threaten his bloody stage: by the clock, 'tis day,
    +And yet dark night strangles the travelling lamp:
    +Is't night's predominance, or the day's shame,
    +That darkness does the face of earth entomb,
    +When living light should kiss it?
    +
    + +Old Man +
    +'Tis unnatural,
    +Even like the deed that's done. On Tuesday last,
    +A falcon, towering in her pride of place,
    +Was by a mousing owl hawk'd at and kill'd.
    +
    + +ROSS +
    +And Duncan's horses--a thing most strange and certain--
    +Beauteous and swift, the minions of their race,
    +Turn'd wild in nature, broke their stalls, flung out,
    +Contending 'gainst obedience, as they would make
    +War with mankind.
    +
    + +Old Man +
    +'Tis said they eat each other.
    +
    + +ROSS +
    +They did so, to the amazement of mine eyes
    +That look'd upon't. Here comes the good Macduff.
    +

    Enter MACDUFF

    +How goes the world, sir, now?
    +
    + +MACDUFF +
    +Why, see you not?
    +
    + +ROSS +
    +Is't known who did this more than bloody deed?
    +
    + +MACDUFF +
    +Those that Macbeth hath slain.
    +
    + +ROSS +
    +Alas, the day!
    +What good could they pretend?
    +
    + +MACDUFF +
    +They were suborn'd:
    +Malcolm and Donalbain, the king's two sons,
    +Are stol'n away and fled; which puts upon them
    +Suspicion of the deed.
    +
    + +ROSS +
    +'Gainst nature still!
    +Thriftless ambition, that wilt ravin up
    +Thine own life's means! Then 'tis most like
    +The sovereignty will fall upon Macbeth.
    +
    + +MACDUFF +
    +He is already named, and gone to Scone
    +To be invested.
    +
    + +ROSS +
    + Where is Duncan's body?
    +
    + +MACDUFF +
    +Carried to Colmekill,
    +The sacred storehouse of his predecessors,
    +And guardian of their bones.
    +
    + +ROSS +
    +Will you to Scone?
    +
    + +MACDUFF +
    +No, cousin, I'll to Fife.
    +
    + +ROSS +
    +Well, I will thither.
    +
    + +MACDUFF +
    +Well, may you see things well done there: adieu!
    +Lest our old robes sit easier than our new!
    +
    + +ROSS +
    +Farewell, father.
    +
    + +Old Man +
    +God's benison go with you; and with those
    +That would make good of bad, and friends of foes!
    +

    Exeunt

    +

    +

    ACT III

    +

    SCENE I. Forres. The palace.

    +

    +Enter BANQUO +
    + +BANQUO +
    +Thou hast it now: king, Cawdor, Glamis, all,
    +As the weird women promised, and, I fear,
    +Thou play'dst most foully for't: yet it was said
    +It should not stand in thy posterity,
    +But that myself should be the root and father
    +Of many kings. If there come truth from them--
    +As upon thee, Macbeth, their speeches shine--
    +Why, by the verities on thee made good,
    +May they not be my oracles as well,
    +And set me up in hope? But hush! no more.
    +

    Sennet sounded. Enter MACBETH, as king, LADY MACBETH, as queen, LENNOX, ROSS, Lords, Ladies, and Attendants

    +
    + +MACBETH +
    +Here's our chief guest.
    +
    + +LADY MACBETH +
    +If he had been forgotten,
    +It had been as a gap in our great feast,
    +And all-thing unbecoming.
    +
    + +MACBETH +
    +To-night we hold a solemn supper sir,
    +And I'll request your presence.
    +
    + +BANQUO +
    +Let your highness
    +Command upon me; to the which my duties
    +Are with a most indissoluble tie
    +For ever knit.
    +
    + +MACBETH +
    + Ride you this afternoon?
    +
    + +BANQUO +
    +Ay, my good lord.
    +
    + +MACBETH +
    +We should have else desired your good advice,
    +Which still hath been both grave and prosperous,
    +In this day's council; but we'll take to-morrow.
    +Is't far you ride?
    +
    + +BANQUO +
    +As far, my lord, as will fill up the time
    +'Twixt this and supper: go not my horse the better,
    +I must become a borrower of the night
    +For a dark hour or twain.
    +
    + +MACBETH +
    +Fail not our feast.
    +
    + +BANQUO +
    +My lord, I will not.
    +
    + +MACBETH +
    +We hear, our bloody cousins are bestow'd
    +In England and in Ireland, not confessing
    +Their cruel parricide, filling their hearers
    +With strange invention: but of that to-morrow,
    +When therewithal we shall have cause of state
    +Craving us jointly. Hie you to horse: adieu,
    +Till you return at night. Goes Fleance with you?
    +
    + +BANQUO +
    +Ay, my good lord: our time does call upon 's.
    +
    + +MACBETH +
    +I wish your horses swift and sure of foot;
    +And so I do commend you to their backs. Farewell.
    +

    Exit BANQUO

    +Let every man be master of his time
    +Till seven at night: to make society
    +The sweeter welcome, we will keep ourself
    +Till supper-time alone: while then, God be with you!
    +

    Exeunt all but MACBETH, and an attendant

    +Sirrah, a word with you: attend those men
    +Our pleasure?
    +
    + +ATTENDANT +
    +They are, my lord, without the palace gate.
    +
    + +MACBETH +
    +Bring them before us.
    +

    Exit Attendant

    +To be thus is nothing;
    +But to be safely thus.--Our fears in Banquo
    +Stick deep; and in his royalty of nature
    +Reigns that which would be fear'd: 'tis much he dares;
    +And, to that dauntless temper of his mind,
    +He hath a wisdom that doth guide his valour
    +To act in safety. There is none but he
    +Whose being I do fear: and, under him,
    +My Genius is rebuked; as, it is said,
    +Mark Antony's was by Caesar. He chid the sisters
    +When first they put the name of king upon me,
    +And bade them speak to him: then prophet-like
    +They hail'd him father to a line of kings:
    +Upon my head they placed a fruitless crown,
    +And put a barren sceptre in my gripe,
    +Thence to be wrench'd with an unlineal hand,
    +No son of mine succeeding. If 't be so,
    +For Banquo's issue have I filed my mind;
    +For them the gracious Duncan have I murder'd;
    +Put rancours in the vessel of my peace
    +Only for them; and mine eternal jewel
    +Given to the common enemy of man,
    +To make them kings, the seed of Banquo kings!
    +Rather than so, come fate into the list.
    +And champion me to the utterance! Who's there!
    +

    Re-enter Attendant, with two Murderers

    +Now go to the door, and stay there till we call.
    +

    Exit Attendant

    +Was it not yesterday we spoke together?
    +
    + +First Murderer +
    +It was, so please your highness.
    +
    + +MACBETH +
    +Well then, now
    +Have you consider'd of my speeches? Know
    +That it was he in the times past which held you
    +So under fortune, which you thought had been
    +Our innocent self: this I made good to you
    +In our last conference, pass'd in probation with you,
    +How you were borne in hand, how cross'd,
    +the instruments,
    +Who wrought with them, and all things else that might
    +To half a soul and to a notion crazed
    +Say 'Thus did Banquo.'
    +
    + +First Murderer +
    +You made it known to us.
    +
    + +MACBETH +
    +I did so, and went further, which is now
    +Our point of second meeting. Do you find
    +Your patience so predominant in your nature
    +That you can let this go? Are you so gospell'd
    +To pray for this good man and for his issue,
    +Whose heavy hand hath bow'd you to the grave
    +And beggar'd yours for ever?
    +
    + +First Murderer +
    +We are men, my liege.
    +
    + +MACBETH +
    +Ay, in the catalogue ye go for men;
    +As hounds and greyhounds, mongrels, spaniels, curs,
    +Shoughs, water-rugs and demi-wolves, are clept
    +All by the name of dogs: the valued file
    +Distinguishes the swift, the slow, the subtle,
    +The housekeeper, the hunter, every one
    +According to the gift which bounteous nature
    +Hath in him closed; whereby he does receive
    +Particular addition. from the bill
    +That writes them all alike: and so of men.
    +Now, if you have a station in the file,
    +Not i' the worst rank of manhood, say 't;
    +And I will put that business in your bosoms,
    +Whose execution takes your enemy off,
    +Grapples you to the heart and love of us,
    +Who wear our health but sickly in his life,
    +Which in his death were perfect.
    +
    + +Second Murderer +
    +I am one, my liege,
    +Whom the vile blows and buffets of the world
    +Have so incensed that I am reckless what
    +I do to spite the world.
    +
    + +First Murderer +
    +And I another
    +So weary with disasters, tugg'd with fortune,
    +That I would set my lie on any chance,
    +To mend it, or be rid on't.
    +
    + +MACBETH +
    +Both of you
    +Know Banquo was your enemy.
    +
    + +Both Murderers +
    +True, my lord.
    +
    + +MACBETH +
    +So is he mine; and in such bloody distance,
    +That every minute of his being thrusts
    +Against my near'st of life: and though I could
    +With barefaced power sweep him from my sight
    +And bid my will avouch it, yet I must not,
    +For certain friends that are both his and mine,
    +Whose loves I may not drop, but wail his fall
    +Who I myself struck down; and thence it is,
    +That I to your assistance do make love,
    +Masking the business from the common eye
    +For sundry weighty reasons.
    +
    + +Second Murderer +
    +We shall, my lord,
    +Perform what you command us.
    +
    + +First Murderer +
    +Though our lives--
    +
    + +MACBETH +
    +Your spirits shine through you. Within this hour at most
    +I will advise you where to plant yourselves;
    +Acquaint you with the perfect spy o' the time,
    +The moment on't; for't must be done to-night,
    +And something from the palace; always thought
    +That I require a clearness: and with him--
    +To leave no rubs nor botches in the work--
    +Fleance his son, that keeps him company,
    +Whose absence is no less material to me
    +Than is his father's, must embrace the fate
    +Of that dark hour. Resolve yourselves apart:
    +I'll come to you anon.
    +
    + +Both Murderers +
    +We are resolved, my lord.
    +
    + +MACBETH +
    +I'll call upon you straight: abide within.
    +

    Exeunt Murderers

    +It is concluded. Banquo, thy soul's flight,
    +If it find heaven, must find it out to-night.
    +

    Exit

    +
    +

    SCENE II. The palace.

    +

    +Enter LADY MACBETH and a Servant +
    + +LADY MACBETH +
    +Is Banquo gone from court?
    +
    + +Servant +
    +Ay, madam, but returns again to-night.
    +
    + +LADY MACBETH +
    +Say to the king, I would attend his leisure
    +For a few words.
    +
    + +Servant +
    + Madam, I will.
    +

    Exit

    +
    + +LADY MACBETH +
    +Nought's had, all's spent,
    +Where our desire is got without content:
    +'Tis safer to be that which we destroy
    +Than by destruction dwell in doubtful joy.
    +

    Enter MACBETH

    +How now, my lord! why do you keep alone,
    +Of sorriest fancies your companions making,
    +Using those thoughts which should indeed have died
    +With them they think on? Things without all remedy
    +Should be without regard: what's done is done.
    +
    + +MACBETH +
    +We have scotch'd the snake, not kill'd it:
    +She'll close and be herself, whilst our poor malice
    +Remains in danger of her former tooth.
    +But let the frame of things disjoint, both the
    +worlds suffer,
    +Ere we will eat our meal in fear and sleep
    +In the affliction of these terrible dreams
    +That shake us nightly: better be with the dead,
    +Whom we, to gain our peace, have sent to peace,
    +Than on the torture of the mind to lie
    +In restless ecstasy. Duncan is in his grave;
    +After life's fitful fever he sleeps well;
    +Treason has done his worst: nor steel, nor poison,
    +Malice domestic, foreign levy, nothing,
    +Can touch him further.
    +
    + +LADY MACBETH +
    +Come on;
    +Gentle my lord, sleek o'er your rugged looks;
    +Be bright and jovial among your guests to-night.
    +
    + +MACBETH +
    +So shall I, love; and so, I pray, be you:
    +Let your remembrance apply to Banquo;
    +Present him eminence, both with eye and tongue:
    +Unsafe the while, that we
    +Must lave our honours in these flattering streams,
    +And make our faces vizards to our hearts,
    +Disguising what they are.
    +
    + +LADY MACBETH +
    +You must leave this.
    +
    + +MACBETH +
    +O, full of scorpions is my mind, dear wife!
    +Thou know'st that Banquo, and his Fleance, lives.
    +
    + +LADY MACBETH +
    +But in them nature's copy's not eterne.
    +
    + +MACBETH +
    +There's comfort yet; they are assailable;
    +Then be thou jocund: ere the bat hath flown
    +His cloister'd flight, ere to black Hecate's summons
    +The shard-borne beetle with his drowsy hums
    +Hath rung night's yawning peal, there shall be done
    +A deed of dreadful note.
    +
    + +LADY MACBETH +
    +What's to be done?
    +
    + +MACBETH +
    +Be innocent of the knowledge, dearest chuck,
    +Till thou applaud the deed. Come, seeling night,
    +Scarf up the tender eye of pitiful day;
    +And with thy bloody and invisible hand
    +Cancel and tear to pieces that great bond
    +Which keeps me pale! Light thickens; and the crow
    +Makes wing to the rooky wood:
    +Good things of day begin to droop and drowse;
    +While night's black agents to their preys do rouse.
    +Thou marvell'st at my words: but hold thee still;
    +Things bad begun make strong themselves by ill.
    +So, prithee, go with me.
    +

    Exeunt

    +
    +

    SCENE III. A park near the palace.

    +

    +Enter three Murderers +
    + +First Murderer +
    +But who did bid thee join with us?
    +
    + +Third Murderer +
    +Macbeth.
    +
    + +Second Murderer +
    +He needs not our mistrust, since he delivers
    +Our offices and what we have to do
    +To the direction just.
    +
    + +First Murderer +
    +Then stand with us.
    +The west yet glimmers with some streaks of day:
    +Now spurs the lated traveller apace
    +To gain the timely inn; and near approaches
    +The subject of our watch.
    +
    + +Third Murderer +
    +Hark! I hear horses.
    +
    + +BANQUO +
    +[Within] Give us a light there, ho!
    +
    + +Second Murderer +
    +Then 'tis he: the rest
    +That are within the note of expectation
    +Already are i' the court.
    +
    + +First Murderer +
    +His horses go about.
    +
    + +Third Murderer +
    +Almost a mile: but he does usually,
    +So all men do, from hence to the palace gate
    +Make it their walk.
    +
    + +Second Murderer +
    +A light, a light!
    +

    Enter BANQUO, and FLEANCE with a torch

    +
    + +Third Murderer +
    +'Tis he.
    +
    + +First Murderer +
    +Stand to't.
    +
    + +BANQUO +
    +It will be rain to-night.
    +
    + +First Murderer +
    +Let it come down.
    +

    They set upon BANQUO

    +
    + +BANQUO +
    +O, treachery! Fly, good Fleance, fly, fly, fly!
    +Thou mayst revenge. O slave!
    +

    Dies. FLEANCE escapes

    +
    + +Third Murderer +
    +Who did strike out the light?
    +
    + +First Murderer +
    +Wast not the way?
    +
    + +Third Murderer +
    +There's but one down; the son is fled.
    +
    + +Second Murderer +
    +We have lost
    +Best half of our affair.
    +
    + +First Murderer +
    +Well, let's away, and say how much is done.
    +

    Exeunt

    +
    +

    SCENE IV. The same. Hall in the palace.

    +

    +A banquet prepared. Enter MACBETH, LADY MACBETH, ROSS, LENNOX, Lords, and Attendants +
    + +MACBETH +
    +You know your own degrees; sit down: at first
    +And last the hearty welcome.
    +
    + +Lords +
    +Thanks to your majesty.
    +
    + +MACBETH +
    +Ourself will mingle with society,
    +And play the humble host.
    +Our hostess keeps her state, but in best time
    +We will require her welcome.
    +
    + +LADY MACBETH +
    +Pronounce it for me, sir, to all our friends;
    +For my heart speaks they are welcome.
    +

    First Murderer appears at the door

    +
    + +MACBETH +
    +See, they encounter thee with their hearts' thanks.
    +Both sides are even: here I'll sit i' the midst:
    +Be large in mirth; anon we'll drink a measure
    +The table round.
    +

    Approaching the door

    +There's blood on thy face.
    +
    + +First Murderer +
    +'Tis Banquo's then.
    +
    + +MACBETH +
    +'Tis better thee without than he within.
    +Is he dispatch'd?
    +
    + +First Murderer +
    +My lord, his throat is cut; that I did for him.
    +
    + +MACBETH +
    +Thou art the best o' the cut-throats: yet he's good
    +That did the like for Fleance: if thou didst it,
    +Thou art the nonpareil.
    +
    + +First Murderer +
    +Most royal sir,
    +Fleance is 'scaped.
    +
    + +MACBETH +
    +Then comes my fit again: I had else been perfect,
    +Whole as the marble, founded as the rock,
    +As broad and general as the casing air:
    +But now I am cabin'd, cribb'd, confined, bound in
    +To saucy doubts and fears. But Banquo's safe?
    +
    + +First Murderer +
    +Ay, my good lord: safe in a ditch he bides,
    +With twenty trenched gashes on his head;
    +The least a death to nature.
    +
    + +MACBETH +
    +Thanks for that:
    +There the grown serpent lies; the worm that's fled
    +Hath nature that in time will venom breed,
    +No teeth for the present. Get thee gone: to-morrow
    +We'll hear, ourselves, again.
    +

    Exit Murderer

    +
    + +LADY MACBETH +
    +My royal lord,
    +You do not give the cheer: the feast is sold
    +That is not often vouch'd, while 'tis a-making,
    +'Tis given with welcome: to feed were best at home;
    +From thence the sauce to meat is ceremony;
    +Meeting were bare without it.
    +
    + +MACBETH +
    +Sweet remembrancer!
    +Now, good digestion wait on appetite,
    +And health on both!
    +
    + +LENNOX +
    +May't please your highness sit.
    +

    The GHOST OF BANQUO enters, and sits in MACBETH's place

    +
    + +MACBETH +
    +Here had we now our country's honour roof'd,
    +Were the graced person of our Banquo present;
    +Who may I rather challenge for unkindness
    +Than pity for mischance!
    +
    + +ROSS +
    +His absence, sir,
    +Lays blame upon his promise. Please't your highness
    +To grace us with your royal company.
    +
    + +MACBETH +
    +The table's full.
    +
    + +LENNOX +
    + Here is a place reserved, sir.
    +
    + +MACBETH +
    +Where?
    +
    + +LENNOX +
    +Here, my good lord. What is't that moves your highness?
    +
    + +MACBETH +
    +Which of you have done this?
    +
    + +Lords +
    +What, my good lord?
    +
    + +MACBETH +
    +Thou canst not say I did it: never shake
    +Thy gory locks at me.
    +
    + +ROSS +
    +Gentlemen, rise: his highness is not well.
    +
    + +LADY MACBETH +
    +Sit, worthy friends: my lord is often thus,
    +And hath been from his youth: pray you, keep seat;
    +The fit is momentary; upon a thought
    +He will again be well: if much you note him,
    +You shall offend him and extend his passion:
    +Feed, and regard him not. Are you a man?
    +
    + +MACBETH +
    +Ay, and a bold one, that dare look on that
    +Which might appal the devil.
    +
    + +LADY MACBETH +
    +O proper stuff!
    +This is the very painting of your fear:
    +This is the air-drawn dagger which, you said,
    +Led you to Duncan. O, these flaws and starts,
    +Impostors to true fear, would well become
    +A woman's story at a winter's fire,
    +Authorized by her grandam. Shame itself!
    +Why do you make such faces? When all's done,
    +You look but on a stool.
    +
    + +MACBETH +
    +Prithee, see there! behold! look! lo!
    +how say you?
    +Why, what care I? If thou canst nod, speak too.
    +If charnel-houses and our graves must send
    +Those that we bury back, our monuments
    +Shall be the maws of kites.
    +

    GHOST OF BANQUO vanishes

    +
    + +LADY MACBETH +
    +What, quite unmann'd in folly?
    +
    + +MACBETH +
    +If I stand here, I saw him.
    +
    + +LADY MACBETH +
    +Fie, for shame!
    +
    + +MACBETH +
    +Blood hath been shed ere now, i' the olden time,
    +Ere human statute purged the gentle weal;
    +Ay, and since too, murders have been perform'd
    +Too terrible for the ear: the times have been,
    +That, when the brains were out, the man would die,
    +And there an end; but now they rise again,
    +With twenty mortal murders on their crowns,
    +And push us from our stools: this is more strange
    +Than such a murder is.
    +
    + +LADY MACBETH +
    +My worthy lord,
    +Your noble friends do lack you.
    +
    + +MACBETH +
    +I do forget.
    +Do not muse at me, my most worthy friends,
    +I have a strange infirmity, which is nothing
    +To those that know me. Come, love and health to all;
    +Then I'll sit down. Give me some wine; fill full.
    +I drink to the general joy o' the whole table,
    +And to our dear friend Banquo, whom we miss;
    +Would he were here! to all, and him, we thirst,
    +And all to all.
    +
    + +Lords +
    + Our duties, and the pledge.
    +

    Re-enter GHOST OF BANQUO

    +
    + +MACBETH +
    +Avaunt! and quit my sight! let the earth hide thee!
    +Thy bones are marrowless, thy blood is cold;
    +Thou hast no speculation in those eyes
    +Which thou dost glare with!
    +
    + +LADY MACBETH +
    +Think of this, good peers,
    +But as a thing of custom: 'tis no other;
    +Only it spoils the pleasure of the time.
    +
    + +MACBETH +
    +What man dare, I dare:
    +Approach thou like the rugged Russian bear,
    +The arm'd rhinoceros, or the Hyrcan tiger;
    +Take any shape but that, and my firm nerves
    +Shall never tremble: or be alive again,
    +And dare me to the desert with thy sword;
    +If trembling I inhabit then, protest me
    +The baby of a girl. Hence, horrible shadow!
    +Unreal mockery, hence!
    +

    GHOST OF BANQUO vanishes

    +Why, so: being gone,
    +I am a man again. Pray you, sit still.
    +
    + +LADY MACBETH +
    +You have displaced the mirth, broke the good meeting,
    +With most admired disorder.
    +
    + +MACBETH +
    +Can such things be,
    +And overcome us like a summer's cloud,
    +Without our special wonder? You make me strange
    +Even to the disposition that I owe,
    +When now I think you can behold such sights,
    +And keep the natural ruby of your cheeks,
    +When mine is blanched with fear.
    +
    + +ROSS +
    +What sights, my lord?
    +
    + +LADY MACBETH +
    +I pray you, speak not; he grows worse and worse;
    +Question enrages him. At once, good night:
    +Stand not upon the order of your going,
    +But go at once.
    +
    + +LENNOX +
    + Good night; and better health
    +Attend his majesty!
    +
    + +LADY MACBETH +
    +A kind good night to all!
    +

    Exeunt all but MACBETH and LADY MACBETH

    +
    + +MACBETH +
    +It will have blood; they say, blood will have blood:
    +Stones have been known to move and trees to speak;
    +Augurs and understood relations have
    +By magot-pies and choughs and rooks brought forth
    +The secret'st man of blood. What is the night?
    +
    + +LADY MACBETH +
    +Almost at odds with morning, which is which.
    +
    + +MACBETH +
    +How say'st thou, that Macduff denies his person
    +At our great bidding?
    +
    + +LADY MACBETH +
    +Did you send to him, sir?
    +
    + +MACBETH +
    +I hear it by the way; but I will send:
    +There's not a one of them but in his house
    +I keep a servant fee'd. I will to-morrow,
    +And betimes I will, to the weird sisters:
    +More shall they speak; for now I am bent to know,
    +By the worst means, the worst. For mine own good,
    +All causes shall give way: I am in blood
    +Stepp'd in so far that, should I wade no more,
    +Returning were as tedious as go o'er:
    +Strange things I have in head, that will to hand;
    +Which must be acted ere they may be scann'd.
    +
    + +LADY MACBETH +
    +You lack the season of all natures, sleep.
    +
    + +MACBETH +
    +Come, we'll to sleep. My strange and self-abuse
    +Is the initiate fear that wants hard use:
    +We are yet but young in deed.
    +

    Exeunt

    +
    +

    SCENE V. A Heath.

    +

    +Thunder. Enter the three Witches meeting HECATE +
    + +First Witch +
    +Why, how now, Hecate! you look angerly.
    +
    + +HECATE +
    +Have I not reason, beldams as you are,
    +Saucy and overbold? How did you dare
    +To trade and traffic with Macbeth
    +In riddles and affairs of death;
    +And I, the mistress of your charms,
    +The close contriver of all harms,
    +Was never call'd to bear my part,
    +Or show the glory of our art?
    +And, which is worse, all you have done
    +Hath been but for a wayward son,
    +Spiteful and wrathful, who, as others do,
    +Loves for his own ends, not for you.
    +But make amends now: get you gone,
    +And at the pit of Acheron
    +Meet me i' the morning: thither he
    +Will come to know his destiny:
    +Your vessels and your spells provide,
    +Your charms and every thing beside.
    +I am for the air; this night I'll spend
    +Unto a dismal and a fatal end:
    +Great business must be wrought ere noon:
    +Upon the corner of the moon
    +There hangs a vaporous drop profound;
    +I'll catch it ere it come to ground:
    +And that distill'd by magic sleights
    +Shall raise such artificial sprites
    +As by the strength of their illusion
    +Shall draw him on to his confusion:
    +He shall spurn fate, scorn death, and bear
    +He hopes 'bove wisdom, grace and fear:
    +And you all know, security
    +Is mortals' chiefest enemy.
    +

    Music and a song within: 'Come away, come away,' & c

    +Hark! I am call'd; my little spirit, see,
    +Sits in a foggy cloud, and stays for me.
    +

    Exit

    +
    + +First Witch +
    +Come, let's make haste; she'll soon be back again.
    +

    Exeunt

    +
    +

    SCENE VI. Forres. The palace.

    +

    +Enter LENNOX and another Lord +
    + +LENNOX +
    +My former speeches have but hit your thoughts,
    +Which can interpret further: only, I say,
    +Things have been strangely borne. The
    +gracious Duncan
    +Was pitied of Macbeth: marry, he was dead:
    +And the right-valiant Banquo walk'd too late;
    +Whom, you may say, if't please you, Fleance kill'd,
    +For Fleance fled: men must not walk too late.
    +Who cannot want the thought how monstrous
    +It was for Malcolm and for Donalbain
    +To kill their gracious father? damned fact!
    +How it did grieve Macbeth! did he not straight
    +In pious rage the two delinquents tear,
    +That were the slaves of drink and thralls of sleep?
    +Was not that nobly done? Ay, and wisely too;
    +For 'twould have anger'd any heart alive
    +To hear the men deny't. So that, I say,
    +He has borne all things well: and I do think
    +That had he Duncan's sons under his key--
    +As, an't please heaven, he shall not--they
    +should find
    +What 'twere to kill a father; so should Fleance.
    +But, peace! for from broad words and 'cause he fail'd
    +His presence at the tyrant's feast, I hear
    +Macduff lives in disgrace: sir, can you tell
    +Where he bestows himself?
    +
    + +Lord +
    +The son of Duncan,
    +From whom this tyrant holds the due of birth
    +Lives in the English court, and is received
    +Of the most pious Edward with such grace
    +That the malevolence of fortune nothing
    +Takes from his high respect: thither Macduff
    +Is gone to pray the holy king, upon his aid
    +To wake Northumberland and warlike Siward:
    +That, by the help of these--with Him above
    +To ratify the work--we may again
    +Give to our tables meat, sleep to our nights,
    +Free from our feasts and banquets bloody knives,
    +Do faithful homage and receive free honours:
    +All which we pine for now: and this report
    +Hath so exasperate the king that he
    +Prepares for some attempt of war.
    +
    + +LENNOX +
    +Sent he to Macduff?
    +
    + +Lord +
    +He did: and with an absolute 'Sir, not I,'
    +The cloudy messenger turns me his back,
    +And hums, as who should say 'You'll rue the time
    +That clogs me with this answer.'
    +
    + +LENNOX +
    +And that well might
    +Advise him to a caution, to hold what distance
    +His wisdom can provide. Some holy angel
    +Fly to the court of England and unfold
    +His message ere he come, that a swift blessing
    +May soon return to this our suffering country
    +Under a hand accursed!
    +
    + +Lord +
    +I'll send my prayers with him.
    +

    Exeunt

    +

    +

    ACT IV

    +

    SCENE I. A cavern. In the middle, a boiling cauldron.

    +

    +Thunder. Enter the three Witches +
    + +First Witch +
    +Thrice the brinded cat hath mew'd.
    +
    + +Second Witch +
    +Thrice and once the hedge-pig whined.
    +
    + +Third Witch +
    +Harpier cries 'Tis time, 'tis time.
    +
    + +First Witch +
    +Round about the cauldron go;
    +In the poison'd entrails throw.
    +Toad, that under cold stone
    +Days and nights has thirty-one
    +Swelter'd venom sleeping got,
    +Boil thou first i' the charmed pot.
    +
    + +ALL +
    +Double, double toil and trouble;
    +Fire burn, and cauldron bubble.
    +
    + +Second Witch +
    +Fillet of a fenny snake,
    +In the cauldron boil and bake;
    +Eye of newt and toe of frog,
    +Wool of bat and tongue of dog,
    +Adder's fork and blind-worm's sting,
    +Lizard's leg and owlet's wing,
    +For a charm of powerful trouble,
    +Like a hell-broth boil and bubble.
    +
    + +ALL +
    +Double, double toil and trouble;
    +Fire burn and cauldron bubble.
    +
    + +Third Witch +
    +Scale of dragon, tooth of wolf,
    +Witches' mummy, maw and gulf
    +Of the ravin'd salt-sea shark,
    +Root of hemlock digg'd i' the dark,
    +Liver of blaspheming Jew,
    +Gall of goat, and slips of yew
    +Silver'd in the moon's eclipse,
    +Nose of Turk and Tartar's lips,
    +Finger of birth-strangled babe
    +Ditch-deliver'd by a drab,
    +Make the gruel thick and slab:
    +Add thereto a tiger's chaudron,
    +For the ingredients of our cauldron.
    +
    + +ALL +
    +Double, double toil and trouble;
    +Fire burn and cauldron bubble.
    +
    + +Second Witch +
    +Cool it with a baboon's blood,
    +Then the charm is firm and good.
    +

    Enter HECATE to the other three Witches

    +
    + +HECATE +
    +O well done! I commend your pains;
    +And every one shall share i' the gains;
    +And now about the cauldron sing,
    +Live elves and fairies in a ring,
    +Enchanting all that you put in.
    +

    Music and a song: 'Black spirits,' & c

    +

    HECATE retires

    +
    + +Second Witch +
    +By the pricking of my thumbs,
    +Something wicked this way comes.
    +Open, locks,
    +Whoever knocks!
    +

    Enter MACBETH

    +
    + +MACBETH +
    +How now, you secret, black, and midnight hags!
    +What is't you do?
    +
    + +ALL +
    + A deed without a name.
    +
    + +MACBETH +
    +I conjure you, by that which you profess,
    +Howe'er you come to know it, answer me:
    +Though you untie the winds and let them fight
    +Against the churches; though the yesty waves
    +Confound and swallow navigation up;
    +Though bladed corn be lodged and trees blown down;
    +Though castles topple on their warders' heads;
    +Though palaces and pyramids do slope
    +Their heads to their foundations; though the treasure
    +Of nature's germens tumble all together,
    +Even till destruction sicken; answer me
    +To what I ask you.
    +
    + +First Witch +
    + Speak.
    +
    + +Second Witch +
    +Demand.
    +
    + +Third Witch +
    +We'll answer.
    +
    + +First Witch +
    +Say, if thou'dst rather hear it from our mouths,
    +Or from our masters?
    +
    + +MACBETH +
    +Call 'em; let me see 'em.
    +
    + +First Witch +
    +Pour in sow's blood, that hath eaten
    +Her nine farrow; grease that's sweaten
    +From the murderer's gibbet throw
    +Into the flame.
    +
    + +ALL +
    + Come, high or low;
    +Thyself and office deftly show!
    +

    Thunder. First Apparition: an armed Head

    +
    + +MACBETH +
    +Tell me, thou unknown power,--
    +
    + +First Witch +
    +He knows thy thought:
    +Hear his speech, but say thou nought.
    +
    + +First Apparition +
    +Macbeth! Macbeth! Macbeth! beware Macduff;
    +Beware the thane of Fife. Dismiss me. Enough.
    +

    Descends

    +
    + +MACBETH +
    +Whate'er thou art, for thy good caution, thanks;
    +Thou hast harp'd my fear aright: but one
    +word more,--
    +
    + +First Witch +
    +He will not be commanded: here's another,
    +More potent than the first.
    +

    Thunder. Second Apparition: A bloody Child

    +
    + +Second Apparition +
    +Macbeth! Macbeth! Macbeth!
    +
    + +MACBETH +
    +Had I three ears, I'ld hear thee.
    +
    + +Second Apparition +
    +Be bloody, bold, and resolute; laugh to scorn
    +The power of man, for none of woman born
    +Shall harm Macbeth.
    +

    Descends

    +
    + +MACBETH +
    +Then live, Macduff: what need I fear of thee?
    +But yet I'll make assurance double sure,
    +And take a bond of fate: thou shalt not live;
    +That I may tell pale-hearted fear it lies,
    +And sleep in spite of thunder.
    +

    Thunder. Third Apparition: a Child crowned, with a tree in his hand

    +What is this
    +That rises like the issue of a king,
    +And wears upon his baby-brow the round
    +And top of sovereignty?
    +
    + +ALL +
    +Listen, but speak not to't.
    +
    + +Third Apparition +
    +Be lion-mettled, proud; and take no care
    +Who chafes, who frets, or where conspirers are:
    +Macbeth shall never vanquish'd be until
    +Great Birnam wood to high Dunsinane hill
    +Shall come against him.
    +

    Descends

    +
    + +MACBETH +
    +That will never be
    +Who can impress the forest, bid the tree
    +Unfix his earth-bound root? Sweet bodements! good!
    +Rebellion's head, rise never till the wood
    +Of Birnam rise, and our high-placed Macbeth
    +Shall live the lease of nature, pay his breath
    +To time and mortal custom. Yet my heart
    +Throbs to know one thing: tell me, if your art
    +Can tell so much: shall Banquo's issue ever
    +Reign in this kingdom?
    +
    + +ALL +
    +Seek to know no more.
    +
    + +MACBETH +
    +I will be satisfied: deny me this,
    +And an eternal curse fall on you! Let me know.
    +Why sinks that cauldron? and what noise is this?
    +

    Hautboys

    +
    + +First Witch +
    +Show!
    +
    + +Second Witch +
    +Show!
    +
    + +Third Witch +
    +Show!
    +
    + +ALL +
    +Show his eyes, and grieve his heart;
    +Come like shadows, so depart!
    +

    A show of Eight Kings, the last with a glass in his hand; GHOST OF BANQUO following

    +
    + +MACBETH +
    +Thou art too like the spirit of Banquo: down!
    +Thy crown does sear mine eye-balls. And thy hair,
    +Thou other gold-bound brow, is like the first.
    +A third is like the former. Filthy hags!
    +Why do you show me this? A fourth! Start, eyes!
    +What, will the line stretch out to the crack of doom?
    +Another yet! A seventh! I'll see no more:
    +And yet the eighth appears, who bears a glass
    +Which shows me many more; and some I see
    +That two-fold balls and treble scepters carry:
    +Horrible sight! Now, I see, 'tis true;
    +For the blood-bolter'd Banquo smiles upon me,
    +And points at them for his.
    +

    Apparitions vanish

    +What, is this so?
    +
    + +First Witch +
    +Ay, sir, all this is so: but why
    +Stands Macbeth thus amazedly?
    +Come, sisters, cheer we up his sprites,
    +And show the best of our delights:
    +I'll charm the air to give a sound,
    +While you perform your antic round:
    +That this great king may kindly say,
    +Our duties did his welcome pay.
    +

    Music. The witches dance and then vanish, with HECATE

    +
    + +MACBETH +
    +Where are they? Gone? Let this pernicious hour
    +Stand aye accursed in the calendar!
    +Come in, without there!
    +

    Enter LENNOX

    +
    + +LENNOX +
    +What's your grace's will?
    +
    + +MACBETH +
    +Saw you the weird sisters?
    +
    + +LENNOX +
    +No, my lord.
    +
    + +MACBETH +
    +Came they not by you?
    +
    + +LENNOX +
    +No, indeed, my lord.
    +
    + +MACBETH +
    +Infected be the air whereon they ride;
    +And damn'd all those that trust them! I did hear
    +The galloping of horse: who was't came by?
    +
    + +LENNOX +
    +'Tis two or three, my lord, that bring you word
    +Macduff is fled to England.
    +
    + +MACBETH +
    +Fled to England!
    +
    + +LENNOX +
    +Ay, my good lord.
    +
    + +MACBETH +
    +Time, thou anticipatest my dread exploits:
    +The flighty purpose never is o'ertook
    +Unless the deed go with it; from this moment
    +The very firstlings of my heart shall be
    +The firstlings of my hand. And even now,
    +To crown my thoughts with acts, be it thought and done:
    +The castle of Macduff I will surprise;
    +Seize upon Fife; give to the edge o' the sword
    +His wife, his babes, and all unfortunate souls
    +That trace him in his line. No boasting like a fool;
    +This deed I'll do before this purpose cool.
    +But no more sights!--Where are these gentlemen?
    +Come, bring me where they are.
    +

    Exeunt

    +
    +

    SCENE II. Fife. Macduff's castle.

    +

    +Enter LADY MACDUFF, her Son, and ROSS +
    + +LADY MACDUFF +
    +What had he done, to make him fly the land?
    +
    + +ROSS +
    +You must have patience, madam.
    +
    + +LADY MACDUFF +
    +He had none:
    +His flight was madness: when our actions do not,
    +Our fears do make us traitors.
    +
    + +ROSS +
    +You know not
    +Whether it was his wisdom or his fear.
    +
    + +LADY MACDUFF +
    +Wisdom! to leave his wife, to leave his babes,
    +His mansion and his titles in a place
    +From whence himself does fly? He loves us not;
    +He wants the natural touch: for the poor wren,
    +The most diminutive of birds, will fight,
    +Her young ones in her nest, against the owl.
    +All is the fear and nothing is the love;
    +As little is the wisdom, where the flight
    +So runs against all reason.
    +
    + +ROSS +
    +My dearest coz,
    +I pray you, school yourself: but for your husband,
    +He is noble, wise, judicious, and best knows
    +The fits o' the season. I dare not speak
    +much further;
    +But cruel are the times, when we are traitors
    +And do not know ourselves, when we hold rumour
    +From what we fear, yet know not what we fear,
    +But float upon a wild and violent sea
    +Each way and move. I take my leave of you:
    +Shall not be long but I'll be here again:
    +Things at the worst will cease, or else climb upward
    +To what they were before. My pretty cousin,
    +Blessing upon you!
    +
    + +LADY MACDUFF +
    +Father'd he is, and yet he's fatherless.
    +
    + +ROSS +
    +I am so much a fool, should I stay longer,
    +It would be my disgrace and your discomfort:
    +I take my leave at once.
    +

    Exit

    +
    + +LADY MACDUFF +
    +Sirrah, your father's dead;
    +And what will you do now? How will you live?
    +
    + +Son +
    +As birds do, mother.
    +
    + +LADY MACDUFF +
    +What, with worms and flies?
    +
    + +Son +
    +With what I get, I mean; and so do they.
    +
    + +LADY MACDUFF +
    +Poor bird! thou'ldst never fear the net nor lime,
    +The pitfall nor the gin.
    +
    + +Son +
    +Why should I, mother? Poor birds they are not set for.
    +My father is not dead, for all your saying.
    +
    + +LADY MACDUFF +
    +Yes, he is dead; how wilt thou do for a father?
    +
    + +Son +
    +Nay, how will you do for a husband?
    +
    + +LADY MACDUFF +
    +Why, I can buy me twenty at any market.
    +
    + +Son +
    +Then you'll buy 'em to sell again.
    +
    + +LADY MACDUFF +
    +Thou speak'st with all thy wit: and yet, i' faith,
    +With wit enough for thee.
    +
    + +Son +
    +Was my father a traitor, mother?
    +
    + +LADY MACDUFF +
    +Ay, that he was.
    +
    + +Son +
    +What is a traitor?
    +
    + +LADY MACDUFF +
    +Why, one that swears and lies.
    +
    + +Son +
    +And be all traitors that do so?
    +
    + +LADY MACDUFF +
    +Every one that does so is a traitor, and must be hanged.
    +
    + +Son +
    +And must they all be hanged that swear and lie?
    +
    + +LADY MACDUFF +
    +Every one.
    +
    + +Son +
    +Who must hang them?
    +
    + +LADY MACDUFF +
    +Why, the honest men.
    +
    + +Son +
    +Then the liars and swearers are fools,
    +for there are liars and swearers enow to beat
    +the honest men and hang up them.
    +
    + +LADY MACDUFF +
    +Now, God help thee, poor monkey!
    +But how wilt thou do for a father?
    +
    + +Son +
    +If he were dead, you'ld weep for
    +him: if you would not, it were a good sign
    +that I should quickly have a new father.
    +
    + +LADY MACDUFF +
    +Poor prattler, how thou talk'st!
    +

    Enter a Messenger

    +
    + +Messenger +
    +Bless you, fair dame! I am not to you known,
    +Though in your state of honour I am perfect.
    +I doubt some danger does approach you nearly:
    +If you will take a homely man's advice,
    +Be not found here; hence, with your little ones.
    +To fright you thus, methinks, I am too savage;
    +To do worse to you were fell cruelty,
    +Which is too nigh your person. Heaven preserve you!
    +I dare abide no longer.
    +

    Exit

    +
    + +LADY MACDUFF +
    +Whither should I fly?
    +I have done no harm. But I remember now
    +I am in this earthly world; where to do harm
    +Is often laudable, to do good sometime
    +Accounted dangerous folly: why then, alas,
    +Do I put up that womanly defence,
    +To say I have done no harm?
    +

    Enter Murderers

    +What are these faces?
    +
    + +First Murderer +
    +Where is your husband?
    +
    + +LADY MACDUFF +
    +I hope, in no place so unsanctified
    +Where such as thou mayst find him.
    +
    + +First Murderer +
    +He's a traitor.
    +
    + +Son +
    +Thou liest, thou shag-hair'd villain!
    +
    + +First Murderer +
    +What, you egg!
    +

    Stabbing him

    +Young fry of treachery!
    +
    + +Son +
    +He has kill'd me, mother:
    +Run away, I pray you!
    +

    Dies

    +

    Exit LADY MACDUFF, crying 'Murder!' Exeunt Murderers, following her

    +
    +

    SCENE III. England. Before the King's palace.

    +

    +Enter MALCOLM and MACDUFF +
    + +MALCOLM +
    +Let us seek out some desolate shade, and there
    +Weep our sad bosoms empty.
    +
    + +MACDUFF +
    +Let us rather
    +Hold fast the mortal sword, and like good men
    +Bestride our down-fall'n birthdom: each new morn
    +New widows howl, new orphans cry, new sorrows
    +Strike heaven on the face, that it resounds
    +As if it felt with Scotland and yell'd out
    +Like syllable of dolour.
    +
    + +MALCOLM +
    +What I believe I'll wail,
    +What know believe, and what I can redress,
    +As I shall find the time to friend, I will.
    +What you have spoke, it may be so perchance.
    +This tyrant, whose sole name blisters our tongues,
    +Was once thought honest: you have loved him well.
    +He hath not touch'd you yet. I am young;
    +but something
    +You may deserve of him through me, and wisdom
    +To offer up a weak poor innocent lamb
    +To appease an angry god.
    +
    + +MACDUFF +
    +I am not treacherous.
    +
    + +MALCOLM +
    +But Macbeth is.
    +A good and virtuous nature may recoil
    +In an imperial charge. But I shall crave
    +your pardon;
    +That which you are my thoughts cannot transpose:
    +Angels are bright still, though the brightest fell;
    +Though all things foul would wear the brows of grace,
    +Yet grace must still look so.
    +
    + +MACDUFF +
    +I have lost my hopes.
    +
    + +MALCOLM +
    +Perchance even there where I did find my doubts.
    +Why in that rawness left you wife and child,
    +Those precious motives, those strong knots of love,
    +Without leave-taking? I pray you,
    +Let not my jealousies be your dishonours,
    +But mine own safeties. You may be rightly just,
    +Whatever I shall think.
    +
    + +MACDUFF +
    +Bleed, bleed, poor country!
    +Great tyranny! lay thou thy basis sure,
    +For goodness dare not cheque thee: wear thou
    +thy wrongs;
    +The title is affeer'd! Fare thee well, lord:
    +I would not be the villain that thou think'st
    +For the whole space that's in the tyrant's grasp,
    +And the rich East to boot.
    +
    + +MALCOLM +
    +Be not offended:
    +I speak not as in absolute fear of you.
    +I think our country sinks beneath the yoke;
    +It weeps, it bleeds; and each new day a gash
    +Is added to her wounds: I think withal
    +There would be hands uplifted in my right;
    +And here from gracious England have I offer
    +Of goodly thousands: but, for all this,
    +When I shall tread upon the tyrant's head,
    +Or wear it on my sword, yet my poor country
    +Shall have more vices than it had before,
    +More suffer and more sundry ways than ever,
    +By him that shall succeed.
    +
    + +MACDUFF +
    +What should he be?
    +
    + +MALCOLM +
    +It is myself I mean: in whom I know
    +All the particulars of vice so grafted
    +That, when they shall be open'd, black Macbeth
    +Will seem as pure as snow, and the poor state
    +Esteem him as a lamb, being compared
    +With my confineless harms.
    +
    + +MACDUFF +
    +Not in the legions
    +Of horrid hell can come a devil more damn'd
    +In evils to top Macbeth.
    +
    + +MALCOLM +
    +I grant him bloody,
    +Luxurious, avaricious, false, deceitful,
    +Sudden, malicious, smacking of every sin
    +That has a name: but there's no bottom, none,
    +In my voluptuousness: your wives, your daughters,
    +Your matrons and your maids, could not fill up
    +The cistern of my lust, and my desire
    +All continent impediments would o'erbear
    +That did oppose my will: better Macbeth
    +Than such an one to reign.
    +
    + +MACDUFF +
    +Boundless intemperance
    +In nature is a tyranny; it hath been
    +The untimely emptying of the happy throne
    +And fall of many kings. But fear not yet
    +To take upon you what is yours: you may
    +Convey your pleasures in a spacious plenty,
    +And yet seem cold, the time you may so hoodwink.
    +We have willing dames enough: there cannot be
    +That vulture in you, to devour so many
    +As will to greatness dedicate themselves,
    +Finding it so inclined.
    +
    + +MALCOLM +
    +With this there grows
    +In my most ill-composed affection such
    +A stanchless avarice that, were I king,
    +I should cut off the nobles for their lands,
    +Desire his jewels and this other's house:
    +And my more-having would be as a sauce
    +To make me hunger more; that I should forge
    +Quarrels unjust against the good and loyal,
    +Destroying them for wealth.
    +
    + +MACDUFF +
    +This avarice
    +Sticks deeper, grows with more pernicious root
    +Than summer-seeming lust, and it hath been
    +The sword of our slain kings: yet do not fear;
    +Scotland hath foisons to fill up your will.
    +Of your mere own: all these are portable,
    +With other graces weigh'd.
    +
    + +MALCOLM +
    +But I have none: the king-becoming graces,
    +As justice, verity, temperance, stableness,
    +Bounty, perseverance, mercy, lowliness,
    +Devotion, patience, courage, fortitude,
    +I have no relish of them, but abound
    +In the division of each several crime,
    +Acting it many ways. Nay, had I power, I should
    +Pour the sweet milk of concord into hell,
    +Uproar the universal peace, confound
    +All unity on earth.
    +
    + +MACDUFF +
    +O Scotland, Scotland!
    +
    + +MALCOLM +
    +If such a one be fit to govern, speak:
    +I am as I have spoken.
    +
    + +MACDUFF +
    +Fit to govern!
    +No, not to live. O nation miserable,
    +With an untitled tyrant bloody-scepter'd,
    +When shalt thou see thy wholesome days again,
    +Since that the truest issue of thy throne
    +By his own interdiction stands accursed,
    +And does blaspheme his breed? Thy royal father
    +Was a most sainted king: the queen that bore thee,
    +Oftener upon her knees than on her feet,
    +Died every day she lived. Fare thee well!
    +These evils thou repeat'st upon thyself
    +Have banish'd me from Scotland. O my breast,
    +Thy hope ends here!
    +
    + +MALCOLM +
    +Macduff, this noble passion,
    +Child of integrity, hath from my soul
    +Wiped the black scruples, reconciled my thoughts
    +To thy good truth and honour. Devilish Macbeth
    +By many of these trains hath sought to win me
    +Into his power, and modest wisdom plucks me
    +From over-credulous haste: but God above
    +Deal between thee and me! for even now
    +I put myself to thy direction, and
    +Unspeak mine own detraction, here abjure
    +The taints and blames I laid upon myself,
    +For strangers to my nature. I am yet
    +Unknown to woman, never was forsworn,
    +Scarcely have coveted what was mine own,
    +At no time broke my faith, would not betray
    +The devil to his fellow and delight
    +No less in truth than life: my first false speaking
    +Was this upon myself: what I am truly,
    +Is thine and my poor country's to command:
    +Whither indeed, before thy here-approach,
    +Old Siward, with ten thousand warlike men,
    +Already at a point, was setting forth.
    +Now we'll together; and the chance of goodness
    +Be like our warranted quarrel! Why are you silent?
    +
    + +MACDUFF +
    +Such welcome and unwelcome things at once
    +'Tis hard to reconcile.
    +

    Enter a Doctor

    +
    + +MALCOLM +
    +Well; more anon.--Comes the king forth, I pray you?
    +
    + +Doctor +
    +Ay, sir; there are a crew of wretched souls
    +That stay his cure: their malady convinces
    +The great assay of art; but at his touch--
    +Such sanctity hath heaven given his hand--
    +They presently amend.
    +
    + +MALCOLM +
    +I thank you, doctor.
    +

    Exit Doctor

    +
    + +MACDUFF +
    +What's the disease he means?
    +
    + +MALCOLM +
    +'Tis call'd the evil:
    +A most miraculous work in this good king;
    +Which often, since my here-remain in England,
    +I have seen him do. How he solicits heaven,
    +Himself best knows: but strangely-visited people,
    +All swoln and ulcerous, pitiful to the eye,
    +The mere despair of surgery, he cures,
    +Hanging a golden stamp about their necks,
    +Put on with holy prayers: and 'tis spoken,
    +To the succeeding royalty he leaves
    +The healing benediction. With this strange virtue,
    +He hath a heavenly gift of prophecy,
    +And sundry blessings hang about his throne,
    +That speak him full of grace.
    +

    Enter ROSS

    +
    + +MACDUFF +
    +See, who comes here?
    +
    + +MALCOLM +
    +My countryman; but yet I know him not.
    +
    + +MACDUFF +
    +My ever-gentle cousin, welcome hither.
    +
    + +MALCOLM +
    +I know him now. Good God, betimes remove
    +The means that makes us strangers!
    +
    + +ROSS +
    +Sir, amen.
    +
    + +MACDUFF +
    +Stands Scotland where it did?
    +
    + +ROSS +
    +Alas, poor country!
    +Almost afraid to know itself. It cannot
    +Be call'd our mother, but our grave; where nothing,
    +But who knows nothing, is once seen to smile;
    +Where sighs and groans and shrieks that rend the air
    +Are made, not mark'd; where violent sorrow seems
    +A modern ecstasy; the dead man's knell
    +Is there scarce ask'd for who; and good men's lives
    +Expire before the flowers in their caps,
    +Dying or ere they sicken.
    +
    + +MACDUFF +
    +O, relation
    +Too nice, and yet too true!
    +
    + +MALCOLM +
    +What's the newest grief?
    +
    + +ROSS +
    +That of an hour's age doth hiss the speaker:
    +Each minute teems a new one.
    +
    + +MACDUFF +
    +How does my wife?
    +
    + +ROSS +
    +Why, well.
    +
    + +MACDUFF +
    + And all my children?
    +
    + +ROSS +
    +Well too.
    +
    + +MACDUFF +
    +The tyrant has not batter'd at their peace?
    +
    + +ROSS +
    +No; they were well at peace when I did leave 'em.
    +
    + +MACDUFF +
    +But not a niggard of your speech: how goes't?
    +
    + +ROSS +
    +When I came hither to transport the tidings,
    +Which I have heavily borne, there ran a rumour
    +Of many worthy fellows that were out;
    +Which was to my belief witness'd the rather,
    +For that I saw the tyrant's power a-foot:
    +Now is the time of help; your eye in Scotland
    +Would create soldiers, make our women fight,
    +To doff their dire distresses.
    +
    + +MALCOLM +
    +Be't their comfort
    +We are coming thither: gracious England hath
    +Lent us good Siward and ten thousand men;
    +An older and a better soldier none
    +That Christendom gives out.
    +
    + +ROSS +
    +Would I could answer
    +This comfort with the like! But I have words
    +That would be howl'd out in the desert air,
    +Where hearing should not latch them.
    +
    + +MACDUFF +
    +What concern they?
    +The general cause? or is it a fee-grief
    +Due to some single breast?
    +
    + +ROSS +
    +No mind that's honest
    +But in it shares some woe; though the main part
    +Pertains to you alone.
    +
    + +MACDUFF +
    +If it be mine,
    +Keep it not from me, quickly let me have it.
    +
    + +ROSS +
    +Let not your ears despise my tongue for ever,
    +Which shall possess them with the heaviest sound
    +That ever yet they heard.
    +
    + +MACDUFF +
    +Hum! I guess at it.
    +
    + +ROSS +
    +Your castle is surprised; your wife and babes
    +Savagely slaughter'd: to relate the manner,
    +Were, on the quarry of these murder'd deer,
    +To add the death of you.
    +
    + +MALCOLM +
    +Merciful heaven!
    +What, man! ne'er pull your hat upon your brows;
    +Give sorrow words: the grief that does not speak
    +Whispers the o'er-fraught heart and bids it break.
    +
    + +MACDUFF +
    +My children too?
    +
    + +ROSS +
    + Wife, children, servants, all
    +That could be found.
    +
    + +MACDUFF +
    +And I must be from thence!
    +My wife kill'd too?
    +
    + +ROSS +
    +I have said.
    +
    + +MALCOLM +
    +Be comforted:
    +Let's make us medicines of our great revenge,
    +To cure this deadly grief.
    +
    + +MACDUFF +
    +He has no children. All my pretty ones?
    +Did you say all? O hell-kite! All?
    +What, all my pretty chickens and their dam
    +At one fell swoop?
    +
    + +MALCOLM +
    +Dispute it like a man.
    +
    + +MACDUFF +
    +I shall do so;
    +But I must also feel it as a man:
    +I cannot but remember such things were,
    +That were most precious to me. Did heaven look on,
    +And would not take their part? Sinful Macduff,
    +They were all struck for thee! naught that I am,
    +Not for their own demerits, but for mine,
    +Fell slaughter on their souls. Heaven rest them now!
    +
    + +MALCOLM +
    +Be this the whetstone of your sword: let grief
    +Convert to anger; blunt not the heart, enrage it.
    +
    + +MACDUFF +
    +O, I could play the woman with mine eyes
    +And braggart with my tongue! But, gentle heavens,
    +Cut short all intermission; front to front
    +Bring thou this fiend of Scotland and myself;
    +Within my sword's length set him; if he 'scape,
    +Heaven forgive him too!
    +
    + +MALCOLM +
    +This tune goes manly.
    +Come, go we to the king; our power is ready;
    +Our lack is nothing but our leave; Macbeth
    +Is ripe for shaking, and the powers above
    +Put on their instruments. Receive what cheer you may:
    +The night is long that never finds the day.
    +

    Exeunt

    +

    +

    ACT V

    +

    SCENE I. Dunsinane. Ante-room in the castle.

    +

    +Enter a Doctor of Physic and a Waiting-Gentlewoman +
    + +Doctor +
    +I have two nights watched with you, but can perceive
    +no truth in your report. When was it she last walked?
    +
    + +Gentlewoman +
    +Since his majesty went into the field, I have seen
    +her rise from her bed, throw her night-gown upon
    +her, unlock her closet, take forth paper, fold it,
    +write upon't, read it, afterwards seal it, and again
    +return to bed; yet all this while in a most fast sleep.
    +
    + +Doctor +
    +A great perturbation in nature, to receive at once
    +the benefit of sleep, and do the effects of
    +watching! In this slumbery agitation, besides her
    +walking and other actual performances, what, at any
    +time, have you heard her say?
    +
    + +Gentlewoman +
    +That, sir, which I will not report after her.
    +
    + +Doctor +
    +You may to me: and 'tis most meet you should.
    +
    + +Gentlewoman +
    +Neither to you nor any one; having no witness to
    +confirm my speech.
    +

    Enter LADY MACBETH, with a taper

    +Lo you, here she comes! This is her very guise;
    +and, upon my life, fast asleep. Observe her; stand close.
    +
    + +Doctor +
    +How came she by that light?
    +
    + +Gentlewoman +
    +Why, it stood by her: she has light by her
    +continually; 'tis her command.
    +
    + +Doctor +
    +You see, her eyes are open.
    +
    + +Gentlewoman +
    +Ay, but their sense is shut.
    +
    + +Doctor +
    +What is it she does now? Look, how she rubs her hands.
    +
    + +Gentlewoman +
    +It is an accustomed action with her, to seem thus
    +washing her hands: I have known her continue in
    +this a quarter of an hour.
    +
    + +LADY MACBETH +
    +Yet here's a spot.
    +
    + +Doctor +
    +Hark! she speaks: I will set down what comes from
    +her, to satisfy my remembrance the more strongly.
    +
    + +LADY MACBETH +
    +Out, damned spot! out, I say!--One: two: why,
    +then, 'tis time to do't.--Hell is murky!--Fie, my
    +lord, fie! a soldier, and afeard? What need we
    +fear who knows it, when none can call our power to
    +account?--Yet who would have thought the old man
    +to have had so much blood in him.
    +
    + +Doctor +
    +Do you mark that?
    +
    + +LADY MACBETH +
    +The thane of Fife had a wife: where is she now?--
    +What, will these hands ne'er be clean?--No more o'
    +that, my lord, no more o' that: you mar all with
    +this starting.
    +
    + +Doctor +
    +Go to, go to; you have known what you should not.
    +
    + +Gentlewoman +
    +She has spoke what she should not, I am sure of
    +that: heaven knows what she has known.
    +
    + +LADY MACBETH +
    +Here's the smell of the blood still: all the
    +perfumes of Arabia will not sweeten this little
    +hand. Oh, oh, oh!
    +
    + +Doctor +
    +What a sigh is there! The heart is sorely charged.
    +
    + +Gentlewoman +
    +I would not have such a heart in my bosom for the
    +dignity of the whole body.
    +
    + +Doctor +
    +Well, well, well,--
    +
    + +Gentlewoman +
    +Pray God it be, sir.
    +
    + +Doctor +
    +This disease is beyond my practise: yet I have known
    +those which have walked in their sleep who have died
    +holily in their beds.
    +
    + +LADY MACBETH +
    +Wash your hands, put on your nightgown; look not so
    +pale.--I tell you yet again, Banquo's buried; he
    +cannot come out on's grave.
    +
    + +Doctor +
    +Even so?
    +
    + +LADY MACBETH +
    +To bed, to bed! there's knocking at the gate:
    +come, come, come, come, give me your hand. What's
    +done cannot be undone.--To bed, to bed, to bed!
    +

    Exit

    +
    + +Doctor +
    +Will she go now to bed?
    +
    + +Gentlewoman +
    +Directly.
    +
    + +Doctor +
    +Foul whisperings are abroad: unnatural deeds
    +Do breed unnatural troubles: infected minds
    +To their deaf pillows will discharge their secrets:
    +More needs she the divine than the physician.
    +God, God forgive us all! Look after her;
    +Remove from her the means of all annoyance,
    +And still keep eyes upon her. So, good night:
    +My mind she has mated, and amazed my sight.
    +I think, but dare not speak.
    +
    + +Gentlewoman +
    +Good night, good doctor.
    +

    Exeunt

    +
    +

    SCENE II. The country near Dunsinane.

    +

    +Drum and colours. Enter MENTEITH, CAITHNESS, ANGUS, LENNOX, and Soldiers +
    + +MENTEITH +
    +The English power is near, led on by Malcolm,
    +His uncle Siward and the good Macduff:
    +Revenges burn in them; for their dear causes
    +Would to the bleeding and the grim alarm
    +Excite the mortified man.
    +
    + +ANGUS +
    +Near Birnam wood
    +Shall we well meet them; that way are they coming.
    +
    + +CAITHNESS +
    +Who knows if Donalbain be with his brother?
    +
    + +LENNOX +
    +For certain, sir, he is not: I have a file
    +Of all the gentry: there is Siward's son,
    +And many unrough youths that even now
    +Protest their first of manhood.
    +
    + +MENTEITH +
    +What does the tyrant?
    +
    + +CAITHNESS +
    +Great Dunsinane he strongly fortifies:
    +Some say he's mad; others that lesser hate him
    +Do call it valiant fury: but, for certain,
    +He cannot buckle his distemper'd cause
    +Within the belt of rule.
    +
    + +ANGUS +
    +Now does he feel
    +His secret murders sticking on his hands;
    +Now minutely revolts upbraid his faith-breach;
    +Those he commands move only in command,
    +Nothing in love: now does he feel his title
    +Hang loose about him, like a giant's robe
    +Upon a dwarfish thief.
    +
    + +MENTEITH +
    +Who then shall blame
    +His pester'd senses to recoil and start,
    +When all that is within him does condemn
    +Itself for being there?
    +
    + +CAITHNESS +
    +Well, march we on,
    +To give obedience where 'tis truly owed:
    +Meet we the medicine of the sickly weal,
    +And with him pour we in our country's purge
    +Each drop of us.
    +
    + +LENNOX +
    + Or so much as it needs,
    +To dew the sovereign flower and drown the weeds.
    +Make we our march towards Birnam.
    +

    Exeunt, marching

    +
    +

    SCENE III. Dunsinane. A room in the castle.

    +

    +Enter MACBETH, Doctor, and Attendants +
    + +MACBETH +
    +Bring me no more reports; let them fly all:
    +Till Birnam wood remove to Dunsinane,
    +I cannot taint with fear. What's the boy Malcolm?
    +Was he not born of woman? The spirits that know
    +All mortal consequences have pronounced me thus:
    +'Fear not, Macbeth; no man that's born of woman
    +Shall e'er have power upon thee.' Then fly,
    +false thanes,
    +And mingle with the English epicures:
    +The mind I sway by and the heart I bear
    +Shall never sag with doubt nor shake with fear.
    +

    Enter a Servant

    +The devil damn thee black, thou cream-faced loon!
    +Where got'st thou that goose look?
    +
    + +Servant +
    +There is ten thousand--
    +
    + +MACBETH +
    +Geese, villain!
    +
    + +Servant +
    +Soldiers, sir.
    +
    + +MACBETH +
    +Go prick thy face, and over-red thy fear,
    +Thou lily-liver'd boy. What soldiers, patch?
    +Death of thy soul! those linen cheeks of thine
    +Are counsellors to fear. What soldiers, whey-face?
    +
    + +Servant +
    +The English force, so please you.
    +
    + +MACBETH +
    +Take thy face hence.
    +

    Exit Servant

    +Seyton!--I am sick at heart,
    +When I behold--Seyton, I say!--This push
    +Will cheer me ever, or disseat me now.
    +I have lived long enough: my way of life
    +Is fall'n into the sear, the yellow leaf;
    +And that which should accompany old age,
    +As honour, love, obedience, troops of friends,
    +I must not look to have; but, in their stead,
    +Curses, not loud but deep, mouth-honour, breath,
    +Which the poor heart would fain deny, and dare not. Seyton!
    +

    Enter SEYTON

    +
    + +SEYTON +
    +What is your gracious pleasure?
    +
    + +MACBETH +
    +What news more?
    +
    + +SEYTON +
    +All is confirm'd, my lord, which was reported.
    +
    + +MACBETH +
    +I'll fight till from my bones my flesh be hack'd.
    +Give me my armour.
    +
    + +SEYTON +
    +'Tis not needed yet.
    +
    + +MACBETH +
    +I'll put it on.
    +Send out more horses; skirr the country round;
    +Hang those that talk of fear. Give me mine armour.
    +How does your patient, doctor?
    +
    + +Doctor +
    +Not so sick, my lord,
    +As she is troubled with thick coming fancies,
    +That keep her from her rest.
    +
    + +MACBETH +
    +Cure her of that.
    +Canst thou not minister to a mind diseased,
    +Pluck from the memory a rooted sorrow,
    +Raze out the written troubles of the brain
    +And with some sweet oblivious antidote
    +Cleanse the stuff'd bosom of that perilous stuff
    +Which weighs upon the heart?
    +
    + +Doctor +
    +Therein the patient
    +Must minister to himself.
    +
    + +MACBETH +
    +Throw physic to the dogs; I'll none of it.
    +Come, put mine armour on; give me my staff.
    +Seyton, send out. Doctor, the thanes fly from me.
    +Come, sir, dispatch. If thou couldst, doctor, cast
    +The water of my land, find her disease,
    +And purge it to a sound and pristine health,
    +I would applaud thee to the very echo,
    +That should applaud again.--Pull't off, I say.--
    +What rhubarb, cyme, or what purgative drug,
    +Would scour these English hence? Hear'st thou of them?
    +
    + +Doctor +
    +Ay, my good lord; your royal preparation
    +Makes us hear something.
    +
    + +MACBETH +
    +Bring it after me.
    +I will not be afraid of death and bane,
    +Till Birnam forest come to Dunsinane.
    +
    + +Doctor +
    +[Aside] Were I from Dunsinane away and clear,
    +Profit again should hardly draw me here.
    +

    Exeunt

    +
    +

    SCENE IV. Country near Birnam wood.

    +

    +Drum and colours. Enter MALCOLM, SIWARD and YOUNG SIWARD, MACDUFF, MENTEITH, CAITHNESS, ANGUS, LENNOX, ROSS, and Soldiers, marching +
    + +MALCOLM +
    +Cousins, I hope the days are near at hand
    +That chambers will be safe.
    +
    + +MENTEITH +
    +We doubt it nothing.
    +
    + +SIWARD +
    +What wood is this before us?
    +
    + +MENTEITH +
    +The wood of Birnam.
    +
    + +MALCOLM +
    +Let every soldier hew him down a bough
    +And bear't before him: thereby shall we shadow
    +The numbers of our host and make discovery
    +Err in report of us.
    +
    + +Soldiers +
    +It shall be done.
    +
    + +SIWARD +
    +We learn no other but the confident tyrant
    +Keeps still in Dunsinane, and will endure
    +Our setting down before 't.
    +
    + +MALCOLM +
    +'Tis his main hope:
    +For where there is advantage to be given,
    +Both more and less have given him the revolt,
    +And none serve with him but constrained things
    +Whose hearts are absent too.
    +
    + +MACDUFF +
    +Let our just censures
    +Attend the true event, and put we on
    +Industrious soldiership.
    +
    + +SIWARD +
    +The time approaches
    +That will with due decision make us know
    +What we shall say we have and what we owe.
    +Thoughts speculative their unsure hopes relate,
    +But certain issue strokes must arbitrate:
    +Towards which advance the war.
    +

    Exeunt, marching

    +
    +

    SCENE V. Dunsinane. Within the castle.

    +

    +Enter MACBETH, SEYTON, and Soldiers, with drum and colours +
    + +MACBETH +
    +Hang out our banners on the outward walls;
    +The cry is still 'They come:' our castle's strength
    +Will laugh a siege to scorn: here let them lie
    +Till famine and the ague eat them up:
    +Were they not forced with those that should be ours,
    +We might have met them dareful, beard to beard,
    +And beat them backward home.
    +

    A cry of women within

    +What is that noise?
    +
    + +SEYTON +
    +It is the cry of women, my good lord.
    +

    Exit

    +
    + +MACBETH +
    +I have almost forgot the taste of fears;
    +The time has been, my senses would have cool'd
    +To hear a night-shriek; and my fell of hair
    +Would at a dismal treatise rouse and stir
    +As life were in't: I have supp'd full with horrors;
    +Direness, familiar to my slaughterous thoughts
    +Cannot once start me.
    +

    Re-enter SEYTON

    +Wherefore was that cry?
    +
    + +SEYTON +
    +The queen, my lord, is dead.
    +
    + +MACBETH +
    +She should have died hereafter;
    +There would have been a time for such a word.
    +To-morrow, and to-morrow, and to-morrow,
    +Creeps in this petty pace from day to day
    +To the last syllable of recorded time,
    +And all our yesterdays have lighted fools
    +The way to dusty death. Out, out, brief candle!
    +Life's but a walking shadow, a poor player
    +That struts and frets his hour upon the stage
    +And then is heard no more: it is a tale
    +Told by an idiot, full of sound and fury,
    +Signifying nothing.
    +

    Enter a Messenger

    +Thou comest to use thy tongue; thy story quickly.
    +
    + +Messenger +
    +Gracious my lord,
    +I should report that which I say I saw,
    +But know not how to do it.
    +
    + +MACBETH +
    +Well, say, sir.
    +
    + +Messenger +
    +As I did stand my watch upon the hill,
    +I look'd toward Birnam, and anon, methought,
    +The wood began to move.
    +
    + +MACBETH +
    +Liar and slave!
    +
    + +Messenger +
    +Let me endure your wrath, if't be not so:
    +Within this three mile may you see it coming;
    +I say, a moving grove.
    +
    + +MACBETH +
    +If thou speak'st false,
    +Upon the next tree shalt thou hang alive,
    +Till famine cling thee: if thy speech be sooth,
    +I care not if thou dost for me as much.
    +I pull in resolution, and begin
    +To doubt the equivocation of the fiend
    +That lies like truth: 'Fear not, till Birnam wood
    +Do come to Dunsinane:' and now a wood
    +Comes toward Dunsinane. Arm, arm, and out!
    +If this which he avouches does appear,
    +There is nor flying hence nor tarrying here.
    +I gin to be aweary of the sun,
    +And wish the estate o' the world were now undone.
    +Ring the alarum-bell! Blow, wind! come, wrack!
    +At least we'll die with harness on our back.
    +

    Exeunt

    +
    +

    SCENE VI. Dunsinane. Before the castle.

    +

    +Drum and colours. Enter MALCOLM, SIWARD, MACDUFF, and their Army, with boughs +
    + +MALCOLM +
    +Now near enough: your leafy screens throw down.
    +And show like those you are. You, worthy uncle,
    +Shall, with my cousin, your right-noble son,
    +Lead our first battle: worthy Macduff and we
    +Shall take upon 's what else remains to do,
    +According to our order.
    +
    + +SIWARD +
    +Fare you well.
    +Do we but find the tyrant's power to-night,
    +Let us be beaten, if we cannot fight.
    +
    + +MACDUFF +
    +Make all our trumpets speak; give them all breath,
    +Those clamorous harbingers of blood and death.
    +

    Exeunt

    +
    +

    SCENE VII. Another part of the field.

    +

    +Alarums. Enter MACBETH +
    + +MACBETH +
    +They have tied me to a stake; I cannot fly,
    +But, bear-like, I must fight the course. What's he
    +That was not born of woman? Such a one
    +Am I to fear, or none.
    +

    Enter YOUNG SIWARD

    +
    + +YOUNG SIWARD +
    +What is thy name?
    +
    + +MACBETH +
    + Thou'lt be afraid to hear it.
    +
    + +YOUNG SIWARD +
    +No; though thou call'st thyself a hotter name
    +Than any is in hell.
    +
    + +MACBETH +
    +My name's Macbeth.
    +
    + +YOUNG SIWARD +
    +The devil himself could not pronounce a title
    +More hateful to mine ear.
    +
    + +MACBETH +
    +No, nor more fearful.
    +
    + +YOUNG SIWARD +
    +Thou liest, abhorred tyrant; with my sword
    +I'll prove the lie thou speak'st.
    +

    They fight and YOUNG SIWARD is slain

    +
    + +MACBETH +
    +Thou wast born of woman
    +But swords I smile at, weapons laugh to scorn,
    +Brandish'd by man that's of a woman born.
    +

    Exit

    +

    Alarums. Enter MACDUFF

    +
    + +MACDUFF +
    +That way the noise is. Tyrant, show thy face!
    +If thou be'st slain and with no stroke of mine,
    +My wife and children's ghosts will haunt me still.
    +I cannot strike at wretched kerns, whose arms
    +Are hired to bear their staves: either thou, Macbeth,
    +Or else my sword with an unbatter'd edge
    +I sheathe again undeeded. There thou shouldst be;
    +By this great clatter, one of greatest note
    +Seems bruited. Let me find him, fortune!
    +And more I beg not.
    +

    Exit. Alarums

    +

    Enter MALCOLM and SIWARD

    +
    + +SIWARD +
    +This way, my lord; the castle's gently render'd:
    +The tyrant's people on both sides do fight;
    +The noble thanes do bravely in the war;
    +The day almost itself professes yours,
    +And little is to do.
    +
    + +MALCOLM +
    +We have met with foes
    +That strike beside us.
    +
    + +SIWARD +
    +Enter, sir, the castle.
    +

    Exeunt. Alarums

    +
    +

    SCENE VIII. Another part of the field.

    +

    +Enter MACBETH +
    + +MACBETH +
    +Why should I play the Roman fool, and die
    +On mine own sword? whiles I see lives, the gashes
    +Do better upon them.
    +

    Enter MACDUFF

    +
    + +MACDUFF +
    +Turn, hell-hound, turn!
    +
    + +MACBETH +
    +Of all men else I have avoided thee:
    +But get thee back; my soul is too much charged
    +With blood of thine already.
    +
    + +MACDUFF +
    +I have no words:
    +My voice is in my sword: thou bloodier villain
    +Than terms can give thee out!
    +

    They fight

    +
    + +MACBETH +
    +Thou losest labour:
    +As easy mayst thou the intrenchant air
    +With thy keen sword impress as make me bleed:
    +Let fall thy blade on vulnerable crests;
    +I bear a charmed life, which must not yield,
    +To one of woman born.
    +
    + +MACDUFF +
    +Despair thy charm;
    +And let the angel whom thou still hast served
    +Tell thee, Macduff was from his mother's womb
    +Untimely ripp'd.
    +
    + +MACBETH +
    +Accursed be that tongue that tells me so,
    +For it hath cow'd my better part of man!
    +And be these juggling fiends no more believed,
    +That palter with us in a double sense;
    +That keep the word of promise to our ear,
    +And break it to our hope. I'll not fight with thee.
    +
    + +MACDUFF +
    +Then yield thee, coward,
    +And live to be the show and gaze o' the time:
    +We'll have thee, as our rarer monsters are,
    +Painted on a pole, and underwrit,
    +'Here may you see the tyrant.'
    +
    + +MACBETH +
    +I will not yield,
    +To kiss the ground before young Malcolm's feet,
    +And to be baited with the rabble's curse.
    +Though Birnam wood be come to Dunsinane,
    +And thou opposed, being of no woman born,
    +Yet I will try the last. Before my body
    +I throw my warlike shield. Lay on, Macduff,
    +And damn'd be him that first cries, 'Hold, enough!'
    +

    Exeunt, fighting. Alarums

    +

    Retreat. Flourish. Enter, with drum and colours, MALCOLM, SIWARD, ROSS, the other Thanes, and Soldiers

    +
    + +MALCOLM +
    +I would the friends we miss were safe arrived.
    +
    + +SIWARD +
    +Some must go off: and yet, by these I see,
    +So great a day as this is cheaply bought.
    +
    + +MALCOLM +
    +Macduff is missing, and your noble son.
    +
    + +ROSS +
    +Your son, my lord, has paid a soldier's debt:
    +He only lived but till he was a man;
    +The which no sooner had his prowess confirm'd
    +In the unshrinking station where he fought,
    +But like a man he died.
    +
    + +SIWARD +
    +Then he is dead?
    +
    + +ROSS +
    +Ay, and brought off the field: your cause of sorrow
    +Must not be measured by his worth, for then
    +It hath no end.
    +
    + +SIWARD +
    + Had he his hurts before?
    +
    + +ROSS +
    +Ay, on the front.
    +
    + +SIWARD +
    + Why then, God's soldier be he!
    +Had I as many sons as I have hairs,
    +I would not wish them to a fairer death:
    +And so, his knell is knoll'd.
    +
    + +MALCOLM +
    +He's worth more sorrow,
    +And that I'll spend for him.
    +
    + +SIWARD +
    +He's worth no more
    +They say he parted well, and paid his score:
    +And so, God be with him! Here comes newer comfort.
    +

    Re-enter MACDUFF, with MACBETH's head

    +
    + +MACDUFF +
    +Hail, king! for so thou art: behold, where stands
    +The usurper's cursed head: the time is free:
    +I see thee compass'd with thy kingdom's pearl,
    +That speak my salutation in their minds;
    +Whose voices I desire aloud with mine:
    +Hail, King of Scotland!
    +
    + +ALL +
    +Hail, King of Scotland!
    +

    Flourish

    +
    + +MALCOLM +
    +We shall not spend a large expense of time
    +Before we reckon with your several loves,
    +And make us even with you. My thanes and kinsmen,
    +Henceforth be earls, the first that ever Scotland
    +In such an honour named. What's more to do,
    +Which would be planted newly with the time,
    +As calling home our exiled friends abroad
    +That fled the snares of watchful tyranny;
    +Producing forth the cruel ministers
    +Of this dead butcher and his fiend-like queen,
    +Who, as 'tis thought, by self and violent hands
    +Took off her life; this, and what needful else
    +That calls upon us, by the grace of Grace,
    +We will perform in measure, time and place:
    +So, thanks to all at once and to each one,
    +Whom we invite to see us crown'd at Scone.
    +

    Flourish. Exeunt

    + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/map.png b/node_modules/selenium-webdriver/lib/test/data/map.png new file mode 100644 index 0000000000000000000000000000000000000000..763f5627995f6f178e8ea78e37f32c80b35f5e2b GIT binary patch literal 26209 zcmW(+WmH?;5)HvpG-%NhT#CCC2$bRu#ob!mrMMF)?(SOLiaW)vxI>Xr+}&QjH!Joh zcinT&T{C<3-V?5@D20hef(8HpFlD4AQ~>}48~ATu5D@+ulh{52|9ayft?di|uu}i` zM(`*Sbprq_@MI*!)IFAuJKQsAHC^d_Cptb~UmPw7gzd|W5X(ToM%_q=H@K0G6E}hZ zwnvS(O+U}8W|j}Tt7>Z<0g)VZ)KLH6U>aqpfSfc}fsF7>i(%CduTz1&+d-c-E|MY{ zVObxMf@E&4=T^J9%2VO<$4@u`m@74yLQ5L%QPs=_Jl1+zslu;mD@A4UEaV#sCS9yEo+M~1aNGOxR^)bWw_In|O@gXac`wkLkwJ>7M41bn z1E_~v>poGbi*I&Oi8kzte-!K$EqPw)xURnHE6P)KQ?q| z+smXi0#X482dM&k10g^Fs2d1^0T|H4tdYP)%6ZqDfiSe9M9l(Wt3tlicUVm^pFRqc zIxd9@3(Xhb?0pe^Eep!&{IdHJQGS&k!7&ksSR~K8rnamf+3Lg;QyM<}rpU(1vawM$ z<+*H3t71e+|Ed7S&(6*+BC5da7{VtL}~BuOZhP}EYyDYOQZ?vI*P(1-UASLbJel}om!Dw<;U zM@N`K<`#=%znnkm>KW){XJqJVYg;zz$i#zj0PRhO?m;GWq&tmhX-jnq3_Ojg*hFcy z?ItB78Lyj98{`xe8$WGz{rvohLMPjV94@fWiUc=)_N`vP)`X?zBV?AeAbs;_c=fb& zF+)gW{#0WOR1g3#kQ{`7r0)MtT-ma+K^5(DX~O_}FhrtK%=-1#*e&gbZTho&Ljizo zoiMA5)@zvfUQg22<{VSk9-ZT8;d!)iSF*r3GCZFlVYuSC%s|72@s~Omo{-#p5!M05 z=j5ND(c)>dGIbJi^5erpFA=IC8I-sVbeD0T{qc>)aGWnR3cqMf)STvPUClE2-<$BX zIu)tCC(A)f)w#2;ambT~^FD)vn)A-OzwoE*aos*N3n>)CC{=PmV z5v@V867U8f5eoqMBR~O;75qA^DQ&H-*(D&SX{g!l2Ypv1&pp-*qS~_l+Cq+u;6)u- z)jG+=D}2(AKG(I`p0pbip9&kX`q)9hN*)u3JD;~WI3{+ubD7R_$?4@5H*85?G)JN| z2tViccJFupgQ7CQ)bYiL7>mR#)j_!c@iZ#qas#N_V5N z49B`~ZO2Vl{;0p0Rfa)$GHZ!_Kh3Dq%rK zwWpU}EE7*7!$~~2SKLUWzsQrZ_N}J<(g-^UD?c`rMk+au$gAjYo{Gx0A#QscxP z2%t!%Il%$}!MJ(v&(#SkR{PV_SarL#gAIFA?J3_8J`tBS20nwthhTE@w?zpPA44Xq z=j#$ssJ^?tT#cW1Ji;;y%eYCWt>VA4(6W#Y9>rhslJlFoaOC{*?wp#Nn_F93o0(B# zO}V`H#{cwEMPBquM#eVt>ba`*=XFcFKHiJmWw zoCiVU;s<{DMJ!Hf?EdT?Z@DtUlTpsM)#3(hl`(+O$*%O zobr6vw6zG-wrpxyk8KviZxRl~&`f3%K87m&-o3m(IXMXk2Vy-Yt43`}@RXWEC3ah=}NTA1`l@S8vDL9!X>rxym3eWN~i-BQ?;V{;*-N(5P8R zW-M3e>qVcJh|g|M*OPsTEy;>>qRnC%yY}O?c;;sz3vkQU&DFu9s<9D$RPn5JCNDX? z!i-fjP0Q6)T0NacKEuJuJ0cPi5;C%*laq;EC;In0YO?0_OY(GTOi7-eo(~TXo}Ly> zku2WV^Q%E#t%!smB7p`nXvu3*zYg6;vtI&kSpLJZ9Tq?4b_>}&4CotpkM02!P9W*0 zJce$7Kj2~u5l8BRZGrCg#GT40a@Ja}I?k3jg4D9Stogb)<%s-PL9XaxYHDg|NZQcQ zuvSYiCK8A0A+=PQ0bW4h8n=v+a-9 zyj4<-I>pu1N{3N@8!&a1=nF4n$PgHSY+y2hWxfxJyQiJ&zBb`15QQR*?FY0ajjiSD zh9xF*5_`}6Y*`%mDhCD!rKF_ZC&}V}I`ka!VmP<$-F0fwS{0oVzD+xPj3Ou^19)s2 zeMzlgM^C7CS+=+g{Z2ZuoA%8#%zlxvJNBbU7%Hyzcl*r{1ZpW{swl0OzweJ*Pzs>& zPL%_V1a;%7%X5XltMEzeJ6!C`z*o1oN{Wink&%hAMQU#C?~A5`FVMHd3dg$(vwze_Uw6)p#86x;t0{Eh;jWxhCVGF zi)Q%Jn0zFvhLkH`)%4^@D!msUUQ$jN3G)B^`J<4*i;0N|Uy<6Y1&Y|z+8TMNG5)9f zqinxtSqnETgh&{HoBWs}E5A_3Q>Gg{?NdH?)&eX z=-p3Uaey2RD|+QB%MDd)4l<+t`?OzJqpz1=Uc@MVk%_e2F_Tc~puHSWk2XB~W9=$+ z?BP`_Q>UZCYCiS*9uae^8(6F!^YS7m4t!Q%}5fs6~W^~LAroe z8rPC%h%S0MnX6V|t!2gPnSh9ljEtO|B}sNNi-{54h2YBYb)u%<>*mzZEqZjfGyMO7 ziL_Mng)tLH462Q3yu*$yVbGjC-tZvva6`* zXg7Cv(UNufkh6r^HNoZ{v zb`d{v@^a9W_4~Gp+SV%!O@At>PDERRpFKQ}?x{1GjiZJ1?(CS+B@A2CFWK-$PKrfwnMosCLJbj${wd7=QcqGxAcc=k9U1u`)=0tAZw6S=L6?DVdyd zWFPO^sbzIzBWH4t@8@8s?IM>c>;o&;1;1zi+X&>aHcG>`6$Ts&7mR@*Sfd%Hkd(x3 zJ~2gic6K)Wk&d$a4sT8h!r~Me>d`2y5GKg{ZqOo)u zR8jp@it-~9>>27qXhM`}?=0cgQCiKt%)vX1SB!+>Jtf~B1l0KwJ@UM1RTf*QX! z8x*sxS$vm_r~Nz9{M;a>*1L5q_mtZz8ZIAVDTAo-n(`uyYw>=lG${on@ z#8A{DXfxiTHD;jyfy~xcE^|@J<|b+Gp~=)QOz{3c+3KI^S?R5jv&sAGLia0tLlaqF znF|TY5V-(o00!DpC}Vf9HRd80b<>8asB;KI5o;&A=L~7z<%FmO_?ylAIEypb!y9+6 zUkBherkEN+8(~(6-3rH~?&5hRV;&aR8@^nAk0^_xsN=kaC{gAgH(^;I&kibyN@eRe zJV*f&l);n?n5Biwxz_eh8_l&@;k^qToR=iIS^BTdD&xP!*wMHHdT$ zNZs8)NG<|2Km!2Bz(oFN0DMSb+16H4jRP{$Ct?p$tS)l2m7Js|_dSF*zwn!hnJR&% zX|qEKONlwgpG-*Fw8mc$%p94=@&TzmaUeu=_V8FO`gu@X4K)OZ(kZcl5wv4ledzmW z?e+Nnj~X&p-N+oXHC{XOVHkD0AD`c&PU}s^;@6MqOxBbvtAhdVmJEKkNt(!XP?7=2=lgNj5!zxMVbiU$2km^4o>wbX z*Vosd9AA(9LM-BT>ad_syU~e5YHQO}M4-miXuHR(3lNuodD4TqqKq2e+a`}5c4JUKlKvz48GvwWfVqgie}o~Ifp&?LDQTn6I`U8ps9z`*{MEeo#`}S{*d}qqE z`=7mzvV_LquOm)vwt2KbfGh%4DFBf+K(g8`v^1jZbKc9HVuf2$nXflYML(kLquz zpmYQsSJg3^HM)j)3d^gpfP>L4iH9ZQhwsQiu-M;$Kz9-Rjf;&fK0SknwT=1R3zdK& z1#Du9dIWSFqQ0F>Y_niuB*}*@JyuO-LOzqULE)bV@og9A-p`m*UyWA>BxgQv7uuP2 z|57k@)-6d6LroC>ZNUi+g_Tx@r&q3CTx=G^V2WO88P}3amN5m#j!V-8sUYbDhz}zh z!8*Ntp5-<$e79`%yKY9C*PDdbuu(-&#r zd40XO#!y`2n0L?3PSW0haM3T}7;|`6_@Sl$570)c7gP}s`%v|H$LxX1rSJ2}OirK< z;tB`vLBpydNwLAuq@K$_PuZ}fW(p&IhoW3;|5B3G>q!S5_J?U6Ae_1gu`cIZPkY_W`8y$UOAOtq)n1TC!toD5CVPX&9tSg}W4mA2*oEVH-i$Sv zIhOEG-Kvt;Cu~dZyg7|Il7;l+-3FQF$1UfZOfQSo8B!!Mx&%haxRiagK&V8f^ZfGj zURG1d+)>-}#P~*gM{{B@a&KlrMUXsF019*p?Esrq zC6r$*C9`TNqqq>dfJ(&x5&;qZQNBA$UtbO#PQqLqM`a9qqOgl|I%q|jr5%~+aPWj= zWdewg%TnrOU;~1dMZcZ&el$gtHej(2{bTQE2eM_B^00gH>17gFm(uI}AU*b1(bh=r z;c#%*^nSV8f@+Rf&hIk$HstHEh8f@OfVMsoqkxV0+a;W*IjL0*9dn*Q8{gRaZEd)X zTGE*t4#6L;(o>EFF6GDm<})yv)vu}Ge^LP>joCzMiySuuRr~ICAG>GzUPp!e`pJaH zAF78E2vvqsG9U|JqNeEDKNCO3ytdt?Yl_abQ2@FtHxytJ)@A@>2(A-QUi_$!zbIEv z{g;VjK}@-+%#p~oz4wZ3Jl&$r)^vov6>quSsioS6&z#(LcBc*RiYBw0>wiJ;{g*r) zUT9v1l(xmT~n0Gjdf&m~Hm|@6ziAT+Abh5fGsveMNGuGalG2>L)$Y`JXL zWZk%|>Uxzv@P6W}k2h6^keW-XBa|3K4X$1b0H6gbSFfUNc!zgv7W541DkjTu*6+Mr zt_-iW$;V6M%B|9@@UGoIXzN;pMqCnSRg^J%n*Vx!|4V8Q#eD)>5N}!f5E_CLii1SS zgan4r57fvMwpBkI>}Qdmw|>4HX)97a?e6a0+%&Scx6f1dNRLJ}2GedKf7yv;+Wzx0 z^d@B5%e@u*xl-LacA!}`B-(HCa>8L&WJ4&To5&@CF?_ z3=B^W+m18qe?ATFNl~nqdtWo4=lX1x0Fh8B&Y`^!Yd;P=}bB@N0+F$2LyzHBdkhgr8NJ!6eEh-2JI4E!)#DpohPJM>re;c5Oo@&( zd_`JB-Y$0e2G4iI?={ULDx5K({y1OPw2`TiC<`q;4zY{BJi9jEzf~jy+j}m0A3eCm zM<^7nB{uKtt#&#%?d=D7AyzuI=;g8htF<5ZA|bP}r^s02X!CeRREyG}96~Z{RQL=o zg8)LhnRonUPL_nQm^?2(MfIIe)bCy2+<1OUEOCNHJMd`y0b&;*#NwTL?S-89W~$T}y%v98 z?2bj}Qq-H)u17$_N-tr#Yo=kuTb=hjt&eLPZOzYDPG#Ku{QR7p(<>{F>O%62MTuyE zkd)CRSz0!BK{eLX(nLO=v+vq&l(kgJHiW>n9vle}0_fP#+nZGZ`f`qff$`OY9wk?P4~rle4KgoQmmJY3vAaWI?xO*vWFa2*(ts%JJ1fZ{+= zrWS&5kf4lUg7xe5{`9dMLxDK*>!pnC@)IrzBUMXo8atvHo35KNuK}hx@x0BAOE~Qy zo>$}cERk4jS*bxvq?JnIam2-kNukGxs?yC1DXG+urOd4!Vh66hC==(N35hN>x%G9> zJ7G9Q1DW$x+Uc$+edqApKHkMW?&pYLnDuBk>LnFfner|jP2SONJkC`~1XHN$GTPaq;Y|#yvNB$eq*K-Q68d3)!D~yDz+8`-NB}kEl%4A_eO(Mvd&T zNT)Xb)ji$C_AP!0>uNZ@vupOCFnpIIoz(XP7U=A=iFrH|1=Pg$S?MQhq@xepC@nnO z`xY#4EjCytEO2=|43;$B{BdJVS$Wnyt$f-#{g;dbb)docN+wW8H7}En;C0)%=Jy(- z>wBFN&G7q&uyb<%hMo}$4mLClo7{xXq+thN*To8YI!j}7W)-()@_nt` zPqs`i19$h^tN+5q&+oNX);ZL8ab~98a;7-jy~Fy24g+U#`EeP?4Jjo;G@yrqtH`a6|$all!dLIb%~xE#6w0&DaKIR-u{$hIOZEmEu2H# z-?v=9$!=LKl9@|OhNcI~1=yB+L=aS_(n02X);sK07|f%BbG2KC?>NzVv@LlBY!fUS znlO*Djw<1ex9xiS5?7cP!T@#hW|Eedrze~#_-ViKA}4Ajx3owXorzN?u8}G+Pa;4A z+WleQD0&f+HPN!Y#9OX7crZ$1{km4RN;ddqfaSKy4{>a(X=_@xE?#}bVMAy=c5)9+ zsy&N*7#ZB7(1UNmj%CT@^Nw!OF-`5XVjh9BO=M9p4P`j_uk@7Hot)%7iyjStSTG$rS zY@CO85O{caEw?XD*6l0(@wjRxlrsG~;84Yeh(HJeukTBYrrYs{cQ~So#)GFoEdWA> zKR1o#9QMz{s8z(@E5ej7{rwUxdLnTl@(K!bN{<^T7na}Ub-Rg;5XF5bfp_xdK$NGy zE9p@W9A$bNwSC^tB6w7>c$4m?D`i`M<#>M>K}<;vs|Yd;Yx~_r($^10D0NTs5udtht^4 zN(g=sglkqjJaY>R?iIdjU?d+OpO&VM1oVLZP+U_yQe8U%OCdX!wA2<;JbRYyB-5(?(V)7AL4BVc&27Vm&3;0C~QdZqA|5}+`&TGDqVUW&(FDWSr zXFf-FFTz);iqu>5-ceBSb-lii?h$0C$>dk8j6HSMx(-G(9!Sgauy0!vv5320^F#TG zmETyPJ)UzSuUxjuaOASkHAOc-o&KQStWcvk$p}w}Z zz$%-X^ZV5vDMG^pu`b2^Rr#1v>u+ms^L}?U4coelmv#%n@IF_TG&avC>M*JapFU-0 zzso@tI1i4SZ&fXe>^Q2M&oJzLqlF{IJP=?C##e_;Ek)q;tv%lQ+~rg@4xS+zoa%b91|wkU^JcW1^ee+t>bE*ImuI zG#ngg-aOM(X`?D71G%Ktq?pgO0@pz5_W4H#h2Of-LJEdGaQAMdt> zt_I4eolSmq^`z9y;PWONjyU`!MoQ(k)3(xCaHtZSh1lUV!AuH0Iy+CxHOZqNe=M8b zDEK&Osc2#$%fD22cp#>67svQvGyv&1P%>Dmcy&4WR@xoblfCoUxw&U&W}NFHHpIa2 zbcnz4D3>Wl=Kz$aNiMAKA*ixbz{?yde)yKSfCeKBI7$Huh%vfnEwA*~) zOd(Xf5$|O`Iy|(_y75&Wiq68p0p?9S2El%CbcO#98MBt3D+zLyZCd11UMw) zgR>lMaE*l)Sq2qU%DM6a7X8|+EG_<~nFg3)t5>69_>;vVhxZJ~^rfQ+ylv?d6usAP z5_znBdAO%sw{x5I4S@Zer)fTY{BLbLR^4*7XMU!I%cyI-4gz4Wo9HY31iu^E_Lb`OpRV!aJh#GvTUH&Gbg+=3 zG`(ZA?+(Iq_OHd@vb^mw$8L|rBIn&w01QYF*a3~qIX#`Qg_oypJI%XA zwajcG0GAP??_x+U{zAKVr|qqn8BZHpn7O1f-=6ixbMK6qR&|R|EzM5<{XRdnnG8&V z22YkZW893BKJYJGT6i=tnD3!fy&04`qv{1botf&D&qa$6xc)N|`D2<|)j|S&^1v?E zh;+r$>fWt4E>dMmik`%bqmk)y{JdS_+j)PJW50IpfL^p;Dl_Y3!Yp076K{JXEc(^& z@ylGfp#cdgIb3oeB^CN`ftmUVNek-0a!*~ZZG|MJPDGj`_{}i@#(n5LqX7QufHW^I z6rf>)QG`WSdt7c-zjRG%4adbT6n^xEUTkRW{w6qc#D4|bmHR+{(HAuQ?)S1AIBHET z-f46qg8^JM$ch1~8T=Wz#C8Ny-U*AIW84svJY_AC$3IVfU58(O$F?|Mi>RM9qNC6$ zWBavtKBH#43~_NdO_~yFNlV2~Y?9)?-mNpJ+;o`&9=!?@W4oQ*29q?jc(nU)|K*9r}TH)-{#V>}D# zuTNA*>3JH8S~zO>0Q=V!2Qv z<^Ud>G@{gByLE%h=m+mSyAAGn9(T+0mgD4fJ zp=98yhZZ^WEt~=`?mx6&&)xlbPYc+`u&3PAX-ba42qxC-{APOixtbXtO-Uq5#1AuVivdO)nIzi)MRDzccvL~<{Eb@+23wunf;?=(6*11(<5bk57)?G3$w2g-;e z=U!Ao?~sj*4vvOrYpE>~0aIlKN5}-$tL}CjIbDJFZBpssh4aKIg|o6P!>Z&znDv`0 zec@Snf5eP4Nj$H-yu74ju9ukEfL2bGO%a|vCMzxT7-I-&WNTRzD&^S2A zojYTk{wCujt$u71s;sP)s<~&3gHyYXmA2pS{0j5<>yoDzNqRh|bGl4aMZs(;xoI&| zWGO2l<#mzMd}_yX&mxWpW-~H5dm`W$o_yB!5Gg*fadO0 z{`gkhbnJZ6`ormJY#2rC&j1D_LQ0_NZ+L-;t4!cv8WnpWSxw)lrn8phbi>tZ!8y&Rju(+U}VW(yOWRKgJ=< zxp@iJT8~@SKQJKiX>H|8HagZZfVi|zsQomh-Vp&<_9X*uxbx|M3wMs{mcDu-oh-GW z&25%rFi)phf1#tgFt}%2iGnLHvn07ZU_c!I9_r4M{?vf*_;!JQ%(8WLW6m=!>l|g{ z&QLL{Li2Iq{05Kv`uwl@pDXLx3=y6h`q)bKSKR;Y!n9^@m_)1?BZTlOrkU%!sJrQv ziKi_yeEaUsA~rh(;xxGy%YV+-vsX)ogZM4q zh|S6lf)n_Q&CGI0S`n0UopvJ>(Mz35oy{Jkk|T2toD2I}#vL zQd)WY26krZ1qD?A%^a~R@Jy0FKDqs~De0}rCJZ%p_{;nBkOhFO_lfAKR(@2aq?uah zOQ0D}Ksu-#1OS5lae@KEGyQ;Xd6sWx%g$H}7_6>4Ih*|Ue!OoKTz@kymh{=`+GW3% zTR8srjDRsv`Je8bU;sK56Ox2+qq~9E=_XQ~J|oX;!RO7Gna^V;7F02iUcIrb15R2t z)^O9QD(Bgm?Fivz!SHP!#10G9Wv`SLliKA%vkQ5fDM~&b;04ZO2jm)hE^5KP|{Ea19Jh z7GP>@Sb8bWQF?H0RoWh1oH&y0Ecru&t1Je)200d)$RA*Q2+k}7Tz*lQ%xW<=ULhn$g7aCb%o70Qe_QL^AU>c?I;I1TO9gV!ln5bBIRwa+aDxkxar^K=6S z+3_kVgfe)&e6y4c@QPpCTf-%Ep!%V6DN{ZuOkVHb;JsM(>BT6iF&9MX5cP4Dc1F(cL zCBuGUkxv3l+zel$$oN$6@20np1G~?kAn8UX$5z?z;o=z9_2JV9$wp;vR={m}KhYS> zAA^5)&c>TY?nbGQvVp7iTsM*y5f1c1?C22kk*;*UmMKQva-O{}87C!H$B z8OHEwC$_uL{b~`oSloC6BNduQbdU3g)P6p?;Ol&Kkm3!Qb33%+>)&9hdO zvxmoSD?%-r+IP$82;s-JAiPj5(1NPKx4jLiFdJ2eW9ue=IR5~ zdwG6`F(ci8y;i<}CHl#Oh~cQcqFqNFNg32Sf5mfp-I>acF{ey%lzvNXT_9%gZz7jZLv}9+dqh$H-MO~l(J=lJ9LuF>mZS66RT!* zOY3+h_X(z0UnGz!Zuxltz{egV3S26>#N_YS$GQqcyd+U>@eD=ntF~YyxSUtN{=;XbO9{zp^xti(xbz@XtYDQ z$!ag3tf+V9(6UUI+{X8Z&Fe&A#C!fbZ#z&<0DX^zVI`Fq`jL@vmMc!^xeCf@X^{Fu z5lmp(T$)juiap|i5C;{u{x;3QSWU`cA&dc=0CLbj`c{uU`7qEM5U>^!sJbYlXj!B! zQ3igutecuvd2@4<^|P39!Bc3`-b+@B@{l zhVH>3e7S*7S=j0Bsj~ky5DoJNJ40NSkFS`0XEd$vq(rofW@*2eRkapjGW*L)D?bLI zPc^+*g#?P1BCZOhEY*J5vmFG@K1HBsXoM$yC-yN{mEY?h{# zNwBvl;Fui#)s50;yhva4_U62il-U>%?QMdWcpUJ!l+e2Lh-ke z^{7!DoB1BNx2Xt#w8@33n*OmDMLO9!cv&yMVz6=!| zMSfZRcK>Z$uS%;-Jv!|URS703!KqDyTLQIK29#$Sqah$9^^Ro=&>igW!zp)>eJ`eR z3IsrA6U*CwKdDvH5&UIb@#zI8->6s`ivg%!mRbI0&a5aEMv0o=482^T^YNZ|(74$p zjr~rMQwBgliK^xPKwuzqFY`n#&k?h3A8!#2PKqGqq3XiM_mr%)6)WEP)~?#}orE&n zugWCgI3H~b%vTkhp#mWvq}p{%>K^4TU6!wRmRK81VpKHZ5DZY#MS@LME)eRgNGMpy zKD|$`4kJ;fF0M%TQk3<%VlW8(J)w|@Wn6F1b_VKI4DK<1uTnm1e)hYg!h1k5 zoSp|4K^YAp)|F@&^LA(BxnoYX%!SIb4e|Q~j@IZAb6aAix!c6lznT@!ktEq)37ggS zxH}*a6TvUsuSht`tutm*c}9puVvU(C*S!3fV_$Y%Gy%#(<`e03H$~#->$U8odHpce zQhW$gRMQ7A3+v~YsH9Vxr5@VHy!Xkzj~|^kTI=U3)Y@c@Tdf!L%N379zw7Q`2+7F< znMt%6C1_>EawYD`<>ZrRQiq9hgX8ZS%67V5Jyx~WI~p2XU=(>JDYBm&0gBxMwb8`$ zp$o#)DZrkrM@0q1>;tCnfsKk>IfUo7n^+$ViMFAqc;zm*n4sXS0Q6kNMSpS%2}@-( zWw9#XE;d-jBQ-`F1z+${+8Zrz*`zl}{#;4)Zi1GThR!OKImWVYw1O8!M?Xs-6*a2< z1Bp7Bdp9sEC>h_L)JgP44;7oK(v3!|^pLWak<)t-<*+wjVFPmcH*QXXJ)#c!2a9Ec zyPP%21}9~eS}xdMM=q(2Z{{8pA8awj6Hj%I{bBV7&Knh3o6dq7x|Yp;FVoXX&*v{n z`ugS7ixzXUDKigF(^}D_?`2E{s@P~7KdI^RHWI8@HP6PncK7!NQbqUYu+aT!{xqRe zTNbsw|9hE~ZMChY#;Eezt0vcuwKP19D?AsFU!X_jNNKk@1ePl zjr<1%L<{E<-5g+P{>9t=)&ev+#cO|ODArI(I$oxmwm-_Zc z{>0aWZ*`hB5^}offlIBPFW`GVQira%<5>@lHp_ZKw^Jl1CO|6O;_%R4W*DbQ8#CTpWB+7)H z`g2m&Ow7JsxJkNLAp=Y4ilNA?#_(k64{8L|-9o8$h9(?M#d7Qe@4|Z1q@rTg?Z;kk zq{z z{Z)rBUiU;-i8BrnebxqXvYuD?NXig6qvhp!DXkaJ-y2RZa&CEgp$-lVD5Ax=4hjn# z0O62HToPPDJ) zG6J+}0rhuIfL!2j5J?=q6WTDjd)jw4gHu+628`wJSRnQUf4tf;!v1hD)L~gYcHDw9 zjoL_`aW~>^upFPif4Q2VfRZBaZ|Q1~bF7*t~jpbbGk z%3X4AO>y_$`hGB)-1YSH*Ty|WfLbRA@P$EKhe?m}xZYBY;;&OO^A15-f>d zq!N}(HHE+wySg=A0?C(D)L2?aMp}GBYY-wNJNxW-C6!zMykV0kfFtCOIl(!cB`k?_OAhM z!IpSo+pL5g^2Bx|3<^FXwCLV3)VEG8aLZS%&B-Ce@urfm4}|7$92@nf?DIC$SqZC|8d)MYf0@b0oiVWxFa+#|pwA zIosJKqlNGlDJmEI8M1WxVKFs_FDU4cWJ#qyG#_axXI-&7g2;#(4%P*{UbH(g&%;mO zxn)U#DQSmDU`dl5RJp(+Wz->^M2+1C^6P_qfu*r)DTB!JDl0lzO*4KbLJC002wjh% z*k{kfagN3C49>WC`EJJ<{L67!n+-{X$;;CFP1Ccu`szE-Cwq3qnT>BW&&$WhAxtH4z+)aP!3M?Cjm$UHAY`xq?{to$Z{!AEO$W`ABCjt!aovHjNd zJtr>a%L1;0ge$LW*Q2AYKvea)kRX2CoM*$VzjP7u__#N|sDTHO z*%9KiAS4jv;QPkc&PV-25?E^oSEs#VY8I3!9<7K93kj)Lvx_EWRG0u3Y%JY(y7Qca zX!IKr3GIwhPDCLGSWl6B`sn!jMYobdz%snA1SxJ}C|9nV&dAh((W5uv*ZIOVoS~ic ziGsn2aT}W>FV@}c>1?)D@Uckj$CyaidZoAp0T}d88KJy-!=lR1;r>YB&wQ;zA=}ue zA&g6&WvMgX0YeIT!3G16jghELt@#Sb&fh(qAg4@;4qG zZg=(Wx=aWK{GQsiC1V^n-Dgt9g9v~oc!%hMN*_JAoIE_8m%(*Pm9+$eLC6)2uNm@ z86!idWyT67?xXPdB$9IqAA4d-w&;re+do-*nJ6eeu?_POfe`p(iG_fMen(?hZO2V{ zgO1~KY@8+K(QS0~Fvj2w`_Ik-WrnMpn|E-W>uBcWbkQ)Q==E&wBlpifdSqkk|hQE`2N+YL16e1}vK$6ag@B!9%9fZxC2{#(Sb9&R65fjgnN zsFrI{c|5$$NhFxBuxYCOh>PTzqx)<5CH=@;;-7t${z4vl$1gR#&lAtVKd4z7)S2KG zn^q_7J?0>Af~k|Z0eUh*(Z}G*_V3k!k*$A)F4FADycId<9|Yr1S@ab!++SG2B&Bi! zQkXINsuns~vyKXoq`Pq*=?BXVqS$_$BBj}{*Vj1@3Q}5nA0AIhhlFRzeKN^Q6+m_j z{()<5@GVUf@msoOG&@GYK1HoDHm$^f=I4+|80eqkLYf9R_y_0f+{5&`t5r_I!&-JG z4p|XLp#rvv7q;Z_o1VPSrL z_*AN*&TnXTu*!kfbDTU~!ebhRIi}eXhqj5-k)YaAF1XRYL<2@SELx8XIyyw)#-|1_nx~jVO+H2j^ zzD{h^3H|lXq2)WOE5760fd8sjYP*VM#aibJgqrcZwx0nDBjC1e((+1%QKkdh^Jo^Y z=Yq~})NIx8d7t0;fy@*Uvqi-~Dyhwz?QcsYe+Qc>M~sDFx=ADSq>B@|diy)+K%M%= zFQb}Y9;Y@$Bz|WXR#a4|GXmxi7G`EN6h?(`)fmdEdb3k8eyFdAq?*!Pxl0Cr&-Ti- z@L*6GH&YX1Vfz(ogqAOoW&zhjjC8U+tY4{22nhj*XV{q&vAI62{@#%#q}_vI z7l-_l6e(q4Ei`N%A4M`PnFx8A^NY+KVFn{AYQ=qGircn79bQ;PyUW8iyM7E7JJPeH z{=j%Og}SmB&W#2_UflFU$7|7LSxbC61-)x}X?x6XEmT>j{t_>15D>e<3Wc$K9CS>`0Rm<_Ex!xA0v;MQ%LPb; zBBnkJ9b7-&zl6T)BB-K_@58{y`_etyZd37Mp@ui7rN74{Ow7WZK5b)!dg12o{&vFO zjNl&5{+EY{Y(PSY7cztD)v09~i0pNK9^c`3U=QwF9>{wdR^$+iL6At;aEAxy8jtTC*#a>(S!Xainc_h}42HsC; zdv>laE)OQi;$CE9_OGFEbkuAX%JuELa>P~=Dwz~2zPo3yc`+H=OP3wK`Zn{mx!(h8 zp}3$HpxFiZ*e~k=BNLE0#WwA|Pz3zG{6HuZh-uEq^PfU$CWP)+?I(WJMHShjGX`?y zacptKaTvx_*Q67VhJZm&3Oq}5ZUR_rXok3#k(Fap8u&qN*fEzC?J>$uj6uB^1rf^7 zBO;J%trEIul)^Rpuhvghcls^zoZtt4bKpC-ozIJQ8fYxCV#i<`FMhB^YwY0;_d`U6 zjgu6)6@K;F8@6TPU(o`29{e2p* zky<2^r0HTItZy3#K?6R?kc>AlevqzE#=UEHS63G>nZN@S7<*1jAJ`*(+XUfqsr z$P^qTWeVENZU1V=V&rWru_7(1TQC{~hJTdAL~*oT2-a*7a-WXgb8aQHAXGB@UZovV zi4;Ifr8!w#*56@6mHHveQ| z@Rdb@O7`%>F-Rp4F?l>Kgqcx#fJh`zhD40eg)W8S`vp)srD7CNdMS_;!y4k&%I*Yj zG(2>?B_HK}7gl{eRX)n$Pe+rO_e&mOPJNi-u1}?^?}ZHVz7Y-P@1pP`ln`~aXK^Ab znm-;UBzs@{d5*qWDq0}*nJyHR!}J4x^3CwXwIe5nipojQK?b+xVIMJXxYG8;h*L8j@JQSl{SSM}>$fve$8~Tn4kjhZNk^(*g6Y z0c5KbH(yQ3DOKD_C*btR(ziDQH+&zE7*603!mIwB6f>og9a0L0*&mB>S^x0T*4FlA=d*cP4y}yBhN|{r7&@`eobJQX1$V{XI&P-V zGlctLRjz4lX27#{Uic;O*!mT<&o;&6b7Oz~@U+qB-${n-1uXy@^Ut+?d3m{$h;Z$Y z64vx??1~~OZmoMUOXGgF1Nx9t8;4x%VR1n2ZKV4uf9D?4>6KUDVPJD`KDP=~W@y6V zE4NiO;#IY7{|(sR`(r6zGBTYTguaBeT=5qv`5?c1*x@cKO<$Cu5VIM1(V}aa;ZEad zIGkvIzDMQ+Veua*k)DB_D&Ly42G!cFug!tj`JYz-MVUa|LO1sVx7y~{bTo|ynqdPn zD7-Cs+K%H_+DMRYR=U?w^ZXdMJ{@61_;yvQh|`Ab>4vc9CXJW#<3>5-%iSM1;ivIM zO>Zg%1adDes+6%iXK5j=M(;0!y$;`pcV;RGHIg`LLFu8kMQ9gz$6zA#Q>yeH_3nkdu`q z@+7_P4V3s+tJqk%mOREJusz_mRDyv4&Qx%4E!J$i$FBdB-}1+p>|*nIGfNn1$Ab7c zY*N$jPJlAf{U-XJqh;dcf-ZDy+2)T}cIo0^oHX-#-?kQm>SvoTB;;z99F}Ta1 zXCxn+@LZWfaYaNgl3x;$a4$SW(C0s7JM27n*nd^mAav$pm}nolO=pOG9T^h5uWz>- zoBsIL@wo96wyb7l&cZdE@i${EY@$N7qmnlC1 z_n^lc=W~*5zhzo^Jie7@B2gq(#mb~~m`lG09H~x4Gt>H|;$61AUyhNsG>MDN*1}um zOT{lI+f}1tWVNO5X}#imn}X-a69Qw;q=2uUhOIa!7H}9P$r@34-&Ol>uWIXkCUVmx z6?U#2#ti~v5k0UqIB$0{eBwE-?i-e~89?tzpAeDBhYF`MVG?nND&8AI&v+v&H*c<} zum;E?dV1T5Mequp$Kg+&f9NDg^>j&(r3gY1!G7P*m{g9t($4M>P7>17CX5wmhn}hi zgx;3cGVD(S)btV?Dn%;A6e&zT^`c0M;P|%bUDChT<4R$HZPJPqbR!xvVEe>Z&7;(7 zz0sqJ7}!_ihU_TS%3oDqI*gO`hX$03*}_i}QPJA|c%EUceOdPq^kX~4I;^6F>b1XN zWuvkDGDB_l^^St!?Zm&%`$ccZoV(5m@`t##CR^xAc;C%^n}<10=H=xDNbF2>2-utX zBoT)9169jeyZ1d!dpY_zg3L1+bD&I)5##$3+M=?Cay$~)L`&4WSQRAX-C`I0YQ|pMX~tG-&9{jL4gj3U%yA-J z(7nSm=kHFz-1uje?6`?oU0D3AP=P)eokIu32${EAZEfL8|EmT1;_sk)ITyJv zp9J;K2MySOiBVQo25=MwSfUcUon1}89!_fK@NRIr?FwC-7Y)>nJ3|qhzdpSFI&9gj z-7#2yg0z>c+n%;$4JjI`8x>;bLc^M8oA`jp#N@@1va&OY@UHT*x-U$eDp?Ncq{^oX zwRs%YpP8TcEFxW#-`k(Bx3yR|Ckb7!uGYb7Vtj_84*-1`6OfUUi0gMHFIh$;GLnuhZ!iXzf0@+s0Q`YI8`;ceKRwP;NwN36TK?im`tXWw!= zO_v;LzimTrNJbl^kQ!yC1|SiYcudu;m*1CmK$t*&ShK9&`|Y*O{hmwsn#!{;e6b$+ zvpEVB1!PkSjGr9}D=tY4^x)nb{&JPx|I6<9OW25=wA&VP2T?e0WqBDFJR;tRi?=nv z&W{)AvGv!sKhb%bSKEv~0x(&?0Q7hc4hO6P-cmwPoF#X{`3=cVBBTx#eC zhT~T3T@eYdTW#QlE&p7d#Zlp8bCzb@uh`cx0N0P&e{VoxxO5m~7QiSbDo#QM4T3_L zG?H?u^}h0M-@D)N+E01c^j8@-J*jEQ;%uYC`~GZg%=y|rOP>-58i`l=H+6V|}7eyMqOcE_B1V653f<8lMXWF#MLU}a?m z?4*X(nw#4cwh_)e2O3_|*kit^3*CdB*YM$wEo2 z<9cK3Pa-?-7MRzr6~pA{xt#Lln02w)HKN38*0&7w2m)P%bT8;8toNzwJ$ru7x1yXMC7yE4Ipi=P5w>~3%j<-z^e!5V%h8P_Go5Dsvyw{4m{37M@|y}Hp1Zqy za8MA?T22r3J?#xo3TI_tU_d}8Nli<$WIAIS_bhQfqzB7UD=4HXZ#>bX-;EB4^$HkJp4tN3@}UO$N}ZCnpsFfMAunK;JSg`Q-1W z<=i;^yg` zeYvUTpiR8m(owJFZZ|FMTVSS!s$w&B;kqPS57d%3H@_ny(9qC?JfX}_`&K)=-@5z} z%(*xE7dGgf1?Z)S>hMP~kQ^HDqMm@xWQW8qkuaroNqv zk=TMZZENRw4vuf1AP|Tz41yEn=hOU}%Uh0yt_W%&-wsD1M=_}GjewTe2N}lInn>1eSW+LQQBj4@k_fs6B5osWY%1%(A!+MBxV$xQ)u5)T zx_@x+{{8!tTeoWKAdH zxoeDZIS#&J*3>pBnaPeWiq%3navU^ZcAlUlx|wD|ESc$uQ79kp69^XV&9i$ly7k>i zX57ur>DmJZF~8I3_&CY01!)XepaTi)PA?b%y34(o_QWwGdoM39V3V4f7FC%yv>k{x zA7JuUBHq?p3-{CwBOoJgZ>a}C@1_2}>Hd(iH_G%$0RMB;fib{{f}EcN!hyoE*!Jb^ z!Q*7UW*G^OjSg_Bh4!aY^rB!VNz>4Di<}?u#;!ymH5;xmSvTVd;wQyLv4rbUt&mpK@T>9HXx(_6SRuuTrUtg&&Cdg4ZO zcXG=}e4Cw{``2{_bP;T8C7bcOl~cF2cHmv6wNE*f6+~R|GjNdakAW;>?9(z z4shdb$Q0t(ZXImZmfo*;;+FnD#+;P`audnbh=P6cW8kb=U0hroFkO;4m;+U;@X>p; zNn^=*gLC2wvrt*kPRoYKk_lLAGiXmrYn~5cp?%w1?=;kiN*f-dKD1o>v^lF?Es7@K zlhKSLVe<4q1~v2!e12Qw=-G9SN|b~ydNBm?{r-d)hZcuci!PA2)8|)N$HwXR_8^=e z8VF%;C%$#_w6$fGo7sUG`-Ji}Z+fa{0MpAbXG&dDQ&USz>p!k2b;RlV3kN&P*O6)2 zPW(zr%1jUi>bHPCfjj3O9buH)6Ivi$A2YOj{V0<+z3^|S(Z{75F>Hr$Jn|iAmd#I3 zPp_`7c6WELitW5=Urm`@HK?Z)C}0zQZw3sYsm>4;{1xGRr?ZgBabXMN zlt3uEA+PGCTV>b}6XzROHPs;ii$>CpcQQZ=#jYhJ-QN)+ZToiW2t5ZiW?M`;f~F9d37tbwX~hBSL~nyzKn{Wf%Ol!q@zhQA~B z;kshjtah_{TW;2|?=~BhzTS^*`MPQq7xfie^&@WQRH5aA3gyF2%;LX*6!`+pHOh9K zcL{KC?8-|_!g%Qo8ntQ#KmQnS@xc45t-dn$=&>#y)WEsPb6Y{nUeQDbFh|Xo-=Fvz zo>XCUJVvO4KU(t}zBBFrd&|F~wuVb1SsK+SXB#Fb##Lv5lEi^BD&g%|S;DJjs)}rc zTG3WCkaGWVhw||%e9Q9>UaS&5;-?EvUquAWW00rTShoauZ}0dp%d5`Tz((_t#=7EvGRmXQzWZ>AP$aCm zFlrrAH@4#(XkR{M0-XBmHeX&wHt64FMsO61z-7%t9f|~FWn2{ee<%~{~ETGLJJ`(Rbq_%p9@k0-=(747@U^bDF6VNu1NgQoz{8v}@^ z8(6QuwPTpCRxFr2H(T(|JP$Vu%EwsLa!6+jIi0R3$ci&-$^sX8b*m+rdDUJaZ3PwB z{$1B2^L-z$vAK2e@xnfnSI<95jrN2pOg*}+AS{w7qP^X54)UyeMD*dwu$P>pucpf>>QGX4<2;Tn!}7yZT1tGnn?jS1rx~9Ub6w{AW!933>>;d_4;c z_n?pz%J_J^_MEX{gMQ9T3(CWRfyzV%DZ0`;hY(!5=|N-5aTwBOS$6r zeyNu2DJ1`L-8k?0t`Cm!2=!;^IC4~G0)c^5(5#O$?YK))emlPQTHUhZR}qMhFSi1;etUck4(=2c|y2N zsnV^+F=>CT=*C7WX0KDYu%EK_Zf-!ZK2_p=9@`&Y^ukj#vhlHEZ8ndiH2S%eE+Y!W ze(CJ|ePWR$V{o_kT_@L76yco~$IkAraw~c=9ozWuC?o%w#Y)o_4qi{?G9~2T;9weR zYI$Zqml;iG;9JYdwe8gT8(Yc^7L5-Y3^cM2(OKE@0wJiOFAy#fgB~u3Ms0}|AQk%i zI6{beSyL868fTaoj($}hjTm4Y% z6v`oZu*G7K-~pthq0T2z9o)+&jqTKrln2qmxs=K{J2|;-r964CqW#XCP{1wM`a}-R zTe`XfLrATwYqXJH`M=30b2qW(YY-#dCL&~*kK|6}9xK@NO;@qfDDRUh( ztnEuO!q2W7h8_Q#g*<%1DUEN#HB-=bG+7~qpJpv%eiWxDm*Q{y=C9EnMe9YX1g{B6 zr#o+dMk6QWjY4%F*HAl)w5qNX6H1*Th@I!dP;?gTPWQNo)t>G$#5(uq8GtM441|It3P0IFy?g!I-xOlp{BNlxc z)qwRlPT z5>>HpD;Zn-s^GW80s#5IVhZzkvI1@xq{$>9H3_}W@MKZbR-VXl(MOT4OvDtoctQ)? z!})%g&IC7H`E|PCWLI5l8&hJi?eQvCozd+n8da?HzbQ@qE|Zjy#x!1I!Z-5z{*e-_ zBy&P4qSA4HAMXDy{C52J-#r@R5{A)#VtuZ`=w1S)zo4&LgMjT+_P@`g@;~Bzo@)8^ zOVYuhta2yfF!owBT#XW0Y|f0BV*ZUs}y;b<+J9N z7J%~t7}|metN*PbEsnC=2b;ZTmWKIH*sPc_*wqk}nCs;P=t8m7itUNNQ(c5-S{mry zyCdA+-;Q^#O;@T+W27yx{-9BB+*dbhG5-k|E3iEI>=}Av9DoaaBdOUx# z-f(t4BE1Oh0Bh3W`b^81iven0G${pW-SgsTlfHsU1vE7g7E$bV*ZV{tm9V=;s zu&@BC*pGUPqx18POyu={i>jOulZlB*@aBTT`#R+A?8SHf@C7pu=NRNKVp?%VlsV0( zSSVtSC@$csynl5qQ=nj25R@b9q5|a}eKqb6h<%pY_CM_3N~QJfLJSF8oWhD;hOgDe z)8&C~F<=h@Xd3WE$N!F+Yr4Xu41h?dKhWXX7^vOika1sU2jo6JfDvzx-c|^MZ)HKyF;i`^(AMm+HA@XecBc z`aqn@X%o&u5jZINaKL(uiw&rJb+$&SMKLP1+z>DPX?++B) zdv?5`*{Ev(Zx%TI8d&Y4DFH7n3!pk+)03txIk z$cO2#6T!~nus%={zBqRE9eR?_GhJs6ncJ;eKml|PcrAeb7Vt31P9-EZBqXiYWg()- z=7~7DeY*NL?8;Qbc6j7w;+lUHZ`lzOTCRo0RhclcW%>XfqD;kXjBJrB4d(YnN;Yv= zxYa}^#IT|`pMeae`o9dNuqr?iWltJ~_xQI{+H|rg-IzJHjnUwW>x+(wiA8aE1ju)i|6|(qm^L&FrX6HX>rRg3GrT`;gs( + + Map test page + + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/markerTransparent.png b/node_modules/selenium-webdriver/lib/test/data/markerTransparent.png new file mode 100644 index 0000000000000000000000000000000000000000..ed4e5e7f4d63fe103983cf3bfa53733a0089ba51 GIT binary patch literal 260 zcmV+f0sH=mP)6Xw+2uq_(M`6dHE24R1_~SA2W)sEi((o#t%gC<}F#-mygTf~{1syRj83 z$v~+4?^7VUur4s{YzK(ScPqf9AN{Mq%K}&hLakp1D8YW + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/meta-redirect.html b/node_modules/selenium-webdriver/lib/test/data/meta-redirect.html new file mode 100644 index 0000000..9d9c2f0 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/meta-redirect.html @@ -0,0 +1,11 @@ + + + Some test page + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/missedJsReference.html b/node_modules/selenium-webdriver/lib/test/data/missedJsReference.html new file mode 100644 index 0000000..6167752 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/missedJsReference.html @@ -0,0 +1,11 @@ + + + + Example page + + +

    This page contains a nested iframe. Execute some JS to locate a reference to an element in this + frame and return it. You should need to switch to that frame in order to use that element.

    + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_1.html b/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_1.html new file mode 100644 index 0000000..4eff01a --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_1.html @@ -0,0 +1,21 @@ + + +First Modal + + + + +

    Modal dialog sample

    + + + +lnk2 +
    + +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_2.html b/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_2.html new file mode 100644 index 0000000..cec3f3f --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_2.html @@ -0,0 +1,21 @@ + + +Second Modal + + + + +

    Modal dialog sample

    + + + +lnk3 +
    + +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_3.html b/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_3.html new file mode 100644 index 0000000..6c5eb72 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_3.html @@ -0,0 +1,15 @@ + + +Third Modal + + + + +

    Modal dialog sample

    + + +
    + +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modalindex.html b/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modalindex.html new file mode 100644 index 0000000..0a1c4c9 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modalindex.html @@ -0,0 +1,21 @@ + + +Main window + + + + +

    Modal dialog sample

    + + + +lnk1 +
    + +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/mouseOver.html b/node_modules/selenium-webdriver/lib/test/data/mouseOver.html new file mode 100644 index 0000000..d4751bf --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/mouseOver.html @@ -0,0 +1,17 @@ + + +
    +
    +
    + +
    diff --git a/node_modules/selenium-webdriver/lib/test/data/mousePositionTracker.html b/node_modules/selenium-webdriver/lib/test/data/mousePositionTracker.html new file mode 100644 index 0000000..39a31cd --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/mousePositionTracker.html @@ -0,0 +1,33 @@ + + + + + + + + + Div tracking mouse position. +
    +
    + Move mouse here. +
    +

    +0, 0 +

    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/nestedElements.html b/node_modules/selenium-webdriver/lib/test/data/nestedElements.html new file mode 100644 index 0000000..cf00083 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/nestedElements.html @@ -0,0 +1,155 @@ + + +

    outside

    +

    outside

    +
    +

    inside

    +
    + + Here's a checkbox:
    + + + +
    + Here's a checkbox:
    + + +
    + +hello world + + + + + + +
    + Here's a checkbox:
    + +
    + +
    + Here's a checkbox:
    + + +
    + +hello world + + + + + + +
    + Here's a checkbox:
    + +
    + +
    + Here's a checkbox:
    + + +
    + +hello world + + + + + + +
    + Here's a checkbox:
    + +
    + +
    + Here's a checkbox:
    + + +
    + +hello world + + +Span with class of one +
    + Find me + Also me + But not me +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/overflow-body.html b/node_modules/selenium-webdriver/lib/test/data/overflow-body.html new file mode 100644 index 0000000..2d2264c --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/overflow-body.html @@ -0,0 +1,15 @@ + + + + The Visibility of Everyday Things + + + +

    This image is copyright Simon Stewart and donated to the Selenium project for use in its test suites. +

    +a nice beach + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_auto.html b/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_auto.html new file mode 100644 index 0000000..cf8a647 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_auto.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_hidden.html b/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_hidden.html new file mode 100644 index 0000000..96fd750 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_hidden.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_scroll.html b/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_scroll.html new file mode 100644 index 0000000..6f1d90b --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_scroll.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_auto.html b/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_auto.html new file mode 100644 index 0000000..24dd192 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_auto.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_hidden.html b/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_hidden.html new file mode 100644 index 0000000..cae5665 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_hidden.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_scroll.html b/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_scroll.html new file mode 100644 index 0000000..d4ffa39 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_scroll.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_auto.html b/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_auto.html new file mode 100644 index 0000000..d425a2a --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_auto.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_hidden.html b/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_hidden.html new file mode 100644 index 0000000..4a6ff59 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_hidden.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_scroll.html b/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_scroll.html new file mode 100644 index 0000000..efa8074 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_scroll.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/pageWithOnBeforeUnloadMessage.html b/node_modules/selenium-webdriver/lib/test/data/pageWithOnBeforeUnloadMessage.html new file mode 100644 index 0000000..cb59707 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/pageWithOnBeforeUnloadMessage.html @@ -0,0 +1,20 @@ + + + + + + Page with OnBeforeUnload handler + + +

    Page with onbeforeunload event handler. Click here to navigate to another page.

    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/pageWithOnLoad.html b/node_modules/selenium-webdriver/lib/test/data/pageWithOnLoad.html new file mode 100644 index 0000000..2c644ff --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/pageWithOnLoad.html @@ -0,0 +1,6 @@ + + + +

    Page with onload event handler

    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/pageWithOnUnload.html b/node_modules/selenium-webdriver/lib/test/data/pageWithOnUnload.html new file mode 100644 index 0000000..6070341 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/pageWithOnUnload.html @@ -0,0 +1,6 @@ + + + +

    Page with onunload event handler

    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/page_with_link_to_slow_loading_page.html b/node_modules/selenium-webdriver/lib/test/data/page_with_link_to_slow_loading_page.html new file mode 100644 index 0000000..ea94f8e --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/page_with_link_to_slow_loading_page.html @@ -0,0 +1,6 @@ + + + +load a slow page + + diff --git a/node_modules/selenium-webdriver/lib/test/data/plain.txt b/node_modules/selenium-webdriver/lib/test/data/plain.txt new file mode 100644 index 0000000..8318c86 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/plain.txt @@ -0,0 +1 @@ +Test \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/proxy/page1.html b/node_modules/selenium-webdriver/lib/test/data/proxy/page1.html new file mode 100644 index 0000000..1810f1c --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/proxy/page1.html @@ -0,0 +1,20 @@ + + + +Page 1 +

    The next query param must be the URL for the next page to +link to. + diff --git a/node_modules/selenium-webdriver/lib/test/data/proxy/page2.html b/node_modules/selenium-webdriver/lib/test/data/proxy/page2.html new file mode 100644 index 0000000..d826f17 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/proxy/page2.html @@ -0,0 +1,24 @@ + + + +Page 2 +This page is a middle man for referrer tests. +This page will include a link to a "next" page if the next query +parameter, or the document.referrer is set. +

    + diff --git a/node_modules/selenium-webdriver/lib/test/data/proxy/page3.html b/node_modules/selenium-webdriver/lib/test/data/proxy/page3.html new file mode 100644 index 0000000..27048f7 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/proxy/page3.html @@ -0,0 +1,5 @@ + + + +Page 3 +

    diff --git a/node_modules/selenium-webdriver/lib/test/data/readOnlyPage.html b/node_modules/selenium-webdriver/lib/test/data/readOnlyPage.html new file mode 100644 index 0000000..b3f0012 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/readOnlyPage.html @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + +

    This is a contentEditable area
    + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/rectangles.html b/node_modules/selenium-webdriver/lib/test/data/rectangles.html new file mode 100644 index 0000000..8ba2339 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/rectangles.html @@ -0,0 +1,40 @@ + + + + Rectangles + + + +
    r1
    +
    r2
    +
    r3
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/resultPage.html b/node_modules/selenium-webdriver/lib/test/data/resultPage.html new file mode 100644 index 0000000..94f3e24 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/resultPage.html @@ -0,0 +1,25 @@ + + + We Arrive Here + + + +

    Success!

    + +
    +

    List of stuff

    +
      +
    1. Item 1
    2. +
    3. Item 2
    4. +
    +
    +
    +

    Almost empty

    +
    + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/rich_text.html b/node_modules/selenium-webdriver/lib/test/data/rich_text.html new file mode 100644 index 0000000..a42e43a --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/rich_text.html @@ -0,0 +1,161 @@ + + + + + + +
    +
    +
    + + + + + +
    +
    IFRAME
    + +
    +
    frame.contentWindow.document.designMode: on
    frame.contentWindow.document.body.contentEditable: false
    +
    +
    DIV
    +
    +
    +
    +
    div.ownerDocument.designMode: off
    div.ownerDocument.body.contentEditable: false
    div.contentEditable: true
    +
    +
    + +
    +
    + + + + + + + + + + + + + + + + + + +
    type:[]
    tagName:[]
    id:[]
    keyIdentifier:[]
    keyLocation:[]
    keyCode:[]
    charCode:[]
    which:[]
    isTrusted:[]
    ---------------------
    Modifiers
    alt:[]
    ctrl:[]
    shift:[]
    meta:[]
    +
    + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/safari/frames_benchmark.html b/node_modules/selenium-webdriver/lib/test/data/safari/frames_benchmark.html new file mode 100644 index 0000000..8a05925 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/safari/frames_benchmark.html @@ -0,0 +1,31 @@ + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/screen/screen.css b/node_modules/selenium-webdriver/lib/test/data/screen/screen.css new file mode 100644 index 0000000..8152618 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/screen/screen.css @@ -0,0 +1,19 @@ +* { + margin: 0; +} +html, body, #output { + width: 100%; + height: 100%; +} +table { + border: 0px; + border-collapse: collapse; + border-spacing: 0px; + display: table; +} +table td { + padding: 0px; +} +.cell { + color: black; +} diff --git a/node_modules/selenium-webdriver/lib/test/data/screen/screen.html b/node_modules/selenium-webdriver/lib/test/data/screen/screen.html new file mode 100644 index 0000000..166665d --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/screen/screen.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/screen/screen.js b/node_modules/selenium-webdriver/lib/test/data/screen/screen.js new file mode 100644 index 0000000..1d16859 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/screen/screen.js @@ -0,0 +1,7 @@ +function toColor(num) { + num >>>= 0; + var b = num & 0xFF, + g = (num & 0xFF00) >>> 8, + r = (num & 0xFF0000) >>> 16; + return "rgb(" + [r, g, b].join(",") + ")"; +} \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame1.html b/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame1.html new file mode 100644 index 0000000..d50c21d --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame1.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame2.html b/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame2.html new file mode 100644 index 0000000..b66cd70 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame2.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/screen/screen_frames.html b/node_modules/selenium-webdriver/lib/test/data/screen/screen_frames.html new file mode 100644 index 0000000..46852dc --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/screen/screen_frames.html @@ -0,0 +1,11 @@ + + + screen test + + + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/screen/screen_iframes.html b/node_modules/selenium-webdriver/lib/test/data/screen/screen_iframes.html new file mode 100644 index 0000000..ae3ea1e --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/screen/screen_iframes.html @@ -0,0 +1,12 @@ + + +Screen test + + +
    + + + +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/screen/screen_too_long.html b/node_modules/selenium-webdriver/lib/test/data/screen/screen_too_long.html new file mode 100644 index 0000000..4d00f02 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/screen/screen_too_long.html @@ -0,0 +1,68 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_long.html b/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_long.html new file mode 100644 index 0000000..1a6a100 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_too_long.html b/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_too_long.html new file mode 100644 index 0000000..3fee005 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_too_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_long.html b/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_long.html new file mode 100644 index 0000000..31733e0 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_too_long.html b/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_too_long.html new file mode 100644 index 0000000..dbef936 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_too_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/scroll.html b/node_modules/selenium-webdriver/lib/test/data/scroll.html new file mode 100644 index 0000000..cd5214f --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scroll.html @@ -0,0 +1,27 @@ + + + + + +
    +
      +
    • line1
    • +
    • line2
    • +
    • line3
    • +
    • line4
    • +
    • line5
    • +
    • line6
    • +
    • line7
    • +
    • line8
    • +
    • line9
    • +
    +
    +Clicked: +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scroll2.html b/node_modules/selenium-webdriver/lib/test/data/scroll2.html new file mode 100644 index 0000000..0ea66d3 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scroll2.html @@ -0,0 +1,21 @@ + + + + +
      +
    • +
    • +
    • Text
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scroll3.html b/node_modules/selenium-webdriver/lib/test/data/scroll3.html new file mode 100644 index 0000000..1aa1709 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scroll3.html @@ -0,0 +1,8 @@ + + +



























































































































































    + +



    + +                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 +
























































































































































    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/scroll4.html b/node_modules/selenium-webdriver/lib/test/data/scroll4.html new file mode 100644 index 0000000..652a778 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scroll4.html @@ -0,0 +1,7 @@ + + +


































































































    + +


































































































    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scroll5.html b/node_modules/selenium-webdriver/lib/test/data/scroll5.html new file mode 100644 index 0000000..b345a8c --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scroll5.html @@ -0,0 +1,18 @@ + + + + + +
    +
    +
    +
    +
    +Clicked: +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_200.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_200.html new file mode 100644 index 0000000..3eb3bf4 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_200.html @@ -0,0 +1,26 @@ + + + + Child frame + + +

    This is a scrolling frame test

    +
    + + + + + + + + + + + + + +
    First row
    Second row
    Third row
    Fourth row
    +
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_2000.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_2000.html new file mode 100644 index 0000000..61ffe85 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_2000.html @@ -0,0 +1,26 @@ + + + + Child frame + + +

    This is a tall frame test

    +
    + + + + + + + + + + + + + +
    First row
    Second row
    Third row
    Fourth row
    +
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame.html new file mode 100644 index 0000000..1530138 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html new file mode 100644 index 0000000..5781aeb --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
    Placeholder
    +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_small_height.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_small_height.html new file mode 100644 index 0000000..047de0f --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_small_height.html @@ -0,0 +1,10 @@ + + + + Child frame + + +

    This is a non-scrolling frame test

    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_double_overflow_auto.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_double_overflow_auto.html new file mode 100644 index 0000000..01b7c30 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_double_overflow_auto.html @@ -0,0 +1,19 @@ + + + + Page with overflow: auto + + + +
    Placeholder
    +
    + Click me! +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_frame_out_of_view.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_frame_out_of_view.html new file mode 100644 index 0000000..c536e41 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_frame_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
    Placeholder
    +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames.html new file mode 100644 index 0000000..e5b7602 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html new file mode 100644 index 0000000..f79f7c8 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
    Placeholder
    +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_non_scrolling_frame.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_non_scrolling_frame.html new file mode 100644 index 0000000..0a493fa --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_non_scrolling_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame.html new file mode 100644 index 0000000..cb5d53a --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame_out_of_view.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame_out_of_view.html new file mode 100644 index 0000000..5df1115 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
    Placeholder
    +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_tall_frame.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_tall_frame.html new file mode 100644 index 0000000..b7cfaf5 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_tall_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_y_overflow_auto.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_y_overflow_auto.html new file mode 100644 index 0000000..b5716e7 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_y_overflow_auto.html @@ -0,0 +1,14 @@ + + + + Page with overflow: auto + + +
    +
    Placeholder
    +
    + Click me! +
    +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/target_page.html b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/target_page.html new file mode 100644 index 0000000..0457a82 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/target_page.html @@ -0,0 +1,9 @@ + + + +Clicked Successfully! + + +

    Clicked Successfully!

    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/selectPage.html b/node_modules/selenium-webdriver/lib/test/data/selectPage.html new file mode 100644 index 0000000..1c785ce --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/selectPage.html @@ -0,0 +1,42 @@ + + + + +Multiple Selection test page + + + + + + + + + + + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/selectableItems.html b/node_modules/selenium-webdriver/lib/test/data/selectableItems.html new file mode 100644 index 0000000..190b2ad --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/selectableItems.html @@ -0,0 +1,65 @@ + + + + + jQuery UI Selectable - Default functionality + + + + + + + + +
    + +
      +
    1. Item 1
    2. +
    3. Item 2
    4. +
    5. Item 3
    6. +
    7. Item 4
    8. +
    9. Item 5
    10. +
    11. Item 6
    12. +
    13. Item 7
    14. +
    + +
    + +
    + +

    Enable a DOM element (or group of elements) to be selectable. Draw a box with your cursor to select items. Hold down the Ctrl key to make multiple non-adjacent selections.

    + + + +
    +

    no info

    +
    + + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/sessionCookie.html b/node_modules/selenium-webdriver/lib/test/data/sessionCookie.html new file mode 100644 index 0000000..0ada24e --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/sessionCookie.html @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/sessionCookieDest.html b/node_modules/selenium-webdriver/lib/test/data/sessionCookieDest.html new file mode 100644 index 0000000..f5e2ef2 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/sessionCookieDest.html @@ -0,0 +1,34 @@ + + + + + Session cookie destination + + + +This is the cookie destination page. + + diff --git a/node_modules/selenium-webdriver/lib/test/data/simple.xml b/node_modules/selenium-webdriver/lib/test/data/simple.xml new file mode 100644 index 0000000..01f4c87 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/simple.xml @@ -0,0 +1,5 @@ + + + baz + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/simpleTest.html b/node_modules/selenium-webdriver/lib/test/data/simpleTest.html new file mode 100644 index 0000000..49bbc26 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/simpleTest.html @@ -0,0 +1,97 @@ + + + Hello WebDriver + + +

    Heading

    + +

    A single line of text

    + +
    +

    A div containing

    + More than one line of text
    + +
    and block level elements
    +
    + +An inline element + +

    This line has lots + + of spaces. +

    + +

    This line has a non-breaking space

    + +

    This line has a   non-breaking space and spaces

    + +

    These lines  
      have leading and trailing NBSPs  

    + +

    This line has text within elements that are meant to be displayed + inline

    + +
    +

    before pre

    +
       This section has a preformatted
    +    text block    
    +  split in four lines
    +         
    +

    after pre

    +
    + +

    Some text

    Some more text

    + +
    Cheese

    Some text

    Some more text

    and also

    Brie
    + +
    Hello, world
    + +
    + +
    + +
    +

    + + +

    +
    + + + + + +
    Top level
    +
    +
    Nested
    +
    + + + + + +
    beforeSpace afterSpace
    + + + + + +a link to an icon + +{a="b", c=1, d=true} +{a="\\b\\\"'\'"} + +  â€â€‚        ​‌â€â€¯âŸâ ã€€test  â€â€‚        ​‌â€â€¯âŸâ ã€€ + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/slowLoadingAlert.html b/node_modules/selenium-webdriver/lib/test/data/slowLoadingAlert.html new file mode 100644 index 0000000..a6216e3 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/slowLoadingAlert.html @@ -0,0 +1,10 @@ + + + +slowLoadingAlert + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/slowLoadingResourcePage.html b/node_modules/selenium-webdriver/lib/test/data/slowLoadingResourcePage.html new file mode 100644 index 0000000..e05f954 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/slowLoadingResourcePage.html @@ -0,0 +1,12 @@ + + + This page loads something slowly + + +

    Simulate the situation where a web-bug or analytics script takes waaay + too long to respond. Normally these things are loaded in an iframe, which is + what we're doing here.

    + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/slow_loading_iframes.html b/node_modules/selenium-webdriver/lib/test/data/slow_loading_iframes.html new file mode 100644 index 0000000..d007248 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/slow_loading_iframes.html @@ -0,0 +1,14 @@ + + + + Page with slow loading iFrames + + + + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/styledPage.html b/node_modules/selenium-webdriver/lib/test/data/styledPage.html new file mode 100644 index 0000000..30810f0 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/styledPage.html @@ -0,0 +1,28 @@ + + + + Styled Page + + + + +
    + +
    + + +
    + +
    + +
    Content
    + + + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/svgPiechart.xhtml b/node_modules/selenium-webdriver/lib/test/data/svgPiechart.xhtml new file mode 100644 index 0000000..bf060fd --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/svgPiechart.xhtml @@ -0,0 +1,81 @@ + + + + + Pie Chart Test + + + +
    + Some text for the chart. +
    +
    Nothing.
    +
    + + + + + Test Chart + + + Apple + + Orange + + Banana + + Orange + + + + + + + + Example RotateScale - Rotate and scale transforms + + + + + + + + + + + + + + ABC (rotate) + + + + + + + + + + + + ABC (scale) + + + + +
    WOrange
    +
    +
    WOrange
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/svgTest.svg b/node_modules/selenium-webdriver/lib/test/data/svgTest.svg new file mode 100644 index 0000000..c6cc283 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/svgTest.svg @@ -0,0 +1,4 @@ + + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/tables.html b/node_modules/selenium-webdriver/lib/test/data/tables.html new file mode 100644 index 0000000..a2bc957 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/tables.html @@ -0,0 +1,36 @@ + + + + Here be tables + + + + + + + + + +
    HelloWorld(Cheese!)
    + + + + + +
    some text +
    some more text
    +
    + + + + + + + + + +
    Heading
    Data 1Data 2
    + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/tinymce.html b/node_modules/selenium-webdriver/lib/test/data/tinymce.html new file mode 100644 index 0000000..067b66c --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/tinymce.html @@ -0,0 +1,10 @@ + + + + TinyMCE + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/transformable.xml b/node_modules/selenium-webdriver/lib/test/data/transformable.xml new file mode 100644 index 0000000..0b7e7fd --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/transformable.xml @@ -0,0 +1,11 @@ + + + ]> + + +

    Click the button.

    + + Go to another page + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/transformable.xsl b/node_modules/selenium-webdriver/lib/test/data/transformable.xsl new file mode 100644 index 0000000..53db9fd --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/transformable.xsl @@ -0,0 +1,37 @@ + + + + + + + +
    + + + + + +
    + + + + + + + + + + + + + + + +
    \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/underscore.html b/node_modules/selenium-webdriver/lib/test/data/underscore.html new file mode 100644 index 0000000..904a444 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/underscore.html @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/unicode_ltr.html b/node_modules/selenium-webdriver/lib/test/data/unicode_ltr.html new file mode 100644 index 0000000..245acc7 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/unicode_ltr.html @@ -0,0 +1,8 @@ + + + + + +
    ‎Some notes‎
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/upload.html b/node_modules/selenium-webdriver/lib/test/data/upload.html new file mode 100644 index 0000000..aca398a --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/upload.html @@ -0,0 +1,45 @@ + + + + Upload Form + + + +
    +
    + Enter a file to upload: +
    +
    +
    + + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/userDefinedProperty.html b/node_modules/selenium-webdriver/lib/test/data/userDefinedProperty.html new file mode 100644 index 0000000..2453e69 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/userDefinedProperty.html @@ -0,0 +1,8 @@ + + +
    + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/veryLargeCanvas.html b/node_modules/selenium-webdriver/lib/test/data/veryLargeCanvas.html new file mode 100644 index 0000000..54a2aba --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/veryLargeCanvas.html @@ -0,0 +1,81 @@ + + + + Rectangles + + + + +
    +
    First Target
    +
    Second Target
    +
    Third Target
    +
    Fourth Target
    +
    Not a Target
    +
    Not a Target
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/visibility-css.html b/node_modules/selenium-webdriver/lib/test/data/visibility-css.html new file mode 100644 index 0000000..80cc649 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/visibility-css.html @@ -0,0 +1,21 @@ + + + + +Visibility test via CSS + +
    +

    Hello world. I like cheese.

    +
    + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/win32frameset.html b/node_modules/selenium-webdriver/lib/test/data/win32frameset.html new file mode 100644 index 0000000..108b80f --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/win32frameset.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/page_with_frame.html b/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/page_with_frame.html new file mode 100644 index 0000000..b94733b --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/page_with_frame.html @@ -0,0 +1,12 @@ + + + + Test page for WindowSwitchingTest.testShouldFocusOnTheTopMostFrameAfterSwitchingToAWindow + + +

    Open new window

    +
    + +
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/simple_page.html b/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/simple_page.html new file mode 100644 index 0000000..52c163c --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/simple_page.html @@ -0,0 +1,9 @@ + + + + Simple Page + + +
    Simple page with simple test.
    + + diff --git a/node_modules/selenium-webdriver/lib/test/data/xhtmlFormPage.xhtml b/node_modules/selenium-webdriver/lib/test/data/xhtmlFormPage.xhtml new file mode 100644 index 0000000..aca53d3 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/xhtmlFormPage.xhtml @@ -0,0 +1,17 @@ + + + + XHTML + + + +
    + + +
    + +

    Here is some content that should not be in the previous p tag + + + diff --git a/node_modules/selenium-webdriver/lib/test/data/xhtmlTest.html b/node_modules/selenium-webdriver/lib/test/data/xhtmlTest.html new file mode 100644 index 0000000..d2f3a5d --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/xhtmlTest.html @@ -0,0 +1,76 @@ + + + + XHTML Test Page + + +

    + + + +
    +

    XHTML Might Be The Future

    + +

    If you'd like to go elsewhere then click me.

    + +

    Alternatively, this goes to the same place.

    + +
    + +
    + + This link has the same text as another link: click me. +
    + +
    Another div starts here.

    +

    An H2 title

    +

    Some more text

    +
    + +
    + Foo +
      + +
    + +
    +
    +
    + + +
    +
    +
    + + I have width +
    +
    +
    +
    + + +

    +

    +
    Link=equalssign + +

    Spaced out

    + + +
    first_div
    +
    second_div
    + first_span + second_span +
    + +
    I'm a parent +
    I'm a child
    +
    + +
    Woo woo
    + + diff --git a/node_modules/selenium-webdriver/lib/test/fileserver.js b/node_modules/selenium-webdriver/lib/test/fileserver.js new file mode 100644 index 0000000..86dea38 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/fileserver.js @@ -0,0 +1,469 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var fs = require('fs'), + http = require('http'), + path = require('path'), + url = require('url'); + +var Server = require('./httpserver').Server, + resources = require('./resources'), + promise = require('../..').promise, + isDevMode = require('../../_base').isDevMode(), + string = require('../../_base').require('goog.string'); + +var WEB_ROOT = isDevMode ? '/common/src/web' : '/common'; +var JS_ROOT = '/javascript'; + +var baseDirectory = resources.locate('.'), + server = new Server(onRequest); + + +var Pages = (function() { + var pages = {}; + function addPage(page, path) { + pages.__defineGetter__(page, function() { + return exports.whereIs(path); + }); + } + + addPage('ajaxyPage', 'ajaxy_page.html'); + addPage('alertsPage', 'alerts.html'); + addPage('bodyTypingPage', 'bodyTypingTest.html'); + addPage('booleanAttributes', 'booleanAttributes.html'); + addPage('childPage', 'child/childPage.html'); + addPage('chinesePage', 'cn-test.html'); + addPage('clickJacker', 'click_jacker.html'); + addPage('clickEventPage', 'clickEventPage.html'); + addPage('clicksPage', 'clicks.html'); + addPage('colorPage', 'colorPage.html'); + addPage('deletingFrame', 'deletingFrame.htm'); + addPage('draggableLists', 'draggableLists.html'); + addPage('dragAndDropPage', 'dragAndDropTest.html'); + addPage('droppableItems', 'droppableItems.html'); + addPage('documentWrite', 'document_write_in_onload.html'); + addPage('dynamicallyModifiedPage', 'dynamicallyModifiedPage.html'); + addPage('dynamicPage', 'dynamic.html'); + addPage('errorsPage', 'errors.html'); + addPage('xhtmlFormPage', 'xhtmlFormPage.xhtml'); + addPage('formPage', 'formPage.html'); + addPage('formSelectionPage', 'formSelectionPage.html'); + addPage('framesetPage', 'frameset.html'); + addPage('grandchildPage', 'child/grandchild/grandchildPage.html'); + addPage('html5Page', 'html5Page.html'); + addPage('html5OfflinePage', 'html5/offline.html'); + addPage('iframePage', 'iframes.html'); + addPage('javascriptEnhancedForm', 'javascriptEnhancedForm.html'); + addPage('javascriptPage', 'javascriptPage.html'); + addPage('linkedImage', 'linked_image.html'); + addPage('longContentPage', 'longContentPage.html'); + addPage('macbethPage', 'macbeth.html'); + addPage('mapVisibilityPage', 'map_visibility.html'); + addPage('metaRedirectPage', 'meta-redirect.html'); + addPage('missedJsReferencePage', 'missedJsReference.html'); + addPage('mouseTrackerPage', 'mousePositionTracker.html'); + addPage('nestedPage', 'nestedElements.html'); + addPage('readOnlyPage', 'readOnlyPage.html'); + addPage('rectanglesPage', 'rectangles.html'); + addPage('redirectPage', 'redirect'); + addPage('resultPage', 'resultPage.html'); + addPage('richTextPage', 'rich_text.html'); + addPage('selectableItemsPage', 'selectableItems.html'); + addPage('selectPage', 'selectPage.html'); + addPage('simpleTestPage', 'simpleTest.html'); + addPage('simpleXmlDocument', 'simple.xml'); + addPage('sleepingPage', 'sleep'); + addPage('slowIframes', 'slow_loading_iframes.html'); + addPage('slowLoadingAlertPage', 'slowLoadingAlert.html'); + addPage('svgPage', 'svgPiechart.xhtml'); + addPage('tables', 'tables.html'); + addPage('underscorePage', 'underscore.html'); + addPage('unicodeLtrPage', 'utf8/unicode_ltr.html'); + addPage('uploadPage', 'upload.html'); + addPage('veryLargeCanvas', 'veryLargeCanvas.html'); + addPage('xhtmlTestPage', 'xhtmlTest.html'); + + return pages; +})(); + + +var Path = { + BASIC_AUTH: WEB_ROOT + '/basicAuth', + MANIFEST: WEB_ROOT + '/manifest', + REDIRECT: WEB_ROOT + '/redirect', + PAGE: WEB_ROOT + '/page', + SLEEP: WEB_ROOT + '/sleep', + UPLOAD: WEB_ROOT + '/upload' +}; + + +/** + * HTTP request handler. + * @param {!http.ServerRequest} request The request object. + * @param {!http.ServerResponse} response The response object. + */ +function onRequest(request, response) { + if (request.method !== 'GET' && request.method !== 'HEAD') { + response.writeHead(405, {'Allowed': 'GET,HEAD'}); + return response.end(); + } + + var pathname = path.resolve(url.parse(request.url).pathname); + if (pathname === '/') { + return sendIndex(request, response); + } + + if (pathname === '/favicon.ico') { + response.writeHead(204); + return response.end(); + } + + switch (pathname) { + case Path.BASIC_AUTH: return sendBasicAuth(response); + case Path.MANIFEST: return sendManifest(response); + case Path.PAGE: return sendInifinitePage(request, response); + case Path.REDIRECT: return redirectToResultPage(response); + case Path.SLEEP: return sendDelayedResponse(request, response); + case Path.UPLOAD: return sendUpload(response); + } + + if (string.startsWith(pathname, Path.PAGE + '/')) { + return sendInifinitePage(request, response); + } + + if ((string.startsWith(pathname, WEB_ROOT) || + string.startsWith(pathname, JS_ROOT)) && + string.endsWith(pathname, '.appcache')) { + return sendManifest(response); + } + + if (string.startsWith(pathname, WEB_ROOT)) { + if (!isDevMode) { + pathname = pathname.substring(WEB_ROOT.length); + } + } else if (string.startsWith(pathname, JS_ROOT)) { + if (!isDevMode) { + sendSimpleError(response, 404, request.url); + return; + } + pathname = pathname.substring(JS_ROOT); + } + + try { + var fullPath = resources.locate(pathname); + } catch (ex) { + fullPath = ''; + } + + if (fullPath.lastIndexOf(baseDirectory, 0) == -1) { + sendSimpleError(response, 404, request.url); + return; + } + + fs.stat(fullPath, function(err, stats) { + if (err) { + sendIOError(request, response, err); + } else if (stats.isDirectory()) { + sendDirectoryListing(request, response, fullPath); + } else if (stats.isFile()) { + sendFile(request, response, fullPath); + } else { + sendSimpleError(response, 404, request.url); + } + }); +} + + +function redirectToResultPage(response) { + response.writeHead(303, { + Location: Pages.resultPage + }); + return response.end(); +} + + +function sendInifinitePage(request, response) { + setTimeout(function() { + var pathname = url.parse(request.url).pathname; + var lastIndex = pathname.lastIndexOf('/'); + var pageNumber = + (lastIndex == -1 ? 'Unknown' : pathname.substring(lastIndex + 1)); + var body = [ + '', + 'Page', pageNumber, '', + 'Page number ', pageNumber, '', + '

    top' + ].join(''); + response.writeHead(200, { + 'Content-Length': Buffer.byteLength(body, 'utf8'), + 'Content-Type': 'text/html; charset=utf-8' + }); + response.end(body); + }, 500); +} + + +function sendDelayedResponse(request, response) { + var duration = 0; + var query = url.parse(request.url).query || ''; + var match = query.match(/\btime=(\d+)/); + if (match) { + duration = parseInt(match[1]); + } + + setTimeout(function() { + var body = [ + '', + 'Done', + 'Slept for ', duration, 's' + ].join(''); + response.writeHead(200, { + 'Content-Length': Buffer.byteLength(body, 'utf8'), + 'Content-Type': 'text/html; charset=utf-8', + 'Cache-Control': 'no-cache', + 'Pragma': 'no-cache', + 'Expires': 0 + }); + response.end(body); + }, duration * 1000); +} + + +/** + * Sends an error in response to an I/O operation. + * @param {!http.ServerRequest} request The request object. + * @param {!http.ServerResponse} response The response object. + * @param {!Error} err The I/O error. + */ +function sendIOError(request, response, err) { + var code = 500; + if (err.code === 'ENOENT') { + code = 404; + } else if (err.code === 'EACCES') { + code = 403; + } + sendSimpleError(response, code, request.url); +} + + +/** + * Sends a simple error message to the client and instructs it to close the + * connection. + * @param {!http.ServerResponse} response The response to populate. + * @param {number} code The numeric HTTP code to send. + * @param {string} message The error message. + */ +function sendSimpleError(response, code, message) { + response.writeHead(code, { + 'Content-Type': 'text/html; charset=utf-8', + 'Connection': 'close' + }); + response.end( + '

    ' + code + ' ' + http.STATUS_CODES[code] + + '


    ' + message); +} + + +var MimeType = { + 'css': 'text/css', + 'gif': 'image/gif', + 'html': 'text/html', + 'js': 'application/javascript', + 'png': 'image/png', + 'svg': 'image/svg+xml', + 'txt': 'text/plain', + 'xhtml': 'application/xhtml+xml', + 'xsl': 'application/xml', + 'xml': 'application/xml' +}; + + +/** + * Responds to a request for an individual file. + * @param {!http.ServerRequest} request The request object. + * @param {!http.ServerResponse} response The response object. + * @param {string} filePath Path to the file to return. + */ +function sendFile(request, response, filePath) { + fs.readFile(filePath, function(err, buffer) { + if (err) { + sendIOError(request, response, err); + return; + } + var index = filePath.lastIndexOf('.'); + var type = MimeType[index < 0 ? '' : filePath.substring(index + 1)]; + var headers = {'Content-Length': buffer.length}; + if (type) headers['Content-Type'] = type; + response.writeHead(200, headers); + response.end(buffer); + }); +} + + +/** + * Responds to a request for the file server's main index. + * @param {!http.ServerRequest} request The request object. + * @param {!http.ServerResponse} response The response object. + */ +function sendIndex(request, response) { + var pathname = url.parse(request.url).pathname; + + var host = request.headers.host; + if (!host) { + host = server.host(); + } + + var requestUrl = ['http://' + host + pathname].join(''); + + function createListEntry(path) { + var url = requestUrl + path; + return ['
  • ', path, ''].join(''); + } + + var data = ['

    /


      ', + createListEntry('common')]; + if (isDevMode) { + data.push(createListEntry('javascript')); + } + data.push('
    '); + data = data.join(''); + + response.writeHead(200, { + 'Content-Type': 'text/html; charset=UTF-8', + 'Content-Length': Buffer.byteLength(data, 'utf8') + }); + response.end(data); +} + + +/** + * Responds to a request for a directory listing. + * @param {!http.ServerRequest} request The request object. + * @param {!http.ServerResponse} response The response object. + * @param {string} dirPath Path to the directory to generate a listing for. + */ +function sendDirectoryListing(request, response, dirPath) { + var pathname = url.parse(request.url).pathname; + + var host = request.headers.host; + if (!host) { + host = server.host(); + } + + var requestUrl = ['http://' + host + pathname].join(''); + if (requestUrl[requestUrl.length - 1] !== '/') { + response.writeHead(303, {'Location': requestUrl + '/'}); + return response.end(); + } + + fs.readdir(dirPath, function(err, files) { + if (err) { + sendIOError(request, response, err); + return; + } + + var data = ['

    ', pathname, '


      ']; + if (pathname !== '/') { + data.push(createListEntry('../')); + } + processNextFile(); + + function processNextFile() { + var file = files.shift(); + if (file) { + fs.stat(path.join(dirPath, file), function(err, stats) { + if (err) { + sendIOError(request, response, err); + return; + } + + data.push(createListEntry( + stats.isDirectory() ? file + '/' : file)); + processNextFile(); + }); + } else { + data = new Buffer(data.join(''), 'utf-8'); + response.writeHead(200, { + 'Content-Type': 'text/html; charset=utf-8', + 'Content-Length': data.length + }); + response.end(data); + } + } + + function createListEntry(path) { + var url = requestUrl + path; + return ['
    • ', path, ''].join(''); + } + }); +} + + +// PUBLIC application + + +/** + * Starts the server on the specified port. + * @param {number=} opt_port The port to use, or 0 for any free port. + * @return {!webdriver.promise.Promise.} A promise that will resolve + * with the server host when it has fully started. + */ +exports.start = server.start.bind(server); + + +/** + * Stops the server. + * @return {!webdriver.promise.Promise} A promise that will resolve when the + * server has closed all connections. + */ +exports.stop = server.stop.bind(server); + + +/** + * Formats a URL for this server. + * @param {string=} opt_pathname The desired pathname on the server. + * @return {string} The formatted URL. + * @throws {Error} If the server is not running. + */ +exports.url = server.url.bind(server); + + +/** + * Builds the URL for a file in the //common/src/web directory of the + * Selenium client. + * @param {string} filePath A path relative to //common/src/web to compute a + * URL for. + * @return {string} The formatted URL. + * @throws {Error} If the server is not running. + */ +exports.whereIs = function(filePath) { + filePath = filePath.replace(/\\/g, '/'); + if (!string.startsWith(filePath, '/')) { + filePath = '/' + filePath; + } + return server.url(WEB_ROOT + filePath); +}; + + +exports.Pages = Pages; + + +if (require.main === module) { + server.start(2310).then(function() { + console.log('Server running at ' + server.url()); + }); +} diff --git a/node_modules/selenium-webdriver/lib/test/httpserver.js b/node_modules/selenium-webdriver/lib/test/httpserver.js new file mode 100644 index 0000000..e75298e --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/httpserver.js @@ -0,0 +1,117 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var assert = require('assert'), + http = require('http'), + url = require('url'); + +var portprober = require('../../net/portprober'), + promise = require('../..').promise; + + + +/** + * Encapsulates a simple HTTP server for testing. The {@code onrequest} + * function should be overridden to define request handling behavior. + * @param {function(!http.ServerRequest, !http.ServerResponse)} requestHandler + * The request handler for the server. + * @constructor + */ +var Server = function(requestHandler) { + var server = http.createServer(function(req, res) { + requestHandler(req, res); + }); + + server.on('connection', function(stream) { + stream.setTimeout(4000); + }); + + /** @typedef {{port: number, address: string, family: string}} */ + var Host; + + /** + * Starts the server on the given port. If no port, or 0, is provided, + * the server will be started on a random port. + * @param {number=} opt_port The port to start on. + * @return {!webdriver.promise.Promise.} A promise that will resolve + * with the server host when it has fully started. + */ + this.start = function(opt_port) { + var port = opt_port || portprober.findFreePort('localhost'); + return promise.when(port, function(port) { + return promise.checkedNodeCall( + server.listen.bind(server, port, 'localhost')); + }).then(function() { + return server.address(); + }); + }; + + /** + * Stops the server. + * @return {!webdriver.promise.Promise} A promise that will resolve when the + * server has closed all connections. + */ + this.stop = function() { + var d = promise.defer(); + server.close(d.fulfill); + return d.promise; + }; + + /** + * @return {Host} This server's host info. + * @throws {Error} If the server is not running. + */ + this.address = function() { + var addr = server.address(); + if (!addr) { + throw Error('There server is not running!'); + } + return addr; + }; + + /** + * return {string} The host:port of this server. + * @throws {Error} If the server is not running. + */ + this.host = function() { + var addr = this.address(); + return addr.address + ':' + addr.port; + }; + + /** + * Formats a URL for this server. + * @param {string=} opt_pathname The desired pathname on the server. + * @return {string} The formatted URL. + * @throws {Error} If the server is not running. + */ + this.url = function(opt_pathname) { + var addr = this.address(); + var pathname = opt_pathname || ''; + return url.format({ + protocol: 'http', + hostname: addr.address, + port: addr.port, + pathname: pathname + }); + }; +}; + + +// PUBLIC API + + +exports.Server = Server; diff --git a/node_modules/selenium-webdriver/lib/test/index.js b/node_modules/selenium-webdriver/lib/test/index.js new file mode 100644 index 0000000..f328bee --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/index.js @@ -0,0 +1,268 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var assert = require('assert'); + +var webdriver = require('../..'), + flow = webdriver.promise.controlFlow(), + testing = require('../../testing'), + fileserver = require('./fileserver'), + seleniumserver = require('./seleniumserver'); + + +var Browser = { + ANDROID: 'android', + CHROME: 'chrome', + IE: 'internet explorer', + // Shorthand for IPAD && IPHONE when using the browsers predciate. + IOS: 'iOS', + IPAD: 'iPad', + IPHONE: 'iPhone', + FIREFOX: 'firefox', + OPERA: 'opera', + PHANTOMJS: 'phantomjs', + SAFARI: 'safari', + + // Browsers that should always be tested via the java Selenium server. + REMOTE_CHROME: 'remote.chrome', + REMOTE_PHANTOMJS: 'remote.phantomjs' +}; + + +/** + * Browsers with native support. + * @type {!Array.} + */ +var NATIVE_BROWSERS = [ + Browser.CHROME, + Browser.PHANTOMJS +]; + + +var browsersToTest = (function() { + var browsers = process.env['SELENIUM_BROWSER'] || Browser.CHROME; + browsers = browsers.split(','); + browsers.forEach(function(browser) { + if (browser === Browser.IOS) { + throw Error('Invalid browser name: ' + browser); + } + + for (var name in Browser) { + if (Browser.hasOwnProperty(name) && Browser[name] === browser) { + return; + } + } + + throw Error('Unrecognized browser: ' + browser); + }); + return browsers; +})(); + + +/** + * Creates a predicate function that ignores tests for specific browsers. + * @param {string} currentBrowser The name of the current browser. + * @param {!Array.} browsersToIgnore The browsers to ignore. + * @return {function(): boolean} The predicate function. + */ +function browsers(currentBrowser, browsersToIgnore) { + return function() { + var checkIos = + currentBrowser === Browser.IPAD || currentBrowser === Browser.IPHONE; + return browsersToIgnore.indexOf(currentBrowser) != -1 || + (checkIos && browsersToIgnore.indexOf(Browser.IOS) != -1); + }; +} + + +/** + * @param {string} browserName The name to use. + * @param {remote.DriverService} server The server to use, if any. + * @constructor + */ +function TestEnvironment(browserName, server) { + var name = browserName; + if (name.lastIndexOf('remote.', 0) == 0) { + name = name.substring('remote.'.length); + } + + var autoCreate = true; + this.__defineGetter__( + 'autoCreateDriver', function() { return autoCreate; }); + this.__defineSetter__( + 'autoCreateDriver', function(auto) { autoCreate = auto; }); + + this.__defineGetter__('browser', function() { return name; }); + + var driver; + this.__defineGetter__('driver', function() { return driver; }); + + this.browsers = function(var_args) { + var browsersToIgnore = Array.prototype.slice.apply(arguments, [0]); + var remoteVariants = []; + browsersToIgnore.forEach(function(browser) { + if (browser.lastIndexOf('remote.', 0) === 0) { + remoteVariants.push(browser.substring('remote.'.length)); + } + }); + browsersToIgnore = browsersToIgnore.concat(remoteVariants); + return browsers(browserName, browsersToIgnore); + }; + + this.builder = function() { + assert.ok(!driver, 'Can only have one driver at a time'); + var builder = new webdriver.Builder(); + var realBuild = builder.build; + + builder.build = function() { + builder.getCapabilities(). + set(webdriver.Capability.BROWSER_NAME, name); + + if (server) { + builder.usingServer(server.address()); + } + return driver = realBuild.call(builder); + }; + + return builder; + }; + + this.createDriver = function() { + if (!driver) { + driver = this.builder().build(); + } + return driver; + }; + + this.refreshDriver = function() { + if (driver) { + driver.quit(); + driver = null; + } + this.createDriver(); + }; + + this.dispose = function() { + if (driver) { + driver.quit(); + driver = null; + } + }; + + this.waitForTitleToBe = function(expected) { + driver.wait(function() { + return driver.getTitle().then(function(title) { + return title === expected; + }); + }, 5000, 'Waiting for title to be ' + expected); + }; +} + + +var seleniumServer; +var inSuite = false; + + +/** + * Expands a function to cover each of the target browsers. + * @param {function(!TestEnvironment)} fn The top level suite + * function. + * @param {{browsers: !Array.}=} opt_options Suite specific options. + */ +function suite(fn, opt_options) { + assert.ok(!inSuite, 'You may not nest suite calls'); + inSuite = true; + + var suiteOptions = opt_options || {}; + var browsers = suiteOptions.browsers; + if (browsers) { + // Filter out browser specific tests when that browser is not currently + // selected for testing. + browsers = browsers.filter(function(browser) { + if (browsersToTest.indexOf(browser) != -1) { + return true; + } + return browsersToTest.indexOf( + browser.substring('remote.'.length)) != -1; + }); + } else { + browsers = browsersToTest; + } + + try { + browsers.forEach(function(browser) { + + testing.describe('[' + browser + ']', function() { + var serverToUse = null; + + if (NATIVE_BROWSERS.indexOf(browser) == -1) { + serverToUse = seleniumServer; + if (!serverToUse) { + serverToUse = seleniumServer = new seleniumserver.Server(); + } + testing.before(seleniumServer.start.bind(seleniumServer, 60 * 1000)); + } + + var env = new TestEnvironment(browser, serverToUse); + + testing.beforeEach(function() { + if (env.autoCreateDriver) { + env.createDriver(); + } + }); + + testing.after(function() { + env.dispose(); + }); + + fn(env); + }); + }); + } finally { + inSuite = false; + } +} + + +// GLOBAL TEST SETUP + + +testing.before(fileserver.start); +testing.after(fileserver.stop); + +// Server is only started if required for a specific config. +testing.after(function() { + if (seleniumServer) { + seleniumServer.stop(); + } +}); + + +// PUBLIC API + + +exports.suite = suite; +exports.after = testing.after; +exports.afterEach = testing.afterEach; +exports.before = testing.before; +exports.beforeEach = testing.beforeEach; +exports.it = testing.it; +exports.ignore = testing.ignore; + +exports.Browser = Browser; +exports.Pages = fileserver.Pages; +exports.whereIs = fileserver.whereIs; diff --git a/node_modules/selenium-webdriver/lib/test/resources.js b/node_modules/selenium-webdriver/lib/test/resources.js new file mode 100644 index 0000000..2f95828 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/resources.js @@ -0,0 +1,42 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var fs = require('fs'), + path = require('path'); + +var resourceRoot = require('../../_base').isDevMode() ? + require('./build').projectRoot() : + path.join(__dirname, 'data'); + + +// PUBLIC API + + +/** + * Locates a test resource. + * @param {string} resourcePath Path of the resource to locate. + * @param {string} filePath The file to locate from the root of the project. + * @return {string} The full path for the file, if it exists. + * @throws {Error} If the file does not exist. + */ +exports.locate = function(filePath) { + var fullPath = path.normalize(path.join(resourceRoot, filePath)); + if (!fs.existsSync(fullPath)) { + throw Error('File does not exist: ' + filePath); + } + return fullPath; +}; diff --git a/node_modules/selenium-webdriver/lib/test/seleniumserver.js b/node_modules/selenium-webdriver/lib/test/seleniumserver.js new file mode 100644 index 0000000..932a02a --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/seleniumserver.js @@ -0,0 +1,81 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var assert = require('assert'), + fs = require('fs'), + util = require('util'); + +var promise = require('../..').promise, + isDevMode = require('../../_base').isDevMode(), + RemoteServer = require('../../remote').SeleniumServer, + build = require('./build'); + + +var DEV_MODE_JAR_PATH = + 'build/java/server/src/org/openqa/grid/selenium/selenium-standalone.jar'; +var SELENIUM_SERVER_JAR_ENV = 'SELENIUM_SERVER_JAR'; +var PROD_MODE_JAR_PATH = process.env[SELENIUM_SERVER_JAR_ENV]; + + +function buildServer() { + if (process.env.SKIP_BUILD) { + return promise.fulfilled(); + } + return build.of('selenium-server-standalone').onlyOnce().go(); +} + + +function getProdModeJarPath() { + assert.ok(!!PROD_MODE_JAR_PATH, + 'You must specify the Selenium server jar to use with the ' + + SELENIUM_SERVER_JAR_ENV + ' environment variable'); + assert.ok(fs.existsSync(PROD_MODE_JAR_PATH), + SELENIUM_SERVER_JAR_ENV + ' does not exist: ' + PROD_MODE_JAR_PATH); + return PROD_MODE_JAR_PATH; +} + + +/** + * Manages the life and death of a Selenium server built in the current client. + * @throws {Error} If not running dev mode and the Selenium server cannot be + * found on the PATH. + * @constructor + * @extends {RemoteServer} + */ +function Server() { + var jarPath = isDevMode ? DEV_MODE_JAR_PATH : getProdModeJarPath(); + RemoteServer.call(this, jarPath, { + port: 0 + }); +} +util.inherits(Server, RemoteServer); + + +/** @override */ +Server.prototype.start = function(opt_timeout) { + var startServer = RemoteServer.prototype.start.bind(this, opt_timeout); + if (isDevMode) { + return buildServer().then(startServer); + } + return startServer(); +}; + + +// PUBLIC API + + +exports.Server = Server; diff --git a/node_modules/selenium-webdriver/lib/webdriver/abstractbuilder.js b/node_modules/selenium-webdriver/lib/webdriver/abstractbuilder.js new file mode 100644 index 0000000..f535f47 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/abstractbuilder.js @@ -0,0 +1,122 @@ +// Copyright 2012 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('webdriver.AbstractBuilder'); + +goog.require('webdriver.Capabilities'); +goog.require('webdriver.process'); + + + +/** + * Creates new {@code webdriver.WebDriver} clients. Upon instantiation, each + * Builder will configure itself based on the following environment variables: + *
      + *
      {@code webdriver.AbstractBuilder.SERVER_URL_ENV}
      + *
      Defines the remote WebDriver server that should be used for command + * command execution; may be overridden using + * {@code webdriver.AbstractBuilder.prototype.usingServer}.
      + *
      + * @constructor + */ +webdriver.AbstractBuilder = function() { + + /** + * URL of the remote server to use for new clients; initialized from the + * value of the {@link webdriver.AbstractBuilder.SERVER_URL_ENV} environment + * variable, but may be overridden using + * {@link webdriver.AbstractBuilder#usingServer}. + * @private {string} + */ + this.serverUrl_ = webdriver.process.getEnv( + webdriver.AbstractBuilder.SERVER_URL_ENV); + + /** + * The desired capabilities to use when creating a new session. + * @private {!webdriver.Capabilities} + */ + this.capabilities_ = new webdriver.Capabilities(); +}; + + +/** + * Environment variable that defines the URL of the WebDriver server that + * should be used for all new WebDriver clients. This setting may be overridden + * using {@code #usingServer(url)}. + * @type {string} + * @const + * @see webdriver.process.getEnv + */ +webdriver.AbstractBuilder.SERVER_URL_ENV = 'wdurl'; + + +/** + * The default URL of the WebDriver server to use if + * {@link webdriver.AbstractBuilder.SERVER_URL_ENV} is not set. + * @type {string} + * @const + */ +webdriver.AbstractBuilder.DEFAULT_SERVER_URL = 'http://localhost:4444/wd/hub'; + + +/** + * Configures which WebDriver server should be used for new sessions. Overrides + * the value loaded from the {@link webdriver.AbstractBuilder.SERVER_URL_ENV} + * upon creation of this instance. + * @param {string} url URL of the server to use. + * @return {!webdriver.AbstractBuilder} This Builder instance for chain calling. + */ +webdriver.AbstractBuilder.prototype.usingServer = function(url) { + this.serverUrl_ = url; + return this; +}; + + +/** + * @return {string} The URL of the WebDriver server this instance is configured + * to use. + */ +webdriver.AbstractBuilder.prototype.getServerUrl = function() { + return this.serverUrl_; +}; + + +/** + * Sets the desired capabilities when requesting a new session. This will + * overwrite any previously set desired capabilities. + * @param {!(Object|webdriver.Capabilities)} capabilities The desired + * capabilities for a new session. + * @return {!webdriver.AbstractBuilder} This Builder instance for chain calling. + */ +webdriver.AbstractBuilder.prototype.withCapabilities = function(capabilities) { + this.capabilities_ = new webdriver.Capabilities(capabilities); + return this; +}; + + +/** + * @return {!webdriver.Capabilities} The current desired capabilities for this + * builder. + */ +webdriver.AbstractBuilder.prototype.getCapabilities = function() { + return this.capabilities_; +}; + + +/** + * Builds a new {@link webdriver.WebDriver} instance using this builder's + * current configuration. + * @return {!webdriver.WebDriver} A new WebDriver client. + */ +webdriver.AbstractBuilder.prototype.build = goog.abstractMethod; diff --git a/node_modules/selenium-webdriver/lib/webdriver/actionsequence.js b/node_modules/selenium-webdriver/lib/webdriver/actionsequence.js new file mode 100644 index 0000000..cd42979 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/actionsequence.js @@ -0,0 +1,356 @@ +// Copyright 2012 Selenium comitters +// Copyright 2012 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('webdriver.ActionSequence'); + +goog.require('goog.array'); +goog.require('webdriver.Button'); +goog.require('webdriver.Command'); +goog.require('webdriver.CommandName'); +goog.require('webdriver.Key'); + + + +/** + * Class for defining sequences of complex user interactions. Each sequence + * will not be executed until {@link #perform} is called. + * + *

      Example:

      
      + *   new webdriver.ActionSequence(driver).
      + *       keyDown(webdriver.Key.SHIFT).
      + *       click(element1).
      + *       click(element2).
      + *       dragAndDrop(element3, element4).
      + *       keyUp(webdriver.Key.SHIFT).
      + *       perform();
      + * 
      + * + * @param {!webdriver.WebDriver} driver The driver instance to use. + * @constructor + */ +webdriver.ActionSequence = function(driver) { + + /** @private {!webdriver.WebDriver} */ + this.driver_ = driver; + + /** @private {!Array.<{description: string, command: !webdriver.Command}>} */ + this.actions_ = []; +}; + + +/** + * Schedules an action to be executed each time {@link #perform} is called on + * this instance. + * @param {string} description A description of the command. + * @param {!webdriver.Command} command The command. + * @private + */ +webdriver.ActionSequence.prototype.schedule_ = function(description, command) { + this.actions_.push({ + description: description, + command: command + }); +}; + + +/** + * Executes this action sequence. + * @return {!webdriver.promise.Promise} A promise that will be resolved once + * this sequence has completed. + */ +webdriver.ActionSequence.prototype.perform = function() { + // Make a protected copy of the scheduled actions. This will protect against + // users defining additional commands before this sequence is actually + // executed. + var actions = goog.array.clone(this.actions_); + var driver = this.driver_; + return driver.controlFlow().execute(function() { + goog.array.forEach(actions, function(action) { + driver.schedule(action.command, action.description); + }); + }, 'ActionSequence.perform'); +}; + + +/** + * Moves the mouse. The location to move to may be specified in terms of the + * mouse's current location, an offset relative to the top-left corner of an + * element, or an element (in which case the middle of the element is used). + * @param {(!webdriver.WebElement|{x: number, y: number})} location The + * location to drag to, as either another WebElement or an offset in pixels. + * @param {{x: number, y: number}=} opt_offset If the target {@code location} + * is defined as a {@link webdriver.WebElement}, this parameter defines an + * offset within that element. The offset should be specified in pixels + * relative to the top-left corner of the element's bounding box. If + * omitted, the element's center will be used as the target offset. + * @return {!webdriver.ActionSequence} A self reference. + */ +webdriver.ActionSequence.prototype.mouseMove = function(location, opt_offset) { + var command = new webdriver.Command(webdriver.CommandName.MOVE_TO); + + if (goog.isNumber(location.x)) { + setOffset(/** @type {{x: number, y: number}} */(location)); + } else { + // The interactions API expect the element ID to be encoded as a simple + // string, not the usual JSON object. + var id = /** @type {!webdriver.WebElement} */ (location).toWireValue(). + then(function(value) { + return value['ELEMENT']; + }); + command.setParameter('element', id); + if (opt_offset) { + setOffset(opt_offset); + } + } + + this.schedule_('mouseMove', command); + return this; + + /** @param {{x: number, y: number}} offset The offset to use. */ + function setOffset(offset) { + command.setParameter('xoffset', offset.x || 0); + command.setParameter('yoffset', offset.y || 0); + } +}; + + +/** + * Schedules a mouse action. + * @param {string} description A simple descriptive label for the scheduled + * action. + * @param {!webdriver.CommandName} commandName The name of the command. + * @param {(webdriver.WebElement|webdriver.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link webdriver.Button.LEFT} if neither an element nor + * button is specified. + * @param {webdriver.Button=} opt_button The button to use. Defaults to + * {@link webdriver.Button.LEFT}. Ignored if the previous argument is + * provided as a button. + * @return {!webdriver.ActionSequence} A self reference. + * @private + */ +webdriver.ActionSequence.prototype.scheduleMouseAction_ = function( + description, commandName, opt_elementOrButton, opt_button) { + var button; + if (goog.isNumber(opt_elementOrButton)) { + button = opt_elementOrButton; + } else { + if (opt_elementOrButton) { + this.mouseMove( + /** @type {!webdriver.WebElement} */ (opt_elementOrButton)); + } + button = goog.isDef(opt_button) ? opt_button : webdriver.Button.LEFT; + } + + var command = new webdriver.Command(commandName). + setParameter('button', button); + this.schedule_(description, command); + return this; +}; + + +/** + * Presses a mouse button. The mouse button will not be released until + * {@link #mouseUp} is called, regardless of whether that call is made in this + * sequence or another. The behavior for out-of-order events (e.g. mouseDown, + * click) is undefined. + * + *

      If an element is provided, the mouse will first be moved to the center + * of that element. This is equivalent to: + *

      sequence.mouseMove(element).mouseDown()
      + * + *

      Warning: this method currently only supports the left mouse button. See + * http://code.google.com/p/selenium/issues/detail?id=4047 + * + * @param {(webdriver.WebElement|webdriver.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link webdriver.Button.LEFT} if neither an element nor + * button is specified. + * @param {webdriver.Button=} opt_button The button to use. Defaults to + * {@link webdriver.Button.LEFT}. Ignored if a button is provided as the + * first argument. + * @return {!webdriver.ActionSequence} A self reference. + */ +webdriver.ActionSequence.prototype.mouseDown = function(opt_elementOrButton, + opt_button) { + return this.scheduleMouseAction_('mouseDown', + webdriver.CommandName.MOUSE_DOWN, opt_elementOrButton, opt_button); +}; + + +/** + * Releases a mouse button. Behavior is undefined for calling this function + * without a previous call to {@link #mouseDown}. + * + *

      If an element is provided, the mouse will first be moved to the center + * of that element. This is equivalent to: + *

      sequence.mouseMove(element).mouseUp()
      + * + *

      Warning: this method currently only supports the left mouse button. See + * http://code.google.com/p/selenium/issues/detail?id=4047 + * + * @param {(webdriver.WebElement|webdriver.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link webdriver.Button.LEFT} if neither an element nor + * button is specified. + * @param {webdriver.Button=} opt_button The button to use. Defaults to + * {@link webdriver.Button.LEFT}. Ignored if a button is provided as the + * first argument. + * @return {!webdriver.ActionSequence} A self reference. + */ +webdriver.ActionSequence.prototype.mouseUp = function(opt_elementOrButton, + opt_button) { + return this.scheduleMouseAction_('mouseUp', + webdriver.CommandName.MOUSE_UP, opt_elementOrButton, opt_button); +}; + + +/** + * Convenience function for performing a "drag and drop" manuever. The target + * element may be moved to the location of another element, or by an offset (in + * pixels). + * @param {!webdriver.WebElement} element The element to drag. + * @param {(!webdriver.WebElement|{x: number, y: number})} location The + * location to drag to, either as another WebElement or an offset in pixels. + * @return {!webdriver.ActionSequence} A self reference. + */ +webdriver.ActionSequence.prototype.dragAndDrop = function(element, location) { + return this.mouseDown(element).mouseMove(location).mouseUp(); +}; + + +/** + * Clicks a mouse button. + * + *

      If an element is provided, the mouse will first be moved to the center + * of that element. This is equivalent to: + *

      sequence.mouseMove(element).click()
      + * + * @param {(webdriver.WebElement|webdriver.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link webdriver.Button.LEFT} if neither an element nor + * button is specified. + * @param {webdriver.Button=} opt_button The button to use. Defaults to + * {@link webdriver.Button.LEFT}. Ignored if a button is provided as the + * first argument. + * @return {!webdriver.ActionSequence} A self reference. + */ +webdriver.ActionSequence.prototype.click = function(opt_elementOrButton, + opt_button) { + return this.scheduleMouseAction_('click', + webdriver.CommandName.CLICK, opt_elementOrButton, opt_button); +}; + + +/** + * Double-clicks a mouse button. + * + *

      If an element is provided, the mouse will first be moved to the center of + * that element. This is equivalent to: + *

      sequence.mouseMove(element).doubleClick()
      + * + *

      Warning: this method currently only supports the left mouse button. See + * http://code.google.com/p/selenium/issues/detail?id=4047 + * + * @param {(webdriver.WebElement|webdriver.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link webdriver.Button.LEFT} if neither an element nor + * button is specified. + * @param {webdriver.Button=} opt_button The button to use. Defaults to + * {@link webdriver.Button.LEFT}. Ignored if a button is provided as the + * first argument. + * @return {!webdriver.ActionSequence} A self reference. + */ +webdriver.ActionSequence.prototype.doubleClick = function(opt_elementOrButton, + opt_button) { + return this.scheduleMouseAction_('doubleClick', + webdriver.CommandName.DOUBLE_CLICK, opt_elementOrButton, opt_button); +}; + + +/** + * Schedules a keyboard action. + * @param {string} description A simple descriptive label for the scheduled + * action. + * @param {!Array.<(string|!webdriver.Key)>} keys The keys to send. + * @return {!webdriver.ActionSequence} A self reference. + * @private + */ +webdriver.ActionSequence.prototype.scheduleKeyboardAction_ = function( + description, keys) { + var command = + new webdriver.Command(webdriver.CommandName.SEND_KEYS_TO_ACTIVE_ELEMENT). + setParameter('value', keys); + this.schedule_(description, command); + return this; +}; + + +/** + * Checks that a key is a modifier key. + * @param {!webdriver.Key} key The key to check. + * @throws {Error} If the key is not a modifier key. + * @private + */ +webdriver.ActionSequence.checkModifierKey_ = function(key) { + if (key !== webdriver.Key.ALT && key !== webdriver.Key.CONTROL && + key !== webdriver.Key.SHIFT && key !== webdriver.Key.COMMAND) { + throw Error('Not a modifier key'); + } +}; + + +/** + * Performs a modifier key press. The modifier key is not released + * until {@link #keyUp} or {@link #sendKeys} is called. The key press will be + * targetted at the currently focused element. + * @param {!webdriver.Key} key The modifier key to push. Must be one of + * {ALT, CONTROL, SHIFT, COMMAND, META}. + * @return {!webdriver.ActionSequence} A self reference. + * @throws {Error} If the key is not a valid modifier key. + */ +webdriver.ActionSequence.prototype.keyDown = function(key) { + webdriver.ActionSequence.checkModifierKey_(key); + return this.scheduleKeyboardAction_('keyDown', [key]); +}; + + +/** + * Performs a modifier key release. The release is targetted at the currently + * focused element. + * @param {!webdriver.Key} key The modifier key to release. Must be one of + * {ALT, CONTROL, SHIFT, COMMAND, META}. + * @return {!webdriver.ActionSequence} A self reference. + * @throws {Error} If the key is not a valid modifier key. + */ +webdriver.ActionSequence.prototype.keyUp = function(key) { + webdriver.ActionSequence.checkModifierKey_(key); + return this.scheduleKeyboardAction_('keyUp', [key]); +}; + + +/** + * Simulates typing multiple keys. Each modifier key encountered in the + * sequence will not be released until it is encountered again. All key events + * will be targetted at the currently focused element. + * @param {...(string|!webdriver.Key|!Array.<(string|!webdriver.Key)>)} var_args + * The keys to type. + * @return {!webdriver.ActionSequence} A self reference. + * @throws {Error} If the key is not a valid modifier key. + */ +webdriver.ActionSequence.prototype.sendKeys = function(var_args) { + var keys = goog.array.flatten(goog.array.slice(arguments, 0)); + return this.scheduleKeyboardAction_('sendKeys', keys); +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/builder.js b/node_modules/selenium-webdriver/lib/webdriver/builder.js new file mode 100644 index 0000000..28d1721 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/builder.js @@ -0,0 +1,117 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('webdriver.Builder'); + +goog.require('goog.userAgent'); +goog.require('webdriver.AbstractBuilder'); +goog.require('webdriver.FirefoxDomExecutor'); +goog.require('webdriver.WebDriver'); +goog.require('webdriver.http.CorsClient'); +goog.require('webdriver.http.Executor'); +goog.require('webdriver.http.XhrClient'); +goog.require('webdriver.process'); + + + +/** + * @constructor + * @extends {webdriver.AbstractBuilder} + */ +webdriver.Builder = function() { + goog.base(this); + + /** + * ID of an existing WebDriver session that new clients should use. + * Initialized from the value of the + * {@link webdriver.AbstractBuilder.SESSION_ID_ENV} environment variable, but + * may be overridden using + * {@link webdriver.AbstractBuilder#usingSession}. + * @private {string} + */ + this.sessionId_ = + webdriver.process.getEnv(webdriver.Builder.SESSION_ID_ENV); +}; +goog.inherits(webdriver.Builder, webdriver.AbstractBuilder); + + +/** + * Environment variable that defines the session ID of an existing WebDriver + * session to use when creating clients. If set, all new Builder instances will + * default to creating clients that use this session. To create a new session, + * use {@code #useExistingSession(boolean)}. The use of this environment + * variable requires that {@link webdriver.AbstractBuilder.SERVER_URL_ENV} also + * be set. + * @type {string} + * @const + * @see webdriver.process.getEnv + */ +webdriver.Builder.SESSION_ID_ENV = 'wdsid'; + + +/** + * Configures the builder to create a client that will use an existing WebDriver + * session. + * @param {string} id The existing session ID to use. + * @return {!webdriver.AbstractBuilder} This Builder instance for chain calling. + */ +webdriver.Builder.prototype.usingSession = function(id) { + this.sessionId_ = id; + return this; +}; + + +/** + * @return {string} The ID of the session, if any, this builder is configured + * to reuse. + */ +webdriver.Builder.prototype.getSession = function() { + return this.sessionId_; +}; + + +/** + * @override + */ +webdriver.Builder.prototype.build = function() { + if (goog.userAgent.GECKO && document.readyState != 'complete') { + throw Error('Cannot create driver instance before window.onload'); + } + + var executor; + + if (webdriver.FirefoxDomExecutor.isAvailable()) { + executor = new webdriver.FirefoxDomExecutor(); + return webdriver.WebDriver.createSession(executor, this.getCapabilities()); + } else { + var url = this.getServerUrl() || + webdriver.AbstractBuilder.DEFAULT_SERVER_URL; + var client; + if (url[0] == '/') { + var origin = window.location.origin || + (window.location.protocol + '//' + window.location.host); + client = new webdriver.http.XhrClient(origin + url); + } else { + client = new webdriver.http.CorsClient(url); + } + executor = new webdriver.http.Executor(client); + + if (this.getSession()) { + return webdriver.WebDriver.attachToSession(executor, this.getSession()); + } else { + throw new Error('Unable to create a new client for this browser. The ' + + 'WebDriver session ID has not been defined.'); + } + } +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/button.js b/node_modules/selenium-webdriver/lib/webdriver/button.js new file mode 100644 index 0000000..aedb0b3 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/button.js @@ -0,0 +1,27 @@ +// Copyright 2012 Selenium comitters +// Copyright 2012 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('webdriver.Button'); + + +/** + * Enumeration of the buttons used in the advanced interactions API. + * @enum {number} + */ +webdriver.Button = { + LEFT: 0, + MIDDLE: 1, + RIGHT: 2 +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/capabilities.js b/node_modules/selenium-webdriver/lib/webdriver/capabilities.js new file mode 100644 index 0000000..783322a --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/capabilities.js @@ -0,0 +1,318 @@ +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Defines the webdriver.Capabilities class. + */ + +goog.provide('webdriver.Browser'); +goog.provide('webdriver.Capabilities'); +goog.provide('webdriver.Capability'); + + + +/** + * Recognized browser names. + * @enum {string} + */ +webdriver.Browser = { + ANDROID: 'android', + CHROME: 'chrome', + FIREFOX: 'firefox', + INTERNET_EXPLORER: 'internet explorer', + IPAD: 'iPad', + IPHONE: 'iPhone', + OPERA: 'opera', + PHANTOM_JS: 'phantomjs', + SAFARI: 'safari', + HTMLUNIT: 'htmlunit' +}; + + + +/** + * Common webdriver capability keys. + * @enum {string} + */ +webdriver.Capability = { + + /** + * Indicates whether a driver should accept all SSL certs by default. This + * capability only applies when requesting a new session. To query whether + * a driver can handle insecure SSL certs, see + * {@link webdriver.Capability.SECURE_SSL}. + */ + ACCEPT_SSL_CERTS: 'acceptSslCerts', + + + /** + * The browser name. Common browser names are defined in the + * {@link webdriver.Browser} enum. + */ + BROWSER_NAME: 'browserName', + + /** + * Whether the driver is capable of handling modal alerts (e.g. alert, + * confirm, prompt). To define how a driver should handle alerts, + * use {@link webdriver.Capability.UNEXPECTED_ALERT_BEHAVIOR}. + */ + HANDLES_ALERTS: 'handlesAlerts', + + /** + * Key for the logging driver logging preferences. + */ + LOGGING_PREFS: 'loggingPrefs', + + /** + * Describes the platform the browser is running on. Will be one of + * ANDROID, IOS, LINUX, MAC, UNIX, or WINDOWS. When requesting a + * session, ANY may be used to indicate no platform preference (this is + * semantically equivalent to omitting the platform capability). + */ + PLATFORM: 'platform', + + /** + * Describes the proxy configuration to use for a new WebDriver session. + */ + PROXY: 'proxy', + + /** Whether the driver supports changing the brower's orientation. */ + ROTATABLE: 'rotatable', + + /** + * Whether a driver is only capable of handling secure SSL certs. To request + * that a driver accept insecure SSL certs by default, use + * {@link webdriver.Capability.ACCEPT_SSL_CERTS}. + */ + SECURE_SSL: 'secureSsl', + + /** Whether the driver supports manipulating the app cache. */ + SUPPORTS_APPLICATION_CACHE: 'applicationCacheEnabled', + + /** + * Whether the driver supports controlling the browser's internet + * connectivity. + */ + SUPPORTS_BROWSER_CONNECTION: 'browserConnectionEnabled', + + /** Whether the driver supports locating elements with CSS selectors. */ + SUPPORTS_CSS_SELECTORS: 'cssSelectorsEnabled', + + /** Whether the browser supports JavaScript. */ + SUPPORTS_JAVASCRIPT: 'javascriptEnabled', + + /** Whether the driver supports controlling the browser's location info. */ + SUPPORTS_LOCATION_CONTEXT: 'locationContextEnabled', + + /** Whether the driver supports taking screenshots. */ + TAKES_SCREENSHOT: 'takesScreenshot', + + /** + * Defines how the driver should handle unexpected alerts. The value should + * be one of "accept", "dismiss", or "ignore. + */ + UNEXPECTED_ALERT_BEHAVIOR: 'unexpectedAlertBehavior', + + /** Defines the browser version. */ + VERSION: 'version' +}; + + + +/** + * @param {(webdriver.Capabilities|Object)=} opt_other Another set of + * capabilities to merge into this instance. + * @constructor + */ +webdriver.Capabilities = function(opt_other) { + + /** @private {!Object} */ + this.caps_ = {}; + + if (opt_other) { + this.merge(opt_other); + } +}; + + +/** + * @return {!webdriver.Capabilities} A basic set of capabilities for Android. + */ +webdriver.Capabilities.android = function() { + return new webdriver.Capabilities(). + set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.ANDROID). + set(webdriver.Capability.PLATFORM, 'ANDROID'); +}; + + +/** + * @return {!webdriver.Capabilities} A basic set of capabilities for Chrome. + */ +webdriver.Capabilities.chrome = function() { + return new webdriver.Capabilities(). + set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.CHROME); +}; + + +/** + * @return {!webdriver.Capabilities} A basic set of capabilities for Firefox. + */ +webdriver.Capabilities.firefox = function() { + return new webdriver.Capabilities(). + set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.FIREFOX); +}; + + +/** + * @return {!webdriver.Capabilities} A basic set of capabilities for + * Internet Explorer. + */ +webdriver.Capabilities.ie = function() { + return new webdriver.Capabilities(). + set(webdriver.Capability.BROWSER_NAME, + webdriver.Browser.INTERNET_EXPLORER). + set(webdriver.Capability.PLATFORM, 'WINDOWS'); +}; + + +/** + * @return {!webdriver.Capabilities} A basic set of capabilities for iPad. + */ +webdriver.Capabilities.ipad = function() { + return new webdriver.Capabilities(). + set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.IPAD). + set(webdriver.Capability.PLATFORM, 'MAC'); +}; + + +/** + * @return {!webdriver.Capabilities} A basic set of capabilities for iPhone. + */ +webdriver.Capabilities.iphone = function() { + return new webdriver.Capabilities(). + set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.IPHONE). + set(webdriver.Capability.PLATFORM, 'MAC'); +}; + + +/** + * @return {!webdriver.Capabilities} A basic set of capabilities for Opera. + */ +webdriver.Capabilities.opera = function() { + return new webdriver.Capabilities(). + set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.OPERA); +}; + + +/** + * @return {!webdriver.Capabilities} A basic set of capabilities for + * PhantomJS. + */ +webdriver.Capabilities.phantomjs = function() { + return new webdriver.Capabilities(). + set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.PHANTOM_JS); +}; + + +/** + * @return {!webdriver.Capabilities} A basic set of capabilities for Safari. + */ +webdriver.Capabilities.safari = function() { + return new webdriver.Capabilities(). + set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.SAFARI); +}; + + +/** + * @return {!webdriver.Capabilities} A basic set of capabilities for HTMLUnit. + */ +webdriver.Capabilities.htmlunit = function() { + return new webdriver.Capabilities(). + set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.HTMLUNIT); +}; + + +/** + * @return {!webdriver.Capabilities} A basic set of capabilities for HTMLUnit + * with enabled Javascript. + */ +webdriver.Capabilities.htmlunitwithjs = function() { + return new webdriver.Capabilities(). + set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.HTMLUNIT). + set(webdriver.Capability.SUPPORTS_JAVASCRIPT, true); +}; + + +/** @return {!Object} The JSON representation of this instance. */ +webdriver.Capabilities.prototype.toJSON = function() { + return this.caps_; +}; + + +/** + * Merges another set of capabilities into this instance. Any duplicates in + * the provided set will override those already set on this instance. + * @param {!(webdriver.Capabilities|Object)} other The capabilities to + * merge into this instance. + * @return {!webdriver.Capabilities} A self reference. + */ +webdriver.Capabilities.prototype.merge = function(other) { + var caps = other instanceof webdriver.Capabilities ? + other.caps_ : other; + for (var key in caps) { + if (caps.hasOwnProperty(key)) { + this.set(key, caps[key]); + } + } + return this; +}; + + +/** + * @param {string} key The capability to set. + * @param {*} value The capability value. Capability values must be JSON + * serializable. Pass {@code null} to unset the capability. + * @return {!webdriver.Capabilities} A self reference. + */ +webdriver.Capabilities.prototype.set = function(key, value) { + if (goog.isDefAndNotNull(value)) { + this.caps_[key] = value; + } else { + delete this.caps_[key]; + } + return this; +}; + + +/** + * @param {string} key The capability to return. + * @return {*} The capability with the given key, or {@code null} if it has + * not been set. + */ +webdriver.Capabilities.prototype.get = function(key) { + var val = null; + if (this.caps_.hasOwnProperty(key)) { + val = this.caps_[key]; + } + return goog.isDefAndNotNull(val) ? val : null; +}; + + +/** + * @param {string} key The capability to check. + * @return {boolean} Whether the specified capability is set. + */ +webdriver.Capabilities.prototype.has = function(key) { + return !!this.get(key); +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/command.js b/node_modules/selenium-webdriver/lib/webdriver/command.js new file mode 100644 index 0000000..3db8443 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/command.js @@ -0,0 +1,240 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Contains several classes for handling commands. + */ + +goog.provide('webdriver.Command'); +goog.provide('webdriver.CommandExecutor'); +goog.provide('webdriver.CommandName'); + + + +/** + * Describes a command to be executed by the WebDriverJS framework. + * @param {!webdriver.CommandName} name The name of this command. + * @constructor + */ +webdriver.Command = function(name) { + + /** + * The name of this command. + * @private {!webdriver.CommandName} + */ + this.name_ = name; + + /** + * The parameters to this command. + * @private {!Object.<*>} + */ + this.parameters_ = {}; +}; + + +/** + * @return {!webdriver.CommandName} This command's name. + */ +webdriver.Command.prototype.getName = function() { + return this.name_; +}; + + +/** + * Sets a parameter to send with this command. + * @param {string} name The parameter name. + * @param {*} value The parameter value. + * @return {!webdriver.Command} A self reference. + */ +webdriver.Command.prototype.setParameter = function(name, value) { + this.parameters_[name] = value; + return this; +}; + + +/** + * Sets the parameters for this command. + * @param {!Object.<*>} parameters The command parameters. + * @return {!webdriver.Command} A self reference. + */ +webdriver.Command.prototype.setParameters = function(parameters) { + this.parameters_ = parameters; + return this; +}; + + +/** + * Returns a named command parameter. + * @param {string} key The parameter key to look up. + * @return {*} The parameter value, or undefined if it has not been set. + */ +webdriver.Command.prototype.getParameter = function(key) { + return this.parameters_[key]; +}; + + +/** + * @return {!Object.<*>} The parameters to send with this command. + */ +webdriver.Command.prototype.getParameters = function() { + return this.parameters_; +}; + + +/** + * Enumeration of predefined names command names that all command processors + * will support. + * @enum {string} + */ +// TODO: Delete obsolete command names. +webdriver.CommandName = { + GET_SERVER_STATUS: 'getStatus', + + NEW_SESSION: 'newSession', + GET_SESSIONS: 'getSessions', + DESCRIBE_SESSION: 'getSessionCapabilities', + + CLOSE: 'close', + QUIT: 'quit', + + GET_CURRENT_URL: 'getCurrentUrl', + GET: 'get', + GO_BACK: 'goBack', + GO_FORWARD: 'goForward', + REFRESH: 'refresh', + + ADD_COOKIE: 'addCookie', + GET_COOKIE: 'getCookie', + GET_ALL_COOKIES: 'getCookies', + DELETE_COOKIE: 'deleteCookie', + DELETE_ALL_COOKIES: 'deleteAllCookies', + + GET_ACTIVE_ELEMENT: 'getActiveElement', + FIND_ELEMENT: 'findElement', + FIND_ELEMENTS: 'findElements', + FIND_CHILD_ELEMENT: 'findChildElement', + FIND_CHILD_ELEMENTS: 'findChildElements', + + CLEAR_ELEMENT: 'clearElement', + CLICK_ELEMENT: 'clickElement', + SEND_KEYS_TO_ELEMENT: 'sendKeysToElement', + SUBMIT_ELEMENT: 'submitElement', + + GET_CURRENT_WINDOW_HANDLE: 'getCurrentWindowHandle', + GET_WINDOW_HANDLES: 'getWindowHandles', + GET_WINDOW_POSITION: 'getWindowPosition', + SET_WINDOW_POSITION: 'setWindowPosition', + GET_WINDOW_SIZE: 'getWindowSize', + SET_WINDOW_SIZE: 'setWindowSize', + MAXIMIZE_WINDOW: 'maximizeWindow', + + SWITCH_TO_WINDOW: 'switchToWindow', + SWITCH_TO_FRAME: 'switchToFrame', + GET_PAGE_SOURCE: 'getPageSource', + GET_TITLE: 'getTitle', + + EXECUTE_SCRIPT: 'executeScript', + EXECUTE_ASYNC_SCRIPT: 'executeAsyncScript', + + GET_ELEMENT_TEXT: 'getElementText', + GET_ELEMENT_TAG_NAME: 'getElementTagName', + IS_ELEMENT_SELECTED: 'isElementSelected', + IS_ELEMENT_ENABLED: 'isElementEnabled', + IS_ELEMENT_DISPLAYED: 'isElementDisplayed', + GET_ELEMENT_LOCATION: 'getElementLocation', + GET_ELEMENT_LOCATION_IN_VIEW: 'getElementLocationOnceScrolledIntoView', + GET_ELEMENT_SIZE: 'getElementSize', + GET_ELEMENT_ATTRIBUTE: 'getElementAttribute', + GET_ELEMENT_VALUE_OF_CSS_PROPERTY: 'getElementValueOfCssProperty', + ELEMENT_EQUALS: 'elementEquals', + + SCREENSHOT: 'screenshot', + IMPLICITLY_WAIT: 'implicitlyWait', + SET_SCRIPT_TIMEOUT: 'setScriptTimeout', + SET_TIMEOUT: 'setTimeout', + + ACCEPT_ALERT: 'acceptAlert', + DISMISS_ALERT: 'dismissAlert', + GET_ALERT_TEXT: 'getAlertText', + SET_ALERT_TEXT: 'setAlertValue', + + EXECUTE_SQL: 'executeSQL', + GET_LOCATION: 'getLocation', + SET_LOCATION: 'setLocation', + GET_APP_CACHE: 'getAppCache', + GET_APP_CACHE_STATUS: 'getStatus', + CLEAR_APP_CACHE: 'clearAppCache', + IS_BROWSER_ONLINE: 'isBrowserOnline', + SET_BROWSER_ONLINE: 'setBrowserOnline', + + GET_LOCAL_STORAGE_ITEM: 'getLocalStorageItem', + GET_LOCAL_STORAGE_KEYS: 'getLocalStorageKeys', + SET_LOCAL_STORAGE_ITEM: 'setLocalStorageItem', + REMOVE_LOCAL_STORAGE_ITEM: 'removeLocalStorageItem', + CLEAR_LOCAL_STORAGE: 'clearLocalStorage', + GET_LOCAL_STORAGE_SIZE: 'getLocalStorageSize', + + GET_SESSION_STORAGE_ITEM: 'getSessionStorageItem', + GET_SESSION_STORAGE_KEYS: 'getSessionStorageKey', + SET_SESSION_STORAGE_ITEM: 'setSessionStorageItem', + REMOVE_SESSION_STORAGE_ITEM: 'removeSessionStorageItem', + CLEAR_SESSION_STORAGE: 'clearSessionStorage', + GET_SESSION_STORAGE_SIZE: 'getSessionStorageSize', + + SET_SCREEN_ORIENTATION: 'setScreenOrientation', + GET_SCREEN_ORIENTATION: 'getScreenOrientation', + + // These belong to the Advanced user interactions - an element is + // optional for these commands. + CLICK: 'mouseClick', + DOUBLE_CLICK: 'mouseDoubleClick', + MOUSE_DOWN: 'mouseButtonDown', + MOUSE_UP: 'mouseButtonUp', + MOVE_TO: 'mouseMoveTo', + SEND_KEYS_TO_ACTIVE_ELEMENT: 'sendKeysToActiveElement', + + // These belong to the Advanced Touch API + TOUCH_SINGLE_TAP: 'touchSingleTap', + TOUCH_DOWN: 'touchDown', + TOUCH_UP: 'touchUp', + TOUCH_MOVE: 'touchMove', + TOUCH_SCROLL: 'touchScroll', + TOUCH_DOUBLE_TAP: 'touchDoubleTap', + TOUCH_LONG_PRESS: 'touchLongPress', + TOUCH_FLICK: 'touchFlick', + + GET_AVAILABLE_LOG_TYPES: 'getAvailableLogTypes', + GET_LOG: 'getLog', + GET_SESSION_LOGS: 'getSessionLogs' +}; + + + +/** + * Handles the execution of {@code webdriver.Command} objects. + * @interface + */ +webdriver.CommandExecutor = function() {}; + + +/** + * Executes the given {@code command}. If there is an error executing the + * command, the provided callback will be invoked with the offending error. + * Otherwise, the callback will be invoked with a null Error and non-null + * {@link bot.response.ResponseObject} object. + * @param {!webdriver.Command} command The command to execute. + * @param {function(Error, !bot.response.ResponseObject=)} callback the function + * to invoke when the command response is ready. + */ +webdriver.CommandExecutor.prototype.execute = goog.abstractMethod; diff --git a/node_modules/selenium-webdriver/lib/webdriver/events.js b/node_modules/selenium-webdriver/lib/webdriver/events.js new file mode 100644 index 0000000..a420163 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/events.js @@ -0,0 +1,176 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview A light weight event system modeled after Node's EventEmitter. + */ + +goog.provide('webdriver.EventEmitter'); + + + +/** + * Object that can emit events for others to listen for. This is used instead + * of Closure's event system because it is much more light weight. The API is + * based on Node's EventEmitters. + * @constructor + */ +webdriver.EventEmitter = function() { + /** + * Map of events to registered listeners. + * @private {!Object.>} + */ + this.events_ = {}; +}; + + +/** + * Fires an event and calls all listeners. + * @param {string} type The type of event to emit. + * @param {...*} var_args Any arguments to pass to each listener. + */ +webdriver.EventEmitter.prototype.emit = function(type, var_args) { + var args = Array.prototype.slice.call(arguments, 1); + var listeners = this.events_[type]; + if (!listeners) { + return; + } + for (var i = 0; i < listeners.length;) { + var listener = listeners[i]; + listener.fn.apply(listener.scope, args); + if (listeners[i] === listener) { + if (listeners[i].oneshot) { + listeners.splice(i, 1); + } else { + i += 1; + } + } + } +}; + + +/** + * Returns a mutable list of listeners for a specific type of event. + * @param {string} type The type of event to retrieve the listeners for. + * @return {!Array.<{fn: !Function, oneshot: boolean, + * scope: (Object|undefined)}>} The registered listeners for + * the given event type. + */ +webdriver.EventEmitter.prototype.listeners = function(type) { + var listeners = this.events_[type]; + if (!listeners) { + listeners = this.events_[type] = []; + } + return listeners; +}; + + +/** + * Registers a listener. + * @param {string} type The type of event to listen for. + * @param {!Function} listenerFn The function to invoke when the event is fired. + * @param {Object=} opt_scope The object in whose scope to invoke the listener. + * @param {boolean=} opt_oneshot Whether the listener should be removed after + * the first event is fired. + * @return {!webdriver.EventEmitter} A self reference. + * @private + */ +webdriver.EventEmitter.prototype.addListener_ = function(type, listenerFn, + opt_scope, opt_oneshot) { + var listeners = this.listeners(type); + var n = listeners.length; + for (var i = 0; i < n; ++i) { + if (listeners[i].fn == listenerFn) { + return this; + } + } + + listeners.push({ + fn: listenerFn, + scope: opt_scope, + oneshot: !!opt_oneshot + }); + return this; +}; + + +/** + * Registers a listener. + * @param {string} type The type of event to listen for. + * @param {!Function} listenerFn The function to invoke when the event is fired. + * @param {Object=} opt_scope The object in whose scope to invoke the listener. + * @return {!webdriver.EventEmitter} A self reference. + */ +webdriver.EventEmitter.prototype.addListener = function(type, listenerFn, + opt_scope) { + return this.addListener_(type, listenerFn, opt_scope); +}; + + +/** + * Registers a one-time listener which will be called only the first time an + * event is emitted, after which it will be removed. + * @param {string} type The type of event to listen for. + * @param {!Function} listenerFn The function to invoke when the event is fired. + * @param {Object=} opt_scope The object in whose scope to invoke the listener. + * @return {!webdriver.EventEmitter} A self reference. + */ +webdriver.EventEmitter.prototype.once = function(type, listenerFn, opt_scope) { + return this.addListener_(type, listenerFn, opt_scope, true); +}; + + +/** + * An alias for {@code #addListener()}. + * @param {string} type The type of event to listen for. + * @param {!Function} listenerFn The function to invoke when the event is fired. + * @param {Object=} opt_scope The object in whose scope to invoke the listener. + * @return {!webdriver.EventEmitter} A self reference. + */ +webdriver.EventEmitter.prototype.on = + webdriver.EventEmitter.prototype.addListener; + + +/** + * Removes a previously registered event listener. + * @param {string} type The type of event to unregister. + * @param {!Function} listenerFn The handler function to remove. + * @return {!webdriver.EventEmitter} A self reference. + */ +webdriver.EventEmitter.prototype.removeListener = function(type, listenerFn) { + var listeners = this.events_[type]; + if (listeners) { + var n = listeners.length; + for (var i = 0; i < n; ++i) { + if (listeners[i].fn == listenerFn) { + listeners.splice(i, 1); + return this; + } + } + } + return this; +}; + + +/** + * Removes all listeners for a specific type of event. If no event is + * specified, all listeners across all types will be removed. + * @param {string=} opt_type The type of event to remove listeners from. + * @return {!webdriver.EventEmitter} A self reference. + */ +webdriver.EventEmitter.prototype.removeAllListeners = function(opt_type) { + goog.isDef(opt_type) ? delete this.events_[opt_type] : this.events_ = {}; + return this; +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/firefoxdomexecutor.js b/node_modules/selenium-webdriver/lib/webdriver/firefoxdomexecutor.js new file mode 100644 index 0000000..5b200cc --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/firefoxdomexecutor.js @@ -0,0 +1,172 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('webdriver.FirefoxDomExecutor'); + +goog.require('bot.response'); +goog.require('goog.json'); +goog.require('goog.userAgent.product'); +goog.require('webdriver.Command'); +goog.require('webdriver.CommandName'); + + + +/** + * @constructor + * @implements {webdriver.CommandExecutor} + */ +webdriver.FirefoxDomExecutor = function() { + if (!webdriver.FirefoxDomExecutor.isAvailable()) { + throw Error( + 'The current environment does not support the FirefoxDomExecutor'); + } + + /** @private {!Document} */ + this.doc_ = document; + + /** @private {!Element} */ + this.docElement_ = document.documentElement; + + this.docElement_.addEventListener( + webdriver.FirefoxDomExecutor.EventType_.RESPONSE, + goog.bind(this.onResponse_, this), false); +}; + + +/** + * @return {boolean} Whether the current environment supports the + * FirefoxDomExecutor. + */ +webdriver.FirefoxDomExecutor.isAvailable = function() { + return goog.userAgent.product.FIREFOX && + typeof document !== 'undefined' && + document.documentElement && + goog.isFunction(document.documentElement.hasAttribute) && + document.documentElement.hasAttribute('webdriver'); +}; + + +/** + * Attributes used to communicate with the FirefoxDriver extension. + * @enum {string} + * @private + */ +webdriver.FirefoxDomExecutor.Attribute_ = { + COMMAND: 'command', + RESPONSE: 'response' +}; + + +/** + * Events used to communicate with the FirefoxDriver extension. + * @enum {string} + * @private + */ +webdriver.FirefoxDomExecutor.EventType_ = { + COMMAND: 'webdriverCommand', + RESPONSE: 'webdriverResponse' +}; + + +/** + * The pending command, if any. + * @private {?{name:string, callback:!Function}} + */ +webdriver.FirefoxDomExecutor.prototype.pendingCommand_ = null; + + +/** @override */ +webdriver.FirefoxDomExecutor.prototype.execute = function(command, callback) { + if (this.pendingCommand_) { + throw Error('Currently awaiting a command response!'); + } + + this.pendingCommand_ = { + name: command.getName(), + callback: callback + }; + + var parameters = command.getParameters(); + + // There are two means for communicating with the FirefoxDriver: via + // HTTP using WebDriver's wire protocol and over the DOM using a custom + // JSON protocol. This class uses the latter. When the FirefoxDriver receives + // commands over HTTP, it builds a parameters object from the URL parameters. + // When an element ID is sent in the URL, it'll be decoded as just id:string + // instead of id:{ELEMENT:string}. When switching to a frame by element, + // however, the element ID is not sent through the URL, so we must make sure + // to encode that parameter properly here. It would be nice if we unified + // the two protocols used by the FirefoxDriver... + if (parameters['id'] && + parameters['id']['ELEMENT'] && + command.getName() != webdriver.CommandName.SWITCH_TO_FRAME) { + parameters['id'] = parameters['id']['ELEMENT']; + } + var json = goog.json.serialize({ + 'name': command.getName(), + 'sessionId': parameters['sessionId'], + 'parameters': parameters + }); + this.docElement_.setAttribute( + webdriver.FirefoxDomExecutor.Attribute_.COMMAND, json); + + var event = this.doc_.createEvent('Event'); + event.initEvent(webdriver.FirefoxDomExecutor.EventType_.COMMAND, + /*canBubble=*/true, /*cancelable=*/true); + + this.docElement_.dispatchEvent(event); +}; + + +/** @private */ +webdriver.FirefoxDomExecutor.prototype.onResponse_ = function() { + if (!this.pendingCommand_) { + return; // Not expecting a response. + } + + var command = this.pendingCommand_; + this.pendingCommand_ = null; + + var json = this.docElement_.getAttribute( + webdriver.FirefoxDomExecutor.Attribute_.RESPONSE); + if (!json) { + command.callback(Error('Empty command response!')); + return; + } + + this.docElement_.removeAttribute( + webdriver.FirefoxDomExecutor.Attribute_.COMMAND); + this.docElement_.removeAttribute( + webdriver.FirefoxDomExecutor.Attribute_.RESPONSE); + + try { + var response = bot.response.checkResponse( + /** @type {!bot.response.ResponseObject} */ (goog.json.parse(json))); + } catch (ex) { + command.callback(ex); + return; + } + + // Prior to Selenium 2.35.0, two commands are required to fully create a + // session: one to allocate the session, and another to fetch the + // capabilities. + if (command.name == webdriver.CommandName.NEW_SESSION && + goog.isString(response['value'])) { + var cmd = new webdriver.Command(webdriver.CommandName.DESCRIBE_SESSION). + setParameter('sessionId', response['value']); + this.execute(cmd, command.callback); + } else { + command.callback(null, response); + } +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/http/corsclient.js b/node_modules/selenium-webdriver/lib/webdriver/http/corsclient.js new file mode 100644 index 0000000..b0ea15a --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/http/corsclient.js @@ -0,0 +1,130 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('webdriver.http.CorsClient'); + +goog.require('goog.json'); +goog.require('webdriver.http.Response'); + + + +/** + * Communicates with a WebDriver server, which may be on a different domain, + * using the cross-origin resource sharing + * (CORS) extension to WebDriver's JSON wire protocol. + * + *

      Each command from the standard JSON protocol will be encoded in a + * JSON object with the following form: + * {method:string, path:string, data:!Object} + * + *

      The encoded command is then sent as a POST request to the server's /xdrpc + * endpoint. The server will decode the command, re-route it to the appropriate + * handler, and then return the command's response as a standard JSON response + * object. The JSON responses will always be returned with a 200 + * response from the server; clients must rely on the response's "status" field + * to determine whether the command succeeded. + * + *

      This client cannot be used with the standard wire protocol due to + * limitations in the various browser implementations of the CORS specification: + *

        + *
      • IE's XDomainRequest object is only + * capable of generating the types of requests that may be generated through + * a standard HTML form - it can not send + * DELETE requests, as is required in the wire protocol. + *
      • WebKit's implementation of CORS does not follow the spec and forbids + * redirects: https://bugs.webkit.org/show_bug.cgi?id=57600 + * This limitation appears to be intentional and is documented in WebKit's + * Layout tests: + * //LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects.html + *
      • If the server does not return a 2xx response, IE and Opera's + * implementations will fire the XDomainRequest/XMLHttpRequest object's + * onerror handler, but without the corresponding response text returned by + * the server. This renders IE and Opera incapable of handling command + * failures in the standard JSON protocol. + *
      + * + * @param {string} url URL for the WebDriver server to send commands to. + * @constructor + * @implements {webdriver.http.Client} + * @see CORS Spec + * @see + * JSON wire protocol + */ +webdriver.http.CorsClient = function(url) { + if (!webdriver.http.CorsClient.isAvailable()) { + throw Error('The current environment does not support cross-origin ' + + 'resource sharing'); + } + + /** @private {string} */ + this.url_ = url + webdriver.http.CorsClient.XDRPC_ENDPOINT; +}; + + +/** + * Resource URL to send commands to on the server. + * @type {string} + * @const + */ +webdriver.http.CorsClient.XDRPC_ENDPOINT = '/xdrpc'; + + +/** + * Tests whether the current environment supports cross-origin resource sharing. + * @return {boolean} Whether cross-origin resource sharing is supported. + * @see http://www.w3.org/TR/cors/ + */ +webdriver.http.CorsClient.isAvailable = function() { + return typeof XDomainRequest !== 'undefined' || + (typeof XMLHttpRequest !== 'undefined' && + goog.isBoolean(new XMLHttpRequest().withCredentials)); +}; + + +/** @override */ +webdriver.http.CorsClient.prototype.send = function(request, callback) { + try { + var xhr = new (typeof XDomainRequest !== 'undefined' ? + XDomainRequest : XMLHttpRequest); + xhr.open('POST', this.url_, true); + + xhr.onload = function() { + callback(null, webdriver.http.Response.fromXmlHttpRequest( + /** @type {!XMLHttpRequest} */ (xhr))); + }; + + var url = this.url_; + xhr.onerror = function() { + callback(Error([ + 'Unable to send request: POST ', url, + '\nPerhaps the server did not respond to the preflight request ', + 'with valid access control headers?' + ].join(''))); + }; + + // Define event handlers for all events on the XDomainRequest. Apparently, + // if we don't do this, IE9+10 will silently abort our request. Yay IE. + // Note, we're not using goog.nullFunction, because it tends to get + // optimized away by the compiler, which leaves us where we were before. + xhr.onprogress = xhr.ontimeout = function() {}; + + xhr.send(goog.json.serialize({ + 'method': request.method, + 'path': request.path, + 'data': request.data + })); + } catch (ex) { + callback(ex); + } +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/http/http.js b/node_modules/selenium-webdriver/lib/webdriver/http/http.js new file mode 100644 index 0000000..a15f2ea --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/http/http.js @@ -0,0 +1,462 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Defines a {@code webdriver.CommandExecutor} that communicates + * with a server over HTTP. + */ + +goog.provide('webdriver.http.Client'); +goog.provide('webdriver.http.Executor'); +goog.provide('webdriver.http.Request'); +goog.provide('webdriver.http.Response'); + +goog.require('bot.ErrorCode'); +goog.require('goog.array'); +goog.require('goog.json'); +goog.require('webdriver.CommandName'); +goog.require('webdriver.promise.Deferred'); + + + +/** + * Interface used for sending individual HTTP requests to the server. + * @interface + */ +webdriver.http.Client = function() { +}; + + +/** + * Sends a request to the server. If an error occurs while sending the request, + * such as a failure to connect to the server, the provided callback will be + * invoked with a non-null {@code Error} describing the error. Otherwise, when + * the server's response has been received, the callback will be invoked with a + * null Error and non-null {@code webdriver.http.Response} object. + * + * @param {!webdriver.http.Request} request The request to send. + * @param {function(Error, !webdriver.http.Response=)} callback the function to + * invoke when the server's response is ready. + */ +webdriver.http.Client.prototype.send = function(request, callback) { +}; + + + +/** + * A command executor that communicates with a server using the WebDriver + * command protocol. + * @param {!webdriver.http.Client} client The client to use when sending + * requests to the server. + * @constructor + * @implements {webdriver.CommandExecutor} + */ +webdriver.http.Executor = function(client) { + + /** + * Client used to communicate with the server. + * @private {!webdriver.http.Client} + */ + this.client_ = client; +}; + + +/** @override */ +webdriver.http.Executor.prototype.execute = function(command, callback) { + var resource = webdriver.http.Executor.COMMAND_MAP_[command.getName()]; + if (!resource) { + throw new Error('Unrecognized command: ' + command.getName()); + } + + var parameters = command.getParameters(); + var path = webdriver.http.Executor.buildPath_(resource.path, parameters); + var request = new webdriver.http.Request(resource.method, path, parameters); + + this.client_.send(request, function(e, response) { + var responseObj; + if (!e) { + try { + responseObj = webdriver.http.Executor.parseHttpResponse_( + /** @type {!webdriver.http.Response} */ (response)); + } catch (ex) { + e = ex; + } + } + callback(e, responseObj); + }); +}; + + +/** + * Builds a fully qualified path using the given set of command parameters. Each + * path segment prefixed with ':' will be replaced by the value of the + * corresponding parameter. All parameters spliced into the path will be + * removed from the parameter map. + * @param {string} path The original resource path. + * @param {!Object.<*>} parameters The parameters object to splice into + * the path. + * @return {string} The modified path. + * @private + */ +webdriver.http.Executor.buildPath_ = function(path, parameters) { + var pathParameters = path.match(/\/:(\w+)\b/g); + if (pathParameters) { + for (var i = 0; i < pathParameters.length; ++i) { + var key = pathParameters[i].substring(2); // Trim the /: + if (key in parameters) { + var value = parameters[key]; + // TODO: move webdriver.WebElement.ELEMENT definition to a + // common file so we can reference it here without pulling in all of + // webdriver.WebElement's dependencies. + if (value && value['ELEMENT']) { + // When inserting a WebElement into the URL, only use its ID value, + // not the full JSON. + value = value['ELEMENT']; + } + path = path.replace(pathParameters[i], '/' + value); + delete parameters[key]; + } else { + throw new Error('Missing required parameter: ' + key); + } + } + } + return path; +}; + + +/** + * Callback used to parse {@link webdriver.http.Response} objects from a + * {@link webdriver.http.Client}. + * @param {!webdriver.http.Response} httpResponse The HTTP response to parse. + * @return {!bot.response.ResponseObject} The parsed response. + * @private + */ +webdriver.http.Executor.parseHttpResponse_ = function(httpResponse) { + try { + return /** @type {!bot.response.ResponseObject} */ (goog.json.parse( + httpResponse.body)); + } catch (ex) { + // Whoops, looks like the server sent us a malformed response. We'll need + // to manually build a response object based on the response code. + } + + var response = { + 'status': bot.ErrorCode.SUCCESS, + 'value': httpResponse.body.replace(/\r\n/g, '\n') + }; + + if (!(httpResponse.status > 199 && httpResponse.status < 300)) { + // 404 represents an unknown command; anything else is a generic unknown + // error. + response['status'] = httpResponse.status == 404 ? + bot.ErrorCode.UNKNOWN_COMMAND : + bot.ErrorCode.UNKNOWN_ERROR; + } + + return response; +}; + + +/** + * Maps command names to resource locator. + * @private {!Object.<{method:string, path:string}>} + * @const + */ +webdriver.http.Executor.COMMAND_MAP_ = (function() { + return new Builder(). + put(webdriver.CommandName.GET_SERVER_STATUS, get('/status')). + put(webdriver.CommandName.NEW_SESSION, post('/session')). + put(webdriver.CommandName.GET_SESSIONS, get('/sessions')). + put(webdriver.CommandName.DESCRIBE_SESSION, get('/session/:sessionId')). + put(webdriver.CommandName.QUIT, del('/session/:sessionId')). + put(webdriver.CommandName.CLOSE, del('/session/:sessionId/window')). + put(webdriver.CommandName.GET_CURRENT_WINDOW_HANDLE, + get('/session/:sessionId/window_handle')). + put(webdriver.CommandName.GET_WINDOW_HANDLES, + get('/session/:sessionId/window_handles')). + put(webdriver.CommandName.GET_CURRENT_URL, + get('/session/:sessionId/url')). + put(webdriver.CommandName.GET, post('/session/:sessionId/url')). + put(webdriver.CommandName.GO_BACK, post('/session/:sessionId/back')). + put(webdriver.CommandName.GO_FORWARD, + post('/session/:sessionId/forward')). + put(webdriver.CommandName.REFRESH, + post('/session/:sessionId/refresh')). + put(webdriver.CommandName.ADD_COOKIE, + post('/session/:sessionId/cookie')). + put(webdriver.CommandName.GET_ALL_COOKIES, + get('/session/:sessionId/cookie')). + put(webdriver.CommandName.DELETE_ALL_COOKIES, + del('/session/:sessionId/cookie')). + put(webdriver.CommandName.DELETE_COOKIE, + del('/session/:sessionId/cookie/:name')). + put(webdriver.CommandName.FIND_ELEMENT, + post('/session/:sessionId/element')). + put(webdriver.CommandName.FIND_ELEMENTS, + post('/session/:sessionId/elements')). + put(webdriver.CommandName.GET_ACTIVE_ELEMENT, + post('/session/:sessionId/element/active')). + put(webdriver.CommandName.FIND_CHILD_ELEMENT, + post('/session/:sessionId/element/:id/element')). + put(webdriver.CommandName.FIND_CHILD_ELEMENTS, + post('/session/:sessionId/element/:id/elements')). + put(webdriver.CommandName.CLEAR_ELEMENT, + post('/session/:sessionId/element/:id/clear')). + put(webdriver.CommandName.CLICK_ELEMENT, + post('/session/:sessionId/element/:id/click')). + put(webdriver.CommandName.SEND_KEYS_TO_ELEMENT, + post('/session/:sessionId/element/:id/value')). + put(webdriver.CommandName.SUBMIT_ELEMENT, + post('/session/:sessionId/element/:id/submit')). + put(webdriver.CommandName.GET_ELEMENT_TEXT, + get('/session/:sessionId/element/:id/text')). + put(webdriver.CommandName.GET_ELEMENT_TAG_NAME, + get('/session/:sessionId/element/:id/name')). + put(webdriver.CommandName.IS_ELEMENT_SELECTED, + get('/session/:sessionId/element/:id/selected')). + put(webdriver.CommandName.IS_ELEMENT_ENABLED, + get('/session/:sessionId/element/:id/enabled')). + put(webdriver.CommandName.IS_ELEMENT_DISPLAYED, + get('/session/:sessionId/element/:id/displayed')). + put(webdriver.CommandName.GET_ELEMENT_LOCATION, + get('/session/:sessionId/element/:id/location')). + put(webdriver.CommandName.GET_ELEMENT_SIZE, + get('/session/:sessionId/element/:id/size')). + put(webdriver.CommandName.GET_ELEMENT_ATTRIBUTE, + get('/session/:sessionId/element/:id/attribute/:name')). + put(webdriver.CommandName.GET_ELEMENT_VALUE_OF_CSS_PROPERTY, + get('/session/:sessionId/element/:id/css/:propertyName')). + put(webdriver.CommandName.ELEMENT_EQUALS, + get('/session/:sessionId/element/:id/equals/:other')). + put(webdriver.CommandName.SWITCH_TO_WINDOW, + post('/session/:sessionId/window')). + put(webdriver.CommandName.MAXIMIZE_WINDOW, + post('/session/:sessionId/window/:windowHandle/maximize')). + put(webdriver.CommandName.GET_WINDOW_POSITION, + get('/session/:sessionId/window/:windowHandle/position')). + put(webdriver.CommandName.SET_WINDOW_POSITION, + post('/session/:sessionId/window/:windowHandle/position')). + put(webdriver.CommandName.GET_WINDOW_SIZE, + get('/session/:sessionId/window/:windowHandle/size')). + put(webdriver.CommandName.SET_WINDOW_SIZE, + post('/session/:sessionId/window/:windowHandle/size')). + put(webdriver.CommandName.SWITCH_TO_FRAME, + post('/session/:sessionId/frame')). + put(webdriver.CommandName.GET_PAGE_SOURCE, + get('/session/:sessionId/source')). + put(webdriver.CommandName.GET_TITLE, + get('/session/:sessionId/title')). + put(webdriver.CommandName.EXECUTE_SCRIPT, + post('/session/:sessionId/execute')). + put(webdriver.CommandName.EXECUTE_ASYNC_SCRIPT, + post('/session/:sessionId/execute_async')). + put(webdriver.CommandName.SCREENSHOT, + get('/session/:sessionId/screenshot')). + put(webdriver.CommandName.SET_TIMEOUT, + post('/session/:sessionId/timeouts')). + put(webdriver.CommandName.SET_SCRIPT_TIMEOUT, + post('/session/:sessionId/timeouts/async_script')). + put(webdriver.CommandName.IMPLICITLY_WAIT, + post('/session/:sessionId/timeouts/implicit_wait')). + put(webdriver.CommandName.MOVE_TO, post('/session/:sessionId/moveto')). + put(webdriver.CommandName.CLICK, post('/session/:sessionId/click')). + put(webdriver.CommandName.DOUBLE_CLICK, + post('/session/:sessionId/doubleclick')). + put(webdriver.CommandName.MOUSE_DOWN, + post('/session/:sessionId/buttondown')). + put(webdriver.CommandName.MOUSE_UP, post('/session/:sessionId/buttonup')). + put(webdriver.CommandName.MOVE_TO, post('/session/:sessionId/moveto')). + put(webdriver.CommandName.SEND_KEYS_TO_ACTIVE_ELEMENT, + post('/session/:sessionId/keys')). + put(webdriver.CommandName.ACCEPT_ALERT, + post('/session/:sessionId/accept_alert')). + put(webdriver.CommandName.DISMISS_ALERT, + post('/session/:sessionId/dismiss_alert')). + put(webdriver.CommandName.GET_ALERT_TEXT, + get('/session/:sessionId/alert_text')). + put(webdriver.CommandName.SET_ALERT_TEXT, + post('/session/:sessionId/alert_text')). + put(webdriver.CommandName.GET_LOG, post('/session/:sessionId/log')). + put(webdriver.CommandName.GET_AVAILABLE_LOG_TYPES, + get('/session/:sessionId/log/types')). + put(webdriver.CommandName.GET_SESSION_LOGS, post('/logs')). + build(); + + /** @constructor */ + function Builder() { + var map = {}; + + this.put = function(name, resource) { + map[name] = resource; + return this; + }; + + this.build = function() { + return map; + }; + } + + function post(path) { return resource('POST', path); } + function del(path) { return resource('DELETE', path); } + function get(path) { return resource('GET', path); } + function resource(method, path) { return {method: method, path: path}; } +})(); + + +/** + * Converts a headers object to a HTTP header block string. + * @param {!Object.} headers The headers object to convert. + * @return {string} The headers as a string. + * @private + */ +webdriver.http.headersToString_ = function(headers) { + var ret = []; + for (var key in headers) { + ret.push(key + ': ' + headers[key]); + } + return ret.join('\n'); +}; + + + +/** + * Describes a partial HTTP request. This class is a "partial" request and only + * defines the path on the server to send a request to. It is each + * {@code webdriver.http.Client}'s responsibility to build the full URL for the + * final request. + * @param {string} method The HTTP method to use for the request. + * @param {string} path Path on the server to send the request to. + * @param {Object=} opt_data This request's JSON data. + * @constructor + */ +webdriver.http.Request = function(method, path, opt_data) { + + /** + * The HTTP method to use for the request. + * @type {string} + */ + this.method = method; + + /** + * The path on the server to send the request to. + * @type {string} + */ + this.path = path; + + /** + * This request's body. + * @type {!Object} + */ + this.data = opt_data || {}; + + /** + * The headers to send with the request. + * @type {!Object.<(string|number)>} + */ + this.headers = {'Accept': 'application/json; charset=utf-8'}; +}; + + +/** @override */ +webdriver.http.Request.prototype.toString = function() { + return [ + this.method + ' ' + this.path + ' HTTP/1.1', + webdriver.http.headersToString_(this.headers), + '', + goog.json.serialize(this.data) + ].join('\n'); +}; + + + +/** + * Represents a HTTP response. + * @param {number} status The response code. + * @param {!Object.} headers The response headers. All header + * names will be converted to lowercase strings for consistent lookups. + * @param {string} body The response body. + * @constructor + */ +webdriver.http.Response = function(status, headers, body) { + + /** + * The HTTP response code. + * @type {number} + */ + this.status = status; + + /** + * The response body. + * @type {string} + */ + this.body = body; + + /** + * The response body. + * @type {!Object.} + */ + this.headers = {}; + for (var header in headers) { + this.headers[header.toLowerCase()] = headers[header]; + } +}; + + +/** + * Builds a {@code webdriver.http.Response} from a {@code XMLHttpRequest} or + * {@code XDomainRequest} response object. + * @param {!(XDomainRequest|XMLHttpRequest)} xhr The request to parse. + * @return {!webdriver.http.Response} The parsed response. + */ +webdriver.http.Response.fromXmlHttpRequest = function(xhr) { + var headers = {}; + + // getAllResponseHeaders is only available on XMLHttpRequest objects. + if (xhr.getAllResponseHeaders) { + var tmp = xhr.getAllResponseHeaders(); + if (tmp) { + tmp = tmp.replace(/\r\n/g, '\n').split('\n'); + goog.array.forEach(tmp, function(header) { + var parts = header.split(/\s*:\s*/, 2); + if (parts[0]) { + headers[parts[0]] = parts[1] || ''; + } + }); + } + } + + // If xhr is a XDomainRequest object, it will not have a status. + // However, if we're parsing the response from a XDomainRequest, then + // that request must have been a success, so we can assume status == 200. + var status = xhr.status || 200; + return new webdriver.http.Response(status, headers, + xhr.responseText.replace(/\0/g, '')); +}; + + +/** @override */ +webdriver.http.Response.prototype.toString = function() { + var headers = webdriver.http.headersToString_(this.headers); + var ret = ['HTTP/1.1 ' + this.status, headers]; + + if (headers) { + ret.push(''); + } + + if (this.body) { + ret.push(this.body); + } + + return ret.join('\n'); +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/http/xhrclient.js b/node_modules/selenium-webdriver/lib/webdriver/http/xhrclient.js new file mode 100644 index 0000000..4f69fc3 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/http/xhrclient.js @@ -0,0 +1,64 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** @fileoverview A XHR client. */ + +goog.provide('webdriver.http.XhrClient'); + +goog.require('goog.json'); +goog.require('goog.net.XmlHttp'); +goog.require('webdriver.http.Response'); + + + +/** + * A HTTP client that sends requests using XMLHttpRequests. + * @param {string} url URL for the WebDriver server to send commands to. + * @constructor + * @implements {webdriver.http.Client} + */ +webdriver.http.XhrClient = function(url) { + + /** @private {string} */ + this.url_ = url; +}; + + +/** @override */ +webdriver.http.XhrClient.prototype.send = function(request, callback) { + try { + var xhr = /** @type {!XMLHttpRequest} */ (goog.net.XmlHttp()); + var url = this.url_ + request.path; + xhr.open(request.method, url, true); + + xhr.onload = function() { + callback(null, webdriver.http.Response.fromXmlHttpRequest(xhr)); + }; + + xhr.onerror = function() { + callback(Error([ + 'Unable to send request: ', request.method, ' ', url, + '\nOriginal request:\n', request + ].join(''))); + }; + + for (var header in request.headers) { + xhr.setRequestHeader(header, request.headers[header] + ''); + } + + xhr.send(goog.json.serialize(request.data)); + } catch (ex) { + callback(ex); + } +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/key.js b/node_modules/selenium-webdriver/lib/webdriver/key.js new file mode 100644 index 0000000..e231581 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/key.js @@ -0,0 +1,89 @@ +// Copyright 2012 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('webdriver.Key'); + + +/** + * Representations of pressable keys that aren't text. These are stored in + * the Unicode PUA (Private Use Area) code points, 0xE000-0xF8FF. Refer to + * http://www.google.com.au/search?&q=unicode+pua&btnG=Search + * + * @enum {string} + */ +webdriver.Key = { + NULL: '\uE000', + CANCEL: '\uE001', // ^break + HELP: '\uE002', + BACK_SPACE: '\uE003', + TAB: '\uE004', + CLEAR: '\uE005', + RETURN: '\uE006', + ENTER: '\uE007', + SHIFT: '\uE008', + CONTROL: '\uE009', + ALT: '\uE00A', + PAUSE: '\uE00B', + ESCAPE: '\uE00C', + SPACE: '\uE00D', + PAGE_UP: '\uE00E', + PAGE_DOWN: '\uE00F', + END: '\uE010', + HOME: '\uE011', + ARROW_LEFT: '\uE012', + LEFT: '\uE012', + ARROW_UP: '\uE013', + UP: '\uE013', + ARROW_RIGHT: '\uE014', + RIGHT: '\uE014', + ARROW_DOWN: '\uE015', + DOWN: '\uE015', + INSERT: '\uE016', + DELETE: '\uE017', + SEMICOLON: '\uE018', + EQUALS: '\uE019', + + NUMPAD0: '\uE01A', // number pad keys + NUMPAD1: '\uE01B', + NUMPAD2: '\uE01C', + NUMPAD3: '\uE01D', + NUMPAD4: '\uE01E', + NUMPAD5: '\uE01F', + NUMPAD6: '\uE020', + NUMPAD7: '\uE021', + NUMPAD8: '\uE022', + NUMPAD9: '\uE023', + MULTIPLY: '\uE024', + ADD: '\uE025', + SEPARATOR: '\uE026', + SUBTRACT: '\uE027', + DECIMAL: '\uE028', + DIVIDE: '\uE029', + + F1: '\uE031', // function keys + F2: '\uE032', + F3: '\uE033', + F4: '\uE034', + F5: '\uE035', + F6: '\uE036', + F7: '\uE037', + F8: '\uE038', + F9: '\uE039', + F10: '\uE03A', + F11: '\uE03B', + F12: '\uE03C', + + COMMAND: '\uE03D', // Apple command key + META: '\uE03D' // alias for Windows key +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/locators.js b/node_modules/selenium-webdriver/lib/webdriver/locators.js new file mode 100644 index 0000000..8d993d8 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/locators.js @@ -0,0 +1,253 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Factory methods for the supported locator strategies. + */ + +goog.provide('webdriver.By'); +goog.provide('webdriver.Locator'); +goog.provide('webdriver.Locator.Strategy'); + +goog.require('goog.array'); +goog.require('goog.object'); +goog.require('goog.string'); + + + +/** + * An element locator. + * @param {string} using The type of strategy to use for this locator. + * @param {string} value The search target of this locator. + * @constructor + */ +webdriver.Locator = function(using, value) { + + /** + * The search strategy to use when searching for an element. + * @type {string} + */ + this.using = using; + + /** + * The search target for this locator. + * @type {string} + */ + this.value = value; +}; + + +/** + * Creates a factory function for a {@link webdriver.Locator}. + * @param {string} type The type of locator for the factory. + * @return {function(string): !webdriver.Locator} The new factory function. + * @private + */ +webdriver.Locator.factory_ = function(type) { + return function(value) { + return new webdriver.Locator(type, value); + }; +}; + + +/** + * A collection of factory functions for creating {@link webdriver.Locator} + * instances. + */ +webdriver.By = {}; +// Exported to the global scope for legacy reasons. +goog.exportSymbol('By', webdriver.By); + + +/** + * Short-hand expressions for the primary element locator strategies. + * For example the following two statements are equivalent: + *
      + * var e1 = driver.findElement(webdriver.By.id('foo'));
      + * var e2 = driver.findElement({id: 'foo'});
      + * 
      + * + *

      Care should be taken when using JavaScript minifiers (such as the + * Closure compiler), as locator hashes will always be parsed using + * the un-obfuscated properties listed below. + * + * @typedef {( + * {className: string}| + * {css: string}| + * {id: string}| + * {js: string}| + * {linkText: string}| + * {name: string}| + * {partialLinkText: string}| + * {tagName: string}| + * {xpath: string})} + */ +webdriver.By.Hash; + + +/** + * Locates elements that have a specific class name. The returned locator + * is equivalent to searching for elements with the CSS selector ".clazz". + * + * @param {string} className The class name to search for. + * @return {!webdriver.Locator} The new locator. + * @see http://www.w3.org/TR/2011/WD-html5-20110525/elements.html#classes + * @see http://www.w3.org/TR/CSS2/selector.html#class-html + */ +webdriver.By.className = webdriver.Locator.factory_('class name'); + + +/** + * Locates elements using a CSS selector. For browsers that do not support + * CSS selectors, WebDriver implementations may return an + * {@link bot.Error.State.INVALID_SELECTOR invalid selector} error. An + * implementation may, however, emulate the CSS selector API. + * + * @param {string} selector The CSS selector to use. + * @return {!webdriver.Locator} The new locator. + * @see http://www.w3.org/TR/CSS2/selector.html + */ +webdriver.By.css = webdriver.Locator.factory_('css selector'); + + +/** + * Locates an element by its ID. + * + * @param {string} id The ID to search for. + * @return {!webdriver.Locator} The new locator. + */ +webdriver.By.id = webdriver.Locator.factory_('id'); + + +/** + * Locates link elements whose {@link webdriver.WebElement#getText visible + * text} matches the given string. + * + * @param {string} text The link text to search for. + * @return {!webdriver.Locator} The new locator. + */ +webdriver.By.linkText = webdriver.Locator.factory_('link text'); + + +/** + * Locates an elements by evaluating a + * {@link webdriver.WebDriver#executeScript JavaScript expression}. + * The result of this expression must be an element or list of elements. + * + * @param {!(string|Function)} script The script to execute. + * @param {...*} var_args The arguments to pass to the script. + * @return {function(!webdriver.WebDriver): !webdriver.promise.Promise} A new, + * JavaScript-based locator function. + */ +webdriver.By.js = function(script, var_args) { + var args = goog.array.slice(arguments, 0); + return function(driver) { + return driver.executeScript.apply(driver, args); + }; +}; + + +/** + * Locates elements whose {@code name} attribute has the given value. + * + * @param {string} name The name attribute to search for. + * @return {!webdriver.Locator} The new locator. + */ +webdriver.By.name = webdriver.Locator.factory_('name'); + + +/** + * Locates link elements whose {@link webdriver.WebElement#getText visible + * text} contains the given substring. + * + * @param {string} text The substring to check for in a link's visible text. + * @return {!webdriver.Locator} The new locator. + */ +webdriver.By.partialLinkText = webdriver.Locator.factory_( + 'partial link text'); + + +/** + * Locates elements with a given tag name. The returned locator is + * equivalent to using the {@code getElementsByTagName} DOM function. + * + * @param {string} text The substring to check for in a link's visible text. + * @return {!webdriver.Locator} The new locator. + * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html + */ +webdriver.By.tagName = webdriver.Locator.factory_('tag name'); + + +/** + * Locates elements matching a XPath selector. Care should be taken when + * using an XPath selector with a {@link webdriver.WebElement} as WebDriver + * will respect the context in the specified in the selector. For example, + * given the selector {@code "//div"}, WebDriver will search from the + * document root regardless of whether the locator was used with a + * WebElement. + * + * @param {string} xpath The XPath selector to use. + * @return {!webdriver.Locator} The new locator. + * @see http://www.w3.org/TR/xpath/ + */ +webdriver.By.xpath = webdriver.Locator.factory_('xpath'); + + +/** + * Maps {@link webdriver.By.Hash} keys to the appropriate factory function. + * @type {!Object.} + * @const + */ +webdriver.Locator.Strategy = { + 'className': webdriver.By.className, + 'css': webdriver.By.css, + 'id': webdriver.By.id, + 'js': webdriver.By.js, + 'linkText': webdriver.By.linkText, + 'name': webdriver.By.name, + 'partialLinkText': webdriver.By.partialLinkText, + 'tagName': webdriver.By.tagName, + 'xpath': webdriver.By.xpath +}; + + +/** + * Verifies that a {@code value} is a valid locator to use for searching for + * elements on the page. + * + * @param {*} value The value to check is a valid locator. + * @return {!(webdriver.Locator|Function)} A valid locator object or function. + * @throws {TypeError} If the given value is an invalid locator. + */ +webdriver.Locator.checkLocator = function(value) { + if (goog.isFunction(value) || value instanceof webdriver.Locator) { + return value; + } + for (var key in value) { + if (value.hasOwnProperty(key) && + webdriver.Locator.Strategy.hasOwnProperty(key)) { + return webdriver.Locator.Strategy[key](value[key]); + } + } + throw new TypeError('Invalid locator'); +}; + + + +/** @override */ +webdriver.Locator.prototype.toString = function() { + return 'By.' + this.using.replace(/ ([a-z])/g, function(all, match) { + return match.toUpperCase(); + }) + '(' + goog.string.quote(this.value) + ')'; +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/logging.js b/node_modules/selenium-webdriver/lib/webdriver/logging.js new file mode 100644 index 0000000..775f758 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/logging.js @@ -0,0 +1,158 @@ +// Copyright 2013 Selenium comitters +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('webdriver.logging'); +goog.provide('webdriver.logging.Preferences'); + +goog.require('goog.object'); + + +/** + * Log level names from WebDriver's JSON wire protocol. + * @enum {string} + */ +webdriver.logging.LevelName = { + ALL: 'ALL', + DEBUG: 'DEBUG', + INFO: 'INFO', + WARNING: 'WARNING', + SEVERE: 'SEVERE', + OFF: 'OFF' +}; + + +/** + * Logging levels. + * @enum {{value: number, name: webdriver.logging.LevelName}} + */ +webdriver.logging.Level = { + ALL: {value: Number.MIN_VALUE, name: webdriver.logging.LevelName.ALL}, + DEBUG: {value: 700, name: webdriver.logging.LevelName.DEBUG}, + INFO: {value: 800, name: webdriver.logging.LevelName.INFO}, + WARNING: {value: 900, name: webdriver.logging.LevelName.WARNING}, + SEVERE: {value: 1000, name: webdriver.logging.LevelName.SEVERE}, + OFF: {value: Number.MAX_VALUE, name: webdriver.logging.LevelName.OFF} +}; + + +/** + * Converts a level name or value to a {@link webdriver.logging.Level} value. + * If the name/value is not recognized, {@link webdriver.logging.Level.ALL} + * will be returned. + * @param {(number|string)} nameOrValue The log level name, or value, to + * convert . + * @return {!webdriver.logging.Level} The converted level. + */ +webdriver.logging.getLevel = function(nameOrValue) { + var predicate = goog.isString(nameOrValue) ? + function(val) { return val.name === nameOrValue; } : + function(val) { return val.value === nameOrValue; }; + + return goog.object.findValue(webdriver.logging.Level, predicate) || + webdriver.logging.Level.ALL; +}; + + +/** + * Common log types. + * @enum {string} + */ +webdriver.logging.Type = { + /** Logs originating from the browser. */ + BROWSER: 'browser', + /** Logs from a WebDriver client. */ + CLIENT: 'client', + /** Logs from a WebDriver implementation. */ + DRIVER: 'driver', + /** Logs related to performance. */ + PERFORMANCE: 'performance', + /** Logs from the remote server. */ + SERVER: 'server' +}; + + +/** + * A hash describing log preferences. + * @typedef {Object.} + */ +webdriver.logging.Preferences; + + +/** + * A single log entry. + * @param {(!webdriver.logging.Level|string)} level The entry level. + * @param {string} message The log message. + * @param {number=} opt_timestamp The time this entry was generated, in + * milliseconds since 0:00:00, January 1, 1970 UTC. If omitted, the + * current time will be used. + * @param {string=} opt_type The log type, if known. + * @constructor + */ +webdriver.logging.Entry = function(level, message, opt_timestamp, opt_type) { + + /** @type {!webdriver.logging.Level} */ + this.level = + goog.isString(level) ? webdriver.logging.getLevel(level) : level; + + /** @type {string} */ + this.message = message; + + /** @type {number} */ + this.timestamp = goog.isNumber(opt_timestamp) ? opt_timestamp : goog.now(); + + /** @type {string} */ + this.type = opt_type || ''; +}; + + +/** + * @return {{level: string, message: string, timestamp: number, + * type: string}} The JSON representation of this entry. + */ +webdriver.logging.Entry.prototype.toJSON = function() { + return { + 'level': this.level.name, + 'message': this.message, + 'timestamp': this.timestamp, + 'type': this.type + }; +}; + + +/** + * Converts a {@link goog.debug.LogRecord} into a + * {@link webdriver.logging.Entry}. + * @param {!goog.debug.LogRecord} logRecord The record to convert. + * @param {string=} opt_type The log type. + * @return {!webdriver.logging.Entry} The converted entry. + */ +webdriver.logging.Entry.fromClosureLogRecord = function(logRecord, opt_type) { + var closureLevel = logRecord.getLevel(); + var level = webdriver.logging.Level.SEVERE; + + if (closureLevel.value <= webdriver.logging.Level.DEBUG.value) { + level = webdriver.logging.Level.DEBUG; + } else if (closureLevel.value <= webdriver.logging.Level.INFO.value) { + level = webdriver.logging.Level.INFO; + } else if (closureLevel.value <= webdriver.logging.Level.WARNING.value) { + level = webdriver.logging.Level.WARNING; + } + + return new webdriver.logging.Entry( + level, + '[' + logRecord.getLoggerName() + '] ' + logRecord.getMessage(), + logRecord.getMillis(), + opt_type); +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/process.js b/node_modules/selenium-webdriver/lib/webdriver/process.js new file mode 100644 index 0000000..ec483d5 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/process.js @@ -0,0 +1,120 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Provides access to the current process' environment variables. + * When running in node, this is simply a wrapper for {@code process.env}. + * When running in a browser, environment variables are loaded by parsing the + * current URL's query string. Variables that have more than one variable will + * be initialized to the JSON representation of the array of all values, + * otherwise the variable will be initialized to a sole string value. If a + * variable does not have any values, but is nonetheless present in the query + * string, it will be initialized to an empty string. + * After the initial parsing, environment variables must be queried and set + * through the API defined in this file. + */ + +goog.provide('webdriver.process'); + +goog.require('goog.Uri'); +goog.require('goog.array'); +goog.require('goog.json'); + + +/** + * @return {boolean} Whether the current process is Node's native process + * object. + */ +webdriver.process.isNative = function() { + return webdriver.process.IS_NATIVE_PROCESS_; +}; + + +/** + * Queries for a named environment variable. + * @param {string} name The name of the environment variable to look up. + * @param {string=} opt_default The default value if the named variable is not + * defined. + * @return {string} The queried environment variable. + */ +webdriver.process.getEnv = function(name, opt_default) { + var value = webdriver.process.PROCESS_.env[name]; + return goog.isDefAndNotNull(value) ? value : opt_default; +}; + + +/** + * Sets an environment value. If the new value is either null or undefined, the + * environment variable will be cleared. + * @param {string} name The value to set. + * @param {*} value The new value; will be coerced to a string. + */ +webdriver.process.setEnv = function(name, value) { + webdriver.process.PROCESS_.env[name] = + goog.isDefAndNotNull(value) ? value + '' : null; +}; + + +/** + * Whether the current environment is using Node's native process object. + * @private {boolean} + * @const + */ +webdriver.process.IS_NATIVE_PROCESS_ = typeof process !== 'undefined'; + + +/** + * Initializes a process object for use in a browser window. + * @param {!Window=} opt_window The window object to initialize the process + * from; if not specified, will default to the current window. Should only + * be set for unit testing. + * @return {!Object} The new process object. + * @private + */ +webdriver.process.initBrowserProcess_ = function(opt_window) { + var process = {'env': {}}; + + var win = opt_window; + if (!win && typeof window != 'undefined') { + win = window; + } + + // Initialize the global error handler. + if (win) { + // Initialize the environment variable map by parsing the current URL query + // string. + if (win.location) { + var data = new goog.Uri(win.location).getQueryData(); + goog.array.forEach(data.getKeys(), function(key) { + var values = data.getValues(key); + process.env[key] = values.length == 0 ? '' : + values.length == 1 ? values[0] : + goog.json.serialize(values); + }); + } + } + + return process; +}; + + +/** + * The global process object to use. Will either be Node's global + * {@code process} object, or an approximation of it for use in a browser + * environment. + * @private {!Object} + * @const + */ +webdriver.process.PROCESS_ = webdriver.process.IS_NATIVE_PROCESS_ ? process : + webdriver.process.initBrowserProcess_(); diff --git a/node_modules/selenium-webdriver/lib/webdriver/promise.js b/node_modules/selenium-webdriver/lib/webdriver/promise.js new file mode 100644 index 0000000..c765caf --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/promise.js @@ -0,0 +1,2057 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @license Portions of this code are from the Dojo toolkit, received under the + * BSD License: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the Dojo Foundation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @fileoverview A promise implementation based on the CommonJS promise/A and + * promise/B proposals. For more information, see + * http://wiki.commonjs.org/wiki/Promises. + */ + +goog.provide('webdriver.promise'); +goog.provide('webdriver.promise.ControlFlow'); +goog.provide('webdriver.promise.ControlFlow.Timer'); +goog.provide('webdriver.promise.Deferred'); +goog.provide('webdriver.promise.Promise'); + +goog.require('goog.array'); +goog.require('goog.debug.Error'); +goog.require('goog.object'); +goog.require('webdriver.EventEmitter'); +goog.require('webdriver.stacktrace.Snapshot'); + + + +/** + * Represents the eventual value of a completed operation. Each promise may be + * in one of three states: pending, resolved, or rejected. Each promise starts + * in the pending state and may make a single transition to either a + * fulfilled or failed state. + * + *

      This class is based on the Promise/A proposal from CommonJS. Additional + * functions are provided for API compatibility with Dojo Deferred objects. + * + * @constructor + * @template T + * @see http://wiki.commonjs.org/wiki/Promises/A + */ +webdriver.promise.Promise = function() { +}; + + +/** + * Cancels the computation of this promise's value, rejecting the promise in the + * process. + * @param {*} reason The reason this promise is being cancelled. If not an + * {@code Error}, one will be created using the value's string + * representation. + */ +webdriver.promise.Promise.prototype.cancel = function(reason) { + throw new TypeError('Unimplemented function: "cancel"'); +}; + + +/** @return {boolean} Whether this promise's value is still being computed. */ +webdriver.promise.Promise.prototype.isPending = function() { + throw new TypeError('Unimplemented function: "isPending"'); +}; + + +/** + * Registers listeners for when this instance is resolved. This function most + * overridden by subtypes. + * + * @param {?(function(T): (R|webdriver.promise.Promise.))=} opt_callback The + * function to call if this promise is successfully resolved. The function + * should expect a single argument: the promise's resolved value. + * @param {?(function(*): (R|webdriver.promise.Promise.))=} opt_errback The + * function to call if this promise is rejected. The function should expect + * a single argument: the rejection reason. + * @return {!webdriver.promise.Promise.} A new promise which will be + * resolved with the result of the invoked callback. + * @template R + */ +webdriver.promise.Promise.prototype.then = function( + opt_callback, opt_errback) { + throw new TypeError('Unimplemented function: "then"'); +}; + + +/** + * Registers a listener for when this promise is rejected. This is synonymous + * with the {@code catch} clause in a synchronous API: + *

      
      + *   // Synchronous API:
      + *   try {
      + *     doSynchronousWork();
      + *   } catch (ex) {
      + *     console.error(ex);
      + *   }
      + *
      + *   // Asynchronous promise API:
      + *   doAsynchronousWork().thenCatch(function(ex) {
      + *     console.error(ex);
      + *   });
      + * 
      + * + * @param {function(*): (R|webdriver.promise.Promise.)} errback The function + * to call if this promise is rejected. The function should expect a single + * argument: the rejection reason. + * @return {!webdriver.promise.Promise.} A new promise which will be + * resolved with the result of the invoked callback. + * @template R + */ +webdriver.promise.Promise.prototype.thenCatch = function(errback) { + return this.then(null, errback); +}; + + +/** + * Registers a listener to invoke when this promise is resolved, regardless + * of whether the promise's value was successfully computed. This function + * is synonymous with the {@code finally} clause in a synchronous API: + *
      
      + *   // Synchronous API:
      + *   try {
      + *     doSynchronousWork();
      + *   } finally {
      + *     cleanUp();
      + *   }
      + *
      + *   // Asynchronous promise API:
      + *   doAsynchronousWork().thenFinally(cleanUp);
      + * 
      + * + * Note: similar to the {@code finally} clause, if the registered + * callback returns a rejected promise or throws an error, it will silently + * replace the rejection error (if any) from this promise: + *
      
      + *   try {
      + *     throw Error('one');
      + *   } finally {
      + *     throw Error('two');  // Hides Error: one
      + *   }
      + *
      + *   webdriver.promise.rejected(Error('one'))
      + *       .thenFinally(function() {
      + *         throw Error('two');  // Hides Error: one
      + *       });
      + * 
      + * + * + * @param {function(): (R|webdriver.promise.Promise.)} callback The function + * to call when this promise is resolved. + * @return {!webdriver.promise.Promise.} A promise that will be fulfilled + * with the callback result. + * @template R + */ +webdriver.promise.Promise.prototype.thenFinally = function(callback) { + return this.then(callback, function(err) { + var value = callback(); + if (webdriver.promise.isPromise(value)) { + return value.then(function() { + throw err; + }); + } + throw err; + }); +}; + + + +/** + * Represents a value that will be resolved at some point in the future. This + * class represents the protected "producer" half of a Promise - each Deferred + * has a {@code promise} property that may be returned to consumers for + * registering callbacks, reserving the ability to resolve the deferred to the + * producer. + * + *

      If this Deferred is rejected and there are no listeners registered before + * the next turn of the event loop, the rejection will be passed to the + * {@link webdriver.promise.ControlFlow} as an unhandled failure. + * + *

      If this Deferred is cancelled, the cancellation reason will be forward to + * the Deferred's canceller function (if provided). The canceller may return a + * truth-y value to override the reason provided for rejection. + * + * @param {Function=} opt_canceller Function to call when cancelling the + * computation of this instance's value. + * @param {webdriver.promise.ControlFlow=} opt_flow The control flow + * this instance was created under. This should only be provided during + * unit tests. + * @constructor + * @extends {webdriver.promise.Promise.} + * @template T + */ +webdriver.promise.Deferred = function(opt_canceller, opt_flow) { + /* NOTE: This class's implementation diverges from the prototypical style + * used in the rest of the atoms library. This was done intentionally to + * protect the internal Deferred state from consumers, as outlined by + * http://wiki.commonjs.org/wiki/Promises + */ + goog.base(this); + + var flow = opt_flow || webdriver.promise.controlFlow(); + + /** + * The listeners registered with this Deferred. Each element in the list will + * be a 3-tuple of the callback function, errback function, and the + * corresponding deferred object. + * @type {!Array.} + */ + var listeners = []; + + /** + * Whether this Deferred's resolution was ever handled by a listener. + * If the Deferred is rejected and its value is not handled by a listener + * before the next turn of the event loop, the error will be passed to the + * global error handler. + * @type {boolean} + */ + var handled = false; + + /** + * Key for the timeout used to delay reproting an unhandled rejection to the + * parent {@link webdriver.promise.ControlFlow}. + * @type {?number} + */ + var pendingRejectionKey = null; + + /** + * This Deferred's current state. + * @type {!webdriver.promise.Deferred.State_} + */ + var state = webdriver.promise.Deferred.State_.PENDING; + + /** + * This Deferred's resolved value; set when the state transitions from + * {@code webdriver.promise.Deferred.State_.PENDING}. + * @type {*} + */ + var value; + + /** @return {boolean} Whether this promise's value is still pending. */ + function isPending() { + return state == webdriver.promise.Deferred.State_.PENDING; + } + + /** + * Removes all of the listeners previously registered on this deferred. + * @throws {Error} If this deferred has already been resolved. + */ + function removeAll() { + listeners = []; + } + + /** + * Resolves this deferred. If the new value is a promise, this function will + * wait for it to be resolved before notifying the registered listeners. + * @param {!webdriver.promise.Deferred.State_} newState The deferred's new + * state. + * @param {*} newValue The deferred's new value. + */ + function resolve(newState, newValue) { + if (webdriver.promise.Deferred.State_.PENDING !== state) { + return; + } + + state = webdriver.promise.Deferred.State_.BLOCKED; + + if (webdriver.promise.isPromise(newValue) && newValue !== self) { + var onFulfill = goog.partial(notifyAll, newState); + var onReject = goog.partial( + notifyAll, webdriver.promise.Deferred.State_.REJECTED); + if (newValue instanceof webdriver.promise.Deferred) { + newValue.then(onFulfill, onReject); + } else { + webdriver.promise.asap(newValue, onFulfill, onReject); + } + + } else { + notifyAll(newState, newValue); + } + } + + /** + * Notifies all of the listeners registered with this Deferred that its state + * has changed. + * @param {!webdriver.promise.Deferred.State_} newState The deferred's new + * state. + * @param {*} newValue The deferred's new value. + */ + function notifyAll(newState, newValue) { + if (newState === webdriver.promise.Deferred.State_.REJECTED && + // We cannot check instanceof Error since the object may have been + // created in a different JS context. + goog.isObject(newValue) && goog.isString(newValue.message)) { + newValue = flow.annotateError(/** @type {!Error} */(newValue)); + } + + state = newState; + value = newValue; + while (listeners.length) { + notify(listeners.shift()); + } + + if (!handled && state == webdriver.promise.Deferred.State_.REJECTED) { + pendingRejectionKey = propagateError(value); + } + } + + /** + * Propagates an unhandled rejection to the parent ControlFlow in a + * future turn of the JavaScript event loop. + * @param {*} error The error value to report. + * @return {number} The key for the registered timeout. + */ + function propagateError(error) { + flow.pendingRejections_ += 1; + return flow.timer.setTimeout(function() { + flow.pendingRejections_ -= 1; + flow.abortFrame_(error); + }, 0); + } + + /** + * Notifies a single listener of this Deferred's change in state. + * @param {!webdriver.promise.Deferred.Listener_} listener The listener to + * notify. + */ + function notify(listener) { + var func = state == webdriver.promise.Deferred.State_.RESOLVED ? + listener.callback : listener.errback; + if (func) { + flow.runInNewFrame_(goog.partial(func, value), + listener.fulfill, listener.reject); + } else if (state == webdriver.promise.Deferred.State_.REJECTED) { + listener.reject(value); + } else { + listener.fulfill(value); + } + } + + /** + * The consumer promise for this instance. Provides protected access to the + * callback registering functions. + * @type {!webdriver.promise.Promise.} + */ + var promise = new webdriver.promise.Promise(); + + /** + * Registers a callback on this Deferred. + * + * @param {?(function(T): (R|webdriver.promise.Promise.))=} opt_callback . + * @param {?(function(*): (R|webdriver.promise.Promise.))=} opt_errback . + * @return {!webdriver.promise.Promise.} A new promise representing the + * result of the callback. + * @template R + * @see webdriver.promise.Promise#then + */ + function then(opt_callback, opt_errback) { + // Avoid unnecessary allocations if we weren't given any callback functions. + if (!opt_callback && !opt_errback) { + return promise; + } + + // The moment a listener is registered, we consider this deferred to be + // handled; the callback must handle any rejection errors. + handled = true; + if (pendingRejectionKey) { + flow.pendingRejections_ -= 1; + flow.timer.clearTimeout(pendingRejectionKey); + } + + var deferred = new webdriver.promise.Deferred(cancel, flow); + var listener = { + callback: opt_callback, + errback: opt_errback, + fulfill: deferred.fulfill, + reject: deferred.reject + }; + + if (state == webdriver.promise.Deferred.State_.PENDING || + state == webdriver.promise.Deferred.State_.BLOCKED) { + listeners.push(listener); + } else { + notify(listener); + } + + return deferred.promise; + } + + var self = this; + + /** + * Resolves this promise with the given value. If the value is itself a + * promise and not a reference to this deferred, this instance will wait for + * it before resolving. + * @param {T=} opt_value The fulfilled value. + */ + function fulfill(opt_value) { + resolve(webdriver.promise.Deferred.State_.RESOLVED, opt_value); + } + + /** + * Rejects this promise. If the error is itself a promise, this instance will + * be chained to it and be rejected with the error's resolved value. + * @param {*=} opt_error The rejection reason, typically either a + * {@code Error} or a {@code string}. + */ + function reject(opt_error) { + resolve(webdriver.promise.Deferred.State_.REJECTED, opt_error); + } + + /** + * Attempts to cancel the computation of this instance's value. This attempt + * will silently fail if this instance has already resolved. + * @param {*=} opt_reason The reason for cancelling this promise. + */ + function cancel(opt_reason) { + if (!isPending()) { + return; + } + + if (opt_canceller) { + opt_reason = opt_canceller(opt_reason) || opt_reason; + } + + reject(opt_reason); + } + + this.promise = promise; + this.promise.then = this.then = then; + this.promise.cancel = this.cancel = cancel; + this.promise.isPending = this.isPending = isPending; + this.fulfill = fulfill; + this.reject = this.errback = reject; + + // Only expose this function to our internal classes. + // TODO: find a cleaner way of handling this. + if (this instanceof webdriver.promise.Task_) { + this.removeAll = removeAll; + } + + // Export symbols necessary for the contract on this object to work in + // compiled mode. + goog.exportProperty(this, 'then', this.then); + goog.exportProperty(this, 'cancel', cancel); + goog.exportProperty(this, 'fulfill', fulfill); + goog.exportProperty(this, 'reject', reject); + goog.exportProperty(this, 'isPending', isPending); + goog.exportProperty(this, 'promise', this.promise); + goog.exportProperty(this.promise, 'then', this.then); + goog.exportProperty(this.promise, 'cancel', cancel); + goog.exportProperty(this.promise, 'isPending', isPending); +}; +goog.inherits(webdriver.promise.Deferred, webdriver.promise.Promise); + + +/** + * Type definition for a listener registered on a Deferred object. + * @typedef {{callback:(Function|undefined), + * errback:(Function|undefined), + * fulfill: function(*), reject: function(*)}} + * @private + */ +webdriver.promise.Deferred.Listener_; + + +/** + * The three states a {@link webdriver.promise.Deferred} object may be in. + * @enum {number} + * @private + */ +webdriver.promise.Deferred.State_ = { + REJECTED: -1, + PENDING: 0, + BLOCKED: 1, + RESOLVED: 2 +}; + + +/** + * Tests if a value is an Error-like object. This is more than an straight + * instanceof check since the value may originate from another context. + * @param {*} value The value to test. + * @return {boolean} Whether the value is an error. + * @private + */ +webdriver.promise.isError_ = function(value) { + return value instanceof Error || + goog.isObject(value) && + (Object.prototype.toString.call(value) === '[object Error]' || + // A special test for goog.testing.JsUnitException. + value.isJsUnitException); + +}; + + +/** + * Determines whether a {@code value} should be treated as a promise. + * Any object whose "then" property is a function will be considered a promise. + * + * @param {*} value The value to test. + * @return {boolean} Whether the value is a promise. + */ +webdriver.promise.isPromise = function(value) { + return !!value && goog.isObject(value) && + // Use array notation so the Closure compiler does not obfuscate away our + // contract. + goog.isFunction(value['then']); +}; + + +/** + * Creates a promise that will be resolved at a set time in the future. + * @param {number} ms The amount of time, in milliseconds, to wait before + * resolving the promise. + * @return {!webdriver.promise.Promise} The promise. + */ +webdriver.promise.delayed = function(ms) { + var timer = webdriver.promise.controlFlow().timer; + var key; + var deferred = new webdriver.promise.Deferred(function() { + timer.clearTimeout(key); + }); + key = timer.setTimeout(deferred.fulfill, ms); + return deferred.promise; +}; + + +/** + * Creates a new deferred object. + * @param {Function=} opt_canceller Function to call when cancelling the + * computation of this instance's value. + * @return {!webdriver.promise.Deferred.} The new deferred object. + * @template T + */ +webdriver.promise.defer = function(opt_canceller) { + return new webdriver.promise.Deferred(opt_canceller); +}; + + +/** + * Creates a promise that has been resolved with the given value. + * @param {T=} opt_value The resolved value. + * @return {!webdriver.promise.Promise.} The resolved promise. + * @template T + */ +webdriver.promise.fulfilled = function(opt_value) { + if (opt_value instanceof webdriver.promise.Promise) { + return opt_value; + } + var deferred = new webdriver.promise.Deferred(); + deferred.fulfill(opt_value); + return deferred.promise; +}; + + +/** + * Creates a promise that has been rejected with the given reason. + * @param {*=} opt_reason The rejection reason; may be any value, but is + * usually an Error or a string. + * @return {!webdriver.promise.Promise.} The rejected promise. + * @template T + */ +webdriver.promise.rejected = function(opt_reason) { + var deferred = new webdriver.promise.Deferred(); + deferred.reject(opt_reason); + return deferred.promise; +}; + + +/** + * Wraps a function that is assumed to be a node-style callback as its final + * argument. This callback takes two arguments: an error value (which will be + * null if the call succeeded), and the success value as the second argument. + * If the call fails, the returned promise will be rejected, otherwise it will + * be resolved with the result. + * @param {!Function} fn The function to wrap. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * result of the provided function's callback. + */ +webdriver.promise.checkedNodeCall = function(fn) { + var deferred = new webdriver.promise.Deferred(function() { + throw Error('This Deferred may not be cancelled'); + }); + try { + fn(function(error, value) { + error ? deferred.reject(error) : deferred.fulfill(value); + }); + } catch (ex) { + deferred.reject(ex); + } + return deferred.promise; +}; + + +/** + * Registers an observer on a promised {@code value}, returning a new promise + * that will be resolved when the value is. If {@code value} is not a promise, + * then the return promise will be immediately resolved. + * @param {*} value The value to observe. + * @param {Function=} opt_callback The function to call when the value is + * resolved successfully. + * @param {Function=} opt_errback The function to call when the value is + * rejected. + * @return {!webdriver.promise.Promise} A new promise. + */ +webdriver.promise.when = function(value, opt_callback, opt_errback) { + if (value instanceof webdriver.promise.Promise) { + return value.then(opt_callback, opt_errback); + } + + var deferred = new webdriver.promise.Deferred(); + + webdriver.promise.asap(value, deferred.fulfill, deferred.reject); + + return deferred.then(opt_callback, opt_errback); +}; + + +/** + * Invokes the appropriate callback function as soon as a promised + * {@code value} is resolved. This function is similar to + * {@link webdriver.promise.when}, except it does not return a new promise. + * @param {*} value The value to observe. + * @param {Function} callback The function to call when the value is + * resolved successfully. + * @param {Function=} opt_errback The function to call when the value is + * rejected. + */ +webdriver.promise.asap = function(value, callback, opt_errback) { + if (webdriver.promise.isPromise(value)) { + value.then(callback, opt_errback); + + // Maybe a Dojo-like deferred object? + } else if (!!value && goog.isObject(value) && + goog.isFunction(value.addCallbacks)) { + value.addCallbacks(callback, opt_errback); + + // A raw value, return a resolved promise. + } else if (callback) { + callback(value); + } +}; + + +/** + * Given an array of promises, will return a promise that will be fulfilled + * with the fulfillment values of the input array's values. If any of the + * input array's promises are rejected, the returned promise will be rejected + * with the same reason. + * + * @param {!Array.<(T|!webdriver.promise.Promise.)>} arr An array of + * promises to wait on. + * @return {!webdriver.promise.Promise.>} A promise that is + * fulfilled with an array containing the fulfilled values of the + * input array, or rejected with the same reason as the first + * rejected value. + * @template T + */ +webdriver.promise.all = function(arr) { + var n = arr.length; + if (!n) { + return webdriver.promise.fulfilled([]); + } + + var toFulfill = n; + var result = webdriver.promise.defer(); + var values = []; + + var onFulfill = function(index, value) { + values[index] = value; + toFulfill--; + if (toFulfill == 0) { + result.fulfill(values); + } + }; + + for (var i = 0; i < n; ++i) { + webdriver.promise.asap( + arr[i], goog.partial(onFulfill, i), result.reject); + } + + return result.promise; +}; + + +/** + * Calls a function for each element in an array and inserts the result into a + * new array, which is used as the fulfillment value of the promise returned + * by this function. + * + *

      If the return value of the mapping function is a promise, this function + * will wait for it to be fulfilled before inserting it into the new array. + * + *

      If the mapping function throws or returns a rejected promise, the + * promise returned by this function will be rejected with the same reason. + * Only the first failure will be reported; all subsequent errors will be + * silently ignored. + * + * @param {!(Array.|webdriver.promise.Promise.>)} arr The + * array to iterator over, or a promise that will resolve to said array. + * @param {function(this: SELF, TYPE, number, !Array.): ?} fn The + * function to call for each element in the array. This function should + * expect three arguments (the element, the index, and the array itself. + * @param {SELF=} opt_self The object to be used as the value of 'this' within + * {@code fn}. + * @template TYPE, SELF + */ +webdriver.promise.map = function(arr, fn, opt_self) { + return webdriver.promise.when(arr, function(arr) { + var result = goog.array.map(arr, fn, opt_self); + return webdriver.promise.all(result); + }); +}; + + +/** + * Calls a function for each element in an array, and if the function returns + * true adds the element to a new array. + * + *

      If the return value of the filter function is a promise, this function + * will wait for it to be fulfilled before determining whether to insert the + * element into the new array. + * + *

      If the filter function throws or returns a rejected promise, the promise + * returned by this function will be rejected with the same reason. Only the + * first failure will be reported; all subsequent errors will be silently + * ignored. + * + * @param {!(Array.|webdriver.promise.Promise.>)} arr The + * array to iterator over, or a promise that will resolve to said array. + * @param {function(this: SELF, TYPE, number, !Array.): ( + * boolean|webdriver.promise.Promise.)} fn The function + * to call for each element in the array. + * @param {SELF=} opt_self The object to be used as the value of 'this' within + * {@code fn}. + * @template TYPE, SELF + */ +webdriver.promise.filter = function(arr, fn, opt_self) { + return webdriver.promise.when(arr, function(arr) { + var originalValues = goog.array.clone(arr); + return webdriver.promise.map(arr, fn, opt_self).then(function(include) { + return goog.array.filter(originalValues, function(value, index) { + return include[index]; + }); + }); + }); +}; + + +/** + * Returns a promise that will be resolved with the input value in a + * fully-resolved state. If the value is an array, each element will be fully + * resolved. Likewise, if the value is an object, all keys will be fully + * resolved. In both cases, all nested arrays and objects will also be + * fully resolved. All fields are resolved in place; the returned promise will + * resolve on {@code value} and not a copy. + * + * Warning: This function makes no checks against objects that contain + * cyclical references: + *

      
      + *   var value = {};
      + *   value['self'] = value;
      + *   webdriver.promise.fullyResolved(value);  // Stack overflow.
      + * 
      + * + * @param {*} value The value to fully resolve. + * @return {!webdriver.promise.Promise} A promise for a fully resolved version + * of the input value. + */ +webdriver.promise.fullyResolved = function(value) { + if (webdriver.promise.isPromise(value)) { + return webdriver.promise.when(value, webdriver.promise.fullyResolveValue_); + } + return webdriver.promise.fullyResolveValue_(value); +}; + + +/** + * @param {*} value The value to fully resolve. If a promise, assumed to + * already be resolved. + * @return {!webdriver.promise.Promise} A promise for a fully resolved version + * of the input value. + * @private + */ +webdriver.promise.fullyResolveValue_ = function(value) { + switch (goog.typeOf(value)) { + case 'array': + return webdriver.promise.fullyResolveKeys_( + /** @type {!Array} */ (value)); + + case 'object': + if (webdriver.promise.isPromise(value)) { + // We get here when the original input value is a promise that + // resolves to itself. When the user provides us with such a promise, + // trust that it counts as a "fully resolved" value and return it. + // Of course, since it's already a promise, we can just return it + // to the user instead of wrapping it in another promise. + return /** @type {!webdriver.promise.Promise} */ (value); + } + + if (goog.isNumber(value.nodeType) && + goog.isObject(value.ownerDocument) && + goog.isNumber(value.ownerDocument.nodeType)) { + // DOM node; return early to avoid infinite recursion. Should we + // only support objects with a certain level of nesting? + return webdriver.promise.fulfilled(value); + } + + return webdriver.promise.fullyResolveKeys_( + /** @type {!Object} */ (value)); + + default: // boolean, function, null, number, string, undefined + return webdriver.promise.fulfilled(value); + } +}; + + +/** + * @param {!(Array|Object)} obj the object to resolve. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * input object once all of its values have been fully resolved. + * @private + */ +webdriver.promise.fullyResolveKeys_ = function(obj) { + var isArray = goog.isArray(obj); + var numKeys = isArray ? obj.length : goog.object.getCount(obj); + if (!numKeys) { + return webdriver.promise.fulfilled(obj); + } + + var numResolved = 0; + var deferred = new webdriver.promise.Deferred(); + + // In pre-IE9, goog.array.forEach will not iterate properly over arrays + // containing undefined values because "index in array" returns false + // when array[index] === undefined (even for x = [undefined, 1]). To get + // around this, we need to use our own forEach implementation. + // DO NOT REMOVE THIS UNTIL WE NO LONGER SUPPORT IE8. This cannot be + // reproduced in IE9 by changing the browser/document modes, it requires an + // actual pre-IE9 browser. Yay, IE! + var forEachKey = !isArray ? goog.object.forEach : function(arr, fn) { + var n = arr.length; + for (var i = 0; i < n; ++i) { + fn.call(null, arr[i], i, arr); + } + }; + + forEachKey(obj, function(partialValue, key) { + var type = goog.typeOf(partialValue); + if (type != 'array' && type != 'object') { + maybeResolveValue(); + return; + } + + webdriver.promise.fullyResolved(partialValue).then( + function(resolvedValue) { + obj[key] = resolvedValue; + maybeResolveValue(); + }, + deferred.reject); + }); + + return deferred.promise; + + function maybeResolveValue() { + if (++numResolved == numKeys) { + deferred.fulfill(obj); + } + } +}; + + +////////////////////////////////////////////////////////////////////////////// +// +// webdriver.promise.ControlFlow +// +////////////////////////////////////////////////////////////////////////////// + + + +/** + * Handles the execution of scheduled tasks, each of which may be an + * asynchronous operation. The control flow will ensure tasks are executed in + * the ordered scheduled, starting each task only once those before it have + * completed. + * + *

      Each task scheduled within this flow may return a + * {@link webdriver.promise.Promise} to indicate it is an asynchronous + * operation. The ControlFlow will wait for such promises to be resolved before + * marking the task as completed. + * + *

      Tasks and each callback registered on a {@link webdriver.promise.Deferred} + * will be run in their own ControlFlow frame. Any tasks scheduled within a + * frame will have priority over previously scheduled tasks. Furthermore, if + * any of the tasks in the frame fails, the remainder of the tasks in that frame + * will be discarded and the failure will be propagated to the user through the + * callback/task's promised result. + * + *

      Each time a ControlFlow empties its task queue, it will fire an + * {@link webdriver.promise.ControlFlow.EventType.IDLE} event. Conversely, + * whenever the flow terminates due to an unhandled error, it will remove all + * remaining tasks in its queue and fire an + * {@link webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION} event. If + * there are no listeners registered with the flow, the error will be + * rethrown to the global error handler. + * + * @param {webdriver.promise.ControlFlow.Timer=} opt_timer The timer object + * to use. Should only be set for testing. + * @constructor + * @extends {webdriver.EventEmitter} + */ +webdriver.promise.ControlFlow = function(opt_timer) { + webdriver.EventEmitter.call(this); + + /** + * The timer used by this instance. + * @type {webdriver.promise.ControlFlow.Timer} + */ + this.timer = opt_timer || webdriver.promise.ControlFlow.defaultTimer; + + /** + * A list of recent tasks. Each time a new task is started, or a frame is + * completed, the previously recorded task is removed from this list. If + * there are multiple tasks, task N+1 is considered a sub-task of task + * N. + * @private {!Array.} + */ + this.history_ = []; +}; +goog.inherits(webdriver.promise.ControlFlow, webdriver.EventEmitter); + + +/** + * @typedef {{clearInterval: function(number), + * clearTimeout: function(number), + * setInterval: function(!Function, number): number, + * setTimeout: function(!Function, number): number}} + */ +webdriver.promise.ControlFlow.Timer; + + +/** + * The default timer object, which uses the global timer functions. + * @type {webdriver.promise.ControlFlow.Timer} + */ +webdriver.promise.ControlFlow.defaultTimer = (function() { + // The default timer functions may be defined as free variables for the + // current context, so do not reference them using "window" or + // "goog.global". Also, we must invoke them in a closure, and not using + // bind(), so we do not get "TypeError: Illegal invocation" (WebKit) or + // "Invalid calling object" (IE) errors. + return { + clearInterval: wrap(clearInterval), + clearTimeout: wrap(clearTimeout), + setInterval: wrap(setInterval), + setTimeout: wrap(setTimeout) + }; + + function wrap(fn) { + return function() { + // Cannot use .call() or .apply() since we do not know which variable + // the function is bound to, and using the wrong one will generate + // an error. + return fn(arguments[0], arguments[1]); + }; + } +})(); + + +/** + * Events that may be emitted by an {@link webdriver.promise.ControlFlow}. + * @enum {string} + */ +webdriver.promise.ControlFlow.EventType = { + + /** Emitted when all tasks have been successfully executed. */ + IDLE: 'idle', + + /** Emitted whenever a new task has been scheduled. */ + SCHEDULE_TASK: 'scheduleTask', + + /** + * Emitted whenever a control flow aborts due to an unhandled promise + * rejection. This event will be emitted along with the offending rejection + * reason. Upon emitting this event, the control flow will empty its task + * queue and revert to its initial state. + */ + UNCAUGHT_EXCEPTION: 'uncaughtException' +}; + + +/** + * How often, in milliseconds, the event loop should run. + * @type {number} + * @const + */ +webdriver.promise.ControlFlow.EVENT_LOOP_FREQUENCY = 10; + + +/** + * Tracks the active execution frame for this instance. Lazily initialized + * when the first task is scheduled. + * @private {webdriver.promise.Frame_} + */ +webdriver.promise.ControlFlow.prototype.activeFrame_ = null; + + +/** + * A reference to the frame in which new tasks should be scheduled. If + * {@code null}, tasks will be scheduled within the active frame. When forcing + * a function to run in the context of a new frame, this pointer is used to + * ensure tasks are scheduled within the newly created frame, even though it + * won't be active yet. + * @private {webdriver.promise.Frame_} + * @see {#runInNewFrame_} + */ +webdriver.promise.ControlFlow.prototype.schedulingFrame_ = null; + + +/** + * Timeout ID set when the flow is about to shutdown without any errors + * being detected. Upon shutting down, the flow will emit an + * {@link webdriver.promise.ControlFlow.EventType.IDLE} event. Idle events + * always follow a brief timeout in order to catch latent errors from the last + * completed task. If this task had a callback registered, but no errback, and + * the task fails, the unhandled failure would not be reported by the promise + * system until the next turn of the event loop: + * + * // Schedule 1 task that fails. + * var result = webriver.promise.controlFlow().schedule('example', + * function() { return webdriver.promise.rejected('failed'); }); + * // Set a callback on the result. This delays reporting the unhandled + * // failure for 1 turn of the event loop. + * result.then(goog.nullFunction); + * + * @private {?number} + */ +webdriver.promise.ControlFlow.prototype.shutdownId_ = null; + + +/** + * Interval ID for this instance's event loop. + * @private {?number} + */ +webdriver.promise.ControlFlow.prototype.eventLoopId_ = null; + + +/** + * The number of "pending" promise rejections. + * + *

      Each time a promise is rejected and is not handled by a listener, it will + * schedule a 0-based timeout to check if it is still unrejected in the next + * turn of the JS-event loop. This allows listeners to attach to, and handle, + * the rejected promise at any point in same turn of the event loop that the + * promise was rejected. + * + *

      When this flow's own event loop triggers, it will not run if there + * are any outstanding promise rejections. This allows unhandled promises to + * be reported before a new task is started, ensuring the error is reported to + * the current task queue. + * + * @private {number} + */ +webdriver.promise.ControlFlow.prototype.pendingRejections_ = 0; + + +/** + * The number of aborted frames since the last time a task was executed or a + * frame completed successfully. + * @private {number} + */ +webdriver.promise.ControlFlow.prototype.numAbortedFrames_ = 0; + + +/** + * Resets this instance, clearing its queue and removing all event listeners. + */ +webdriver.promise.ControlFlow.prototype.reset = function() { + this.activeFrame_ = null; + this.clearHistory(); + this.removeAllListeners(); + this.cancelShutdown_(); + this.cancelEventLoop_(); +}; + + +/** + * Returns a summary of the recent task activity for this instance. This + * includes the most recently completed task, as well as any parent tasks. In + * the returned summary, the task at index N is considered a sub-task of the + * task at index N+1. + * @return {!Array.} A summary of this instance's recent task + * activity. + */ +webdriver.promise.ControlFlow.prototype.getHistory = function() { + var pendingTasks = []; + var currentFrame = this.activeFrame_; + while (currentFrame) { + var task = currentFrame.getPendingTask(); + if (task) { + pendingTasks.push(task); + } + // A frame's parent node will always be another frame. + currentFrame = + /** @type {webdriver.promise.Frame_} */ (currentFrame.getParent()); + } + + var fullHistory = goog.array.concat(this.history_, pendingTasks); + return goog.array.map(fullHistory, function(task) { + return task.toString(); + }); +}; + + +/** Clears this instance's task history. */ +webdriver.promise.ControlFlow.prototype.clearHistory = function() { + this.history_ = []; +}; + + +/** + * Removes a completed task from this instance's history record. If any + * tasks remain from aborted frames, those will be removed as well. + * @private + */ +webdriver.promise.ControlFlow.prototype.trimHistory_ = function() { + if (this.numAbortedFrames_) { + goog.array.splice(this.history_, + this.history_.length - this.numAbortedFrames_, + this.numAbortedFrames_); + this.numAbortedFrames_ = 0; + } + this.history_.pop(); +}; + + +/** + * Property used to track whether an error has been annotated by + * {@link webdriver.promise.ControlFlow#annotateError}. + * @private {string} + * @const + */ +webdriver.promise.ControlFlow.ANNOTATION_PROPERTY_ = + 'webdriver_promise_error_'; + + +/** + * Appends a summary of this instance's recent task history to the given + * error's stack trace. This function will also ensure the error's stack trace + * is in canonical form. + * @param {!(Error|goog.testing.JsUnitException)} e The error to annotate. + * @return {!(Error|goog.testing.JsUnitException)} The annotated error. + */ +webdriver.promise.ControlFlow.prototype.annotateError = function(e) { + if (!!e[webdriver.promise.ControlFlow.ANNOTATION_PROPERTY_]) { + return e; + } + + var history = this.getHistory(); + if (history.length) { + e = webdriver.stacktrace.format(e); + + /** @type {!Error} */(e).stack += [ + '\n==== async task ====\n', + history.join('\n==== async task ====\n') + ].join(''); + + e[webdriver.promise.ControlFlow.ANNOTATION_PROPERTY_] = true; + } + + return e; +}; + + +/** + * @return {string} The scheduled tasks still pending with this instance. + */ +webdriver.promise.ControlFlow.prototype.getSchedule = function() { + return this.activeFrame_ ? this.activeFrame_.getRoot().toString() : '[]'; +}; + + +/** + * Schedules a task for execution. If there is nothing currently in the + * queue, the task will be executed in the next turn of the event loop. + * + * @param {function(): (T|webdriver.promise.Promise.)} fn The function to + * call to start the task. If the function returns a + * {@link webdriver.promise.Promise}, this instance will wait for it to be + * resolved before starting the next task. + * @param {string=} opt_description A description of the task. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * with the result of the action. + * @template T + */ +webdriver.promise.ControlFlow.prototype.execute = function( + fn, opt_description) { + this.cancelShutdown_(); + + if (!this.activeFrame_) { + this.activeFrame_ = new webdriver.promise.Frame_(this); + } + + // Trim an extra frame off the generated stack trace for the call to this + // function. + var snapshot = new webdriver.stacktrace.Snapshot(1); + var task = new webdriver.promise.Task_( + this, fn, opt_description || '', snapshot); + var scheduleIn = this.schedulingFrame_ || this.activeFrame_; + scheduleIn.addChild(task); + + this.emit(webdriver.promise.ControlFlow.EventType.SCHEDULE_TASK, opt_description); + + this.scheduleEventLoopStart_(); + return task.promise; +}; + + +/** + * Inserts a {@code setTimeout} into the command queue. This is equivalent to + * a thread sleep in a synchronous programming language. + * + * @param {number} ms The timeout delay, in milliseconds. + * @param {string=} opt_description A description to accompany the timeout. + * @return {!webdriver.promise.Promise} A promise that will be resolved with + * the result of the action. + */ +webdriver.promise.ControlFlow.prototype.timeout = function( + ms, opt_description) { + return this.execute(function() { + return webdriver.promise.delayed(ms); + }, opt_description); +}; + + +/** + * Schedules a task that shall wait for a condition to hold. Each condition + * function may return any value, but it will always be evaluated as a boolean. + * + *

      Condition functions may schedule sub-tasks with this instance, however, + * their execution time will be factored into whether a wait has timed out. + * + *

      In the event a condition returns a Promise, the polling loop will wait for + * it to be resolved before evaluating whether the condition has been satisfied. + * The resolution time for a promise is factored into whether a wait has timed + * out. + * + *

      If the condition function throws, or returns a rejected promise, the + * wait task will fail. + * + * @param {!Function} condition The condition function to poll. + * @param {number} timeout How long to wait, in milliseconds, for the condition + * to hold before timing out. + * @param {string=} opt_message An optional error message to include if the + * wait times out; defaults to the empty string. + * @return {!webdriver.promise.Promise} A promise that will be resolved when the + * condition has been satisified. The promise shall be rejected if the wait + * times out waiting for the condition. + */ +webdriver.promise.ControlFlow.prototype.wait = function( + condition, timeout, opt_message) { + var sleep = Math.min(timeout, 100); + var self = this; + + return this.execute(function() { + var startTime = goog.now(); + var waitResult = new webdriver.promise.Deferred(); + var waitFrame = self.activeFrame_; + waitFrame.isWaiting = true; + pollCondition(); + return waitResult.promise; + + function pollCondition() { + self.runInNewFrame_(condition, function(value) { + var elapsed = goog.now() - startTime; + if (!!value) { + waitFrame.isWaiting = false; + waitResult.fulfill(value); + } else if (elapsed >= timeout) { + waitResult.reject(new Error((opt_message ? opt_message + '\n' : '') + + 'Wait timed out after ' + elapsed + 'ms')); + } else { + self.timer.setTimeout(pollCondition, sleep); + } + }, waitResult.reject, true); + } + }, opt_message); +}; + + +/** + * Schedules a task that will wait for another promise to resolve. The resolved + * promise's value will be returned as the task result. + * @param {!webdriver.promise.Promise} promise The promise to wait on. + * @return {!webdriver.promise.Promise} A promise that will resolve when the + * task has completed. + */ +webdriver.promise.ControlFlow.prototype.await = function(promise) { + return this.execute(function() { + return promise; + }); +}; + + +/** + * Schedules the interval for this instance's event loop, if necessary. + * @private + */ +webdriver.promise.ControlFlow.prototype.scheduleEventLoopStart_ = function() { + if (!this.eventLoopId_) { + this.eventLoopId_ = this.timer.setInterval( + goog.bind(this.runEventLoop_, this), + webdriver.promise.ControlFlow.EVENT_LOOP_FREQUENCY); + } +}; + + +/** + * Cancels the event loop, if necessary. + * @private + */ +webdriver.promise.ControlFlow.prototype.cancelEventLoop_ = function() { + if (this.eventLoopId_) { + this.timer.clearInterval(this.eventLoopId_); + this.eventLoopId_ = null; + } +}; + + +/** + * Executes the next task for the current frame. If the current frame has no + * more tasks, the frame's result will be resolved, returning control to the + * frame's creator. This will terminate the flow if the completed frame was at + * the top of the stack. + * @private + */ +webdriver.promise.ControlFlow.prototype.runEventLoop_ = function() { + // If we get here and there are pending promise rejections, then those + // promises are queued up to run as soon as this (JS) event loop terminates. + // Short-circuit our loop to give those promises a chance to run. Otherwise, + // we might start a new task only to have it fail because of one of these + // pending rejections. + if (this.pendingRejections_) { + return; + } + + // If the flow aborts due to an unhandled exception after we've scheduled + // another turn of the execution loop, we can end up in here with no tasks + // left. This is OK, just quietly return. + if (!this.activeFrame_) { + this.commenceShutdown_(); + return; + } + + var task; + if (this.activeFrame_.getPendingTask() || !(task = this.getNextTask_())) { + // Either the current frame is blocked on a pending task, or we don't have + // a task to finish because we've completed a frame. When completing a + // frame, we must abort the event loop to allow the frame's promise's + // callbacks to execute. + return; + } + + var activeFrame = this.activeFrame_; + activeFrame.setPendingTask(task); + var markTaskComplete = goog.bind(function() { + this.history_.push(/** @type {!webdriver.promise.Task_} */ (task)); + activeFrame.setPendingTask(null); + }, this); + + this.trimHistory_(); + var self = this; + this.runInNewFrame_(task.execute, function(result) { + markTaskComplete(); + task.fulfill(result); + }, function(error) { + markTaskComplete(); + + if (!webdriver.promise.isError_(error) && + !webdriver.promise.isPromise(error)) { + error = Error(error); + } + + task.reject(self.annotateError(/** @type {!Error} */ (error))); + }, true); +}; + + +/** + * @return {webdriver.promise.Task_} The next task to execute, or + * {@code null} if a frame was resolved. + * @private + */ +webdriver.promise.ControlFlow.prototype.getNextTask_ = function() { + var firstChild = this.activeFrame_.getFirstChild(); + if (!firstChild) { + if (!this.activeFrame_.isWaiting) { + this.resolveFrame_(this.activeFrame_); + } + return null; + } + + if (firstChild instanceof webdriver.promise.Frame_) { + this.activeFrame_ = firstChild; + return this.getNextTask_(); + } + + firstChild.getParent().removeChild(firstChild); + return firstChild; +}; + + +/** + * @param {!webdriver.promise.Frame_} frame The frame to resolve. + * @private + */ +webdriver.promise.ControlFlow.prototype.resolveFrame_ = function(frame) { + if (this.activeFrame_ === frame) { + // Frame parent is always another frame, but the compiler is not smart + // enough to recognize this. + this.activeFrame_ = + /** @type {webdriver.promise.Frame_} */ (frame.getParent()); + } + + if (frame.getParent()) { + frame.getParent().removeChild(frame); + } + this.trimHistory_(); + frame.fulfill(); + + if (!this.activeFrame_) { + this.commenceShutdown_(); + } +}; + + +/** + * Aborts the current frame. The frame, and all of the tasks scheduled within it + * will be discarded. If this instance does not have an active frame, it will + * immediately terminate all execution. + * @param {*} error The reason the frame is being aborted; typically either + * an Error or string. + * @private + */ +webdriver.promise.ControlFlow.prototype.abortFrame_ = function(error) { + // Annotate the error value if it is Error-like. + if (webdriver.promise.isError_(error)) { + this.annotateError(/** @type {!Error} */ (error)); + } + this.numAbortedFrames_++; + + if (!this.activeFrame_) { + this.abortNow_(error); + return; + } + + // Frame parent is always another frame, but the compiler is not smart + // enough to recognize this. + var parent = /** @type {webdriver.promise.Frame_} */ ( + this.activeFrame_.getParent()); + if (parent) { + parent.removeChild(this.activeFrame_); + } + + var frame = this.activeFrame_; + this.activeFrame_ = parent; + frame.reject(error); +}; + + +/** + * Executes a function in a new frame. If the function does not schedule any new + * tasks, the frame will be discarded and the function's result returned + * immediately. Otherwise, a promise will be returned. This promise will be + * resolved with the function's result once all of the tasks scheduled within + * the function have been completed. If the function's frame is aborted, the + * returned promise will be rejected. + * + * @param {!Function} fn The function to execute. + * @param {function(*)} callback The function to call with a successful result. + * @param {function(*)} errback The function to call if there is an error. + * @param {boolean=} opt_activate Whether the active frame should be updated to + * the newly created frame so tasks are treated as sub-tasks. + * @private + */ +webdriver.promise.ControlFlow.prototype.runInNewFrame_ = function( + fn, callback, errback, opt_activate) { + var newFrame = new webdriver.promise.Frame_(this), + self = this, + oldFrame = this.activeFrame_; + + try { + if (!this.activeFrame_) { + this.activeFrame_ = newFrame; + } else { + this.activeFrame_.addChild(newFrame); + } + + // Activate the new frame to force tasks to be treated as sub-tasks of + // the parent frame. + if (opt_activate) { + this.activeFrame_ = newFrame; + } + + try { + this.schedulingFrame_ = newFrame; + webdriver.promise.pushFlow_(this); + var result = fn(); + } finally { + webdriver.promise.popFlow_(); + this.schedulingFrame_ = null; + } + newFrame.lockFrame(); + + // If there was nothing scheduled in the new frame we can discard the + // frame and return immediately. + if (!newFrame.children_.length) { + removeNewFrame(); + webdriver.promise.asap(result, callback, errback); + return; + } + + newFrame.then(function() { + webdriver.promise.asap(result, callback, errback); + }, function(e) { + if (result instanceof webdriver.promise.Promise && result.isPending()) { + result.cancel(e); + e = result; + } + errback(e); + }); + } catch (ex) { + removeNewFrame(new webdriver.promise.CanceledTaskError_(ex)); + errback(ex); + } + + /** + * @param {webdriver.promise.CanceledTaskError_=} opt_err If provided, the + * error that triggered the removal of this frame. + */ + function removeNewFrame(opt_err) { + var parent = newFrame.getParent(); + if (parent) { + parent.removeChild(newFrame); + } + + if (opt_err) { + newFrame.cancelRemainingTasks(opt_err); + } + self.activeFrame_ = oldFrame; + } +}; + + +/** + * Commences the shutdown sequence for this instance. After one turn of the + * event loop, this object will emit the + * {@link webdriver.promise.ControlFlow.EventType.IDLE} event to signal + * listeners that it has completed. During this wait, if another task is + * scheduled, the shutdown will be aborted. + * @private + */ +webdriver.promise.ControlFlow.prototype.commenceShutdown_ = function() { + if (!this.shutdownId_) { + // Go ahead and stop the event loop now. If we're in here, then there are + // no more frames with tasks to execute. If we waited to cancel the event + // loop in our timeout below, the event loop could trigger *before* the + // timeout, generating an error from there being no frames. + // If #execute is called before the timeout below fires, it will cancel + // the timeout and restart the event loop. + this.cancelEventLoop_(); + + var self = this; + self.shutdownId_ = self.timer.setTimeout(function() { + self.shutdownId_ = null; + self.emit(webdriver.promise.ControlFlow.EventType.IDLE); + }, 0); + } +}; + + +/** + * Cancels the shutdown sequence if it is currently scheduled. + * @private + */ +webdriver.promise.ControlFlow.prototype.cancelShutdown_ = function() { + if (this.shutdownId_) { + this.timer.clearTimeout(this.shutdownId_); + this.shutdownId_ = null; + } +}; + + +/** + * Aborts this flow, abandoning all remaining tasks. If there are + * listeners registered, an {@code UNCAUGHT_EXCEPTION} will be emitted with the + * offending {@code error}, otherwise, the {@code error} will be rethrown to the + * global error handler. + * @param {*} error Object describing the error that caused the flow to + * abort; usually either an Error or string value. + * @private + */ +webdriver.promise.ControlFlow.prototype.abortNow_ = function(error) { + this.activeFrame_ = null; + this.cancelShutdown_(); + this.cancelEventLoop_(); + + var listeners = this.listeners( + webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION); + if (!listeners.length) { + this.timer.setTimeout(function() { + throw error; + }, 0); + } else { + this.emit(webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, + error); + } +}; + + + +/** + * A single node in an {@link webdriver.promise.ControlFlow}'s task tree. + * @param {!webdriver.promise.ControlFlow} flow The flow this instance belongs + * to. + * @constructor + * @extends {webdriver.promise.Deferred} + * @private + */ +webdriver.promise.Node_ = function(flow) { + webdriver.promise.Deferred.call(this, null, flow); +}; +goog.inherits(webdriver.promise.Node_, webdriver.promise.Deferred); + + +/** + * This node's parent. + * @private {webdriver.promise.Node_} + */ +webdriver.promise.Node_.prototype.parent_ = null; + + +/** @return {webdriver.promise.Node_} This node's parent. */ +webdriver.promise.Node_.prototype.getParent = function() { + return this.parent_; +}; + + +/** + * @param {webdriver.promise.Node_} parent This node's new parent. + */ +webdriver.promise.Node_.prototype.setParent = function(parent) { + this.parent_ = parent; +}; + + +/** + * @return {!webdriver.promise.Node_} The root of this node's tree. + */ +webdriver.promise.Node_.prototype.getRoot = function() { + var root = this; + while (root.parent_) { + root = root.parent_; + } + return root; +}; + + + +/** + * An execution frame within a {@link webdriver.promise.ControlFlow}. Each + * frame represents the execution context for either a + * {@link webdriver.promise.Task_} or a callback on a + * {@link webdriver.promise.Deferred}. + * + *

      Each frame may contain sub-frames. If child N is a sub-frame, then the + * items queued within it are given priority over child N+1. + * + * @param {!webdriver.promise.ControlFlow} flow The flow this instance belongs + * to. + * @constructor + * @extends {webdriver.promise.Node_} + * @private + */ +webdriver.promise.Frame_ = function(flow) { + webdriver.promise.Node_.call(this, flow); + + var reject = goog.bind(this.reject, this); + var cancelRemainingTasks = goog.bind(this.cancelRemainingTasks, this); + + /** @override */ + this.reject = function(e) { + cancelRemainingTasks(new webdriver.promise.CanceledTaskError_(e)); + reject(e); + }; + + /** + * @private {!Array.} + */ + this.children_ = []; +}; +goog.inherits(webdriver.promise.Frame_, webdriver.promise.Node_); + + +/** + * The task currently being executed within this frame. + * @private {webdriver.promise.Task_} + */ +webdriver.promise.Frame_.prototype.pendingTask_ = null; + + +/** + * Whether this frame is active. A frame is considered active once one of its + * descendants has been removed for execution. + * + * Adding a sub-frame as a child to an active frame is an indication that + * a callback to a {@link webdriver.promise.Deferred} is being invoked and any + * tasks scheduled within it should have priority over previously scheduled + * tasks: + *

      + *   var flow = webdriver.promise.controlFlow();
      + *   flow.execute('start here', goog.nullFunction).then(function() {
      + *     flow.execute('this should execute 2nd', goog.nullFunction);
      + *   });
      + *   flow.execute('this should execute last', goog.nullFunction);
      + * 
      + * + * @private {boolean} + */ +webdriver.promise.Frame_.prototype.isActive_ = false; + + +/** + * Whether this frame is currently locked. A locked frame represents a callback + * or task function which has run to completion and scheduled all of its tasks. + * + *

      Once a frame becomes {@link #isActive_ active}, any new frames which are + * added represent callbacks on a {@link webdriver.promise.Deferred}, whose + * tasks must be given priority over previously scheduled tasks. + * + * @private {boolean} + */ +webdriver.promise.Frame_.prototype.isLocked_ = false; + + +/** + * A reference to the last node inserted in this frame. + * @private {webdriver.promise.Node_} + */ +webdriver.promise.Frame_.prototype.lastInsertedChild_ = null; + + +/** + * Marks all of the tasks that are descendants of this frame in the execution + * tree as cancelled. This is necessary for callbacks scheduled asynchronous. + * For example: + * + * var someResult; + * webdriver.promise.createFlow(function(flow) { + * someResult = flow.execute(function() {}); + * throw Error(); + * }).addErrback(function(err) { + * console.log('flow failed: ' + err); + * someResult.then(function() { + * console.log('task succeeded!'); + * }, function(err) { + * console.log('task failed! ' + err); + * }); + * }); + * // flow failed: Error: boom + * // task failed! CanceledTaskError: Task discarded due to a previous + * // task failure: Error: boom + * + * @param {!webdriver.promise.CanceledTaskError_} error The cancellation + * error. + */ +webdriver.promise.Frame_.prototype.cancelRemainingTasks = function(error) { + goog.array.forEach(this.children_, function(child) { + if (child instanceof webdriver.promise.Frame_) { + child.cancelRemainingTasks(error); + } else { + // None of the previously registered listeners should be notified that + // the task is being canceled, however, we need at least one errback + // to prevent the cancellation from bubbling up. + child.removeAll(); + child.thenCatch(goog.nullFunction); + child.cancel(error); + } + }); +}; + + +/** + * @return {webdriver.promise.Task_} The task currently executing + * within this frame, if any. + */ +webdriver.promise.Frame_.prototype.getPendingTask = function() { + return this.pendingTask_; +}; + + +/** + * @param {webdriver.promise.Task_} task The task currently + * executing within this frame, if any. + */ +webdriver.promise.Frame_.prototype.setPendingTask = function(task) { + this.pendingTask_ = task; +}; + + +/** Locks this frame. */ +webdriver.promise.Frame_.prototype.lockFrame = function() { + this.isLocked_ = true; +}; + + +/** + * Adds a new node to this frame. + * @param {!(webdriver.promise.Frame_|webdriver.promise.Task_)} node + * The node to insert. + */ +webdriver.promise.Frame_.prototype.addChild = function(node) { + if (this.lastInsertedChild_ && + this.lastInsertedChild_ instanceof webdriver.promise.Frame_ && + !this.lastInsertedChild_.isLocked_) { + this.lastInsertedChild_.addChild(node); + return; + } + + node.setParent(this); + + if (this.isActive_ && node instanceof webdriver.promise.Frame_) { + var index = 0; + if (this.lastInsertedChild_ instanceof + webdriver.promise.Frame_) { + index = goog.array.indexOf(this.children_, this.lastInsertedChild_) + 1; + } + goog.array.insertAt(this.children_, node, index); + this.lastInsertedChild_ = node; + return; + } + + this.lastInsertedChild_ = node; + this.children_.push(node); +}; + + +/** + * @return {(webdriver.promise.Frame_|webdriver.promise.Task_)} This frame's + * fist child. + */ +webdriver.promise.Frame_.prototype.getFirstChild = function() { + this.isActive_ = true; + this.lastInsertedChild_ = null; + return this.children_[0]; +}; + + +/** + * Removes a child from this frame. + * @param {!(webdriver.promise.Frame_|webdriver.promise.Task_)} child + * The child to remove. + */ +webdriver.promise.Frame_.prototype.removeChild = function(child) { + var index = goog.array.indexOf(this.children_, child); + child.setParent(null); + goog.array.removeAt(this.children_, index); + if (this.lastInsertedChild_ === child) { + this.lastInsertedChild_ = null; + } +}; + + +/** @override */ +webdriver.promise.Frame_.prototype.toString = function() { + return '[' + goog.array.map(this.children_, function(child) { + return child.toString(); + }).join(', ') + ']'; +}; + + + +/** + * A task to be executed by a {@link webdriver.promise.ControlFlow}. + * + * @param {!webdriver.promise.ControlFlow} flow The flow this instances belongs + * to. + * @param {!Function} fn The function to call when the task executes. If it + * returns a {@code webdriver.promise.Promise}, the flow will wait + * for it to be resolved before starting the next task. + * @param {string} description A description of the task for debugging. + * @param {!webdriver.stacktrace.Snapshot} snapshot A snapshot of the stack + * when this task was scheduled. + * @constructor + * @extends {webdriver.promise.Node_} + * @private + */ +webdriver.promise.Task_ = function(flow, fn, description, snapshot) { + webdriver.promise.Node_.call(this, flow); + + /** + * Executes this task. + * @type {!Function} + */ + this.execute = fn; + + /** @private {string} */ + this.description_ = description; + + /** @private {!webdriver.stacktrace.Snapshot} */ + this.snapshot_ = snapshot; +}; +goog.inherits(webdriver.promise.Task_, webdriver.promise.Node_); + + +/** @return {string} This task's description. */ +webdriver.promise.Task_.prototype.getDescription = function() { + return this.description_; +}; + + +/** @override */ +webdriver.promise.Task_.prototype.toString = function() { + var stack = this.snapshot_.getStacktrace(); + var ret = this.description_; + if (stack.length) { + if (this.description_) { + ret += '\n'; + } + ret += stack.join('\n'); + } + return ret; +}; + + + +/** + * Special error used to signal when a task is canceled because a previous + * task in the same frame failed. + * @param {*} err The error that caused the task cancellation. + * @constructor + * @extends {goog.debug.Error} + * @private + */ +webdriver.promise.CanceledTaskError_ = function(err) { + goog.base(this, 'Task discarded due to a previous task failure: ' + err); +}; +goog.inherits(webdriver.promise.CanceledTaskError_, goog.debug.Error); + + +/** @override */ +webdriver.promise.CanceledTaskError_.prototype.name = 'CanceledTaskError'; + + + +/** + * The default flow to use if no others are active. + * @private {!webdriver.promise.ControlFlow} + */ +webdriver.promise.defaultFlow_ = new webdriver.promise.ControlFlow(); + + +/** + * A stack of active control flows, with the top of the stack used to schedule + * commands. When there are multiple flows on the stack, the flow at index N + * represents a callback triggered within a task owned by the flow at index + * N-1. + * @private {!Array.} + */ +webdriver.promise.activeFlows_ = []; + + +/** + * Changes the default flow to use when no others are active. + * @param {!webdriver.promise.ControlFlow} flow The new default flow. + * @throws {Error} If the default flow is not currently active. + */ +webdriver.promise.setDefaultFlow = function(flow) { + if (webdriver.promise.activeFlows_.length) { + throw Error('You may only change the default flow while it is active'); + } + webdriver.promise.defaultFlow_ = flow; +}; + + +/** + * @return {!webdriver.promise.ControlFlow} The currently active control flow. + */ +webdriver.promise.controlFlow = function() { + return /** @type {!webdriver.promise.ControlFlow} */ ( + goog.array.peek(webdriver.promise.activeFlows_) || + webdriver.promise.defaultFlow_); +}; + + +/** + * @param {!webdriver.promise.ControlFlow} flow The new flow. + * @private + */ +webdriver.promise.pushFlow_ = function(flow) { + webdriver.promise.activeFlows_.push(flow); +}; + + +/** @private */ +webdriver.promise.popFlow_ = function() { + webdriver.promise.activeFlows_.pop(); +}; + + +/** + * Creates a new control flow. The provided callback will be invoked as the + * first task within the new flow, with the flow as its sole argument. Returns + * a promise that resolves to the callback result. + * @param {function(!webdriver.promise.ControlFlow)} callback The entry point + * to the newly created flow. + * @return {!webdriver.promise.Promise} A promise that resolves to the callback + * result. + */ +webdriver.promise.createFlow = function(callback) { + var flow = new webdriver.promise.ControlFlow( + webdriver.promise.defaultFlow_.timer); + return flow.execute(function() { + return callback(flow); + }); +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/session.js b/node_modules/selenium-webdriver/lib/webdriver/session.js new file mode 100644 index 0000000..03d3219 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/session.js @@ -0,0 +1,71 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('webdriver.Session'); + +goog.require('webdriver.Capabilities'); + + + +/** + * Contains information about a WebDriver session. + * @param {string} id The session ID. + * @param {!(Object|webdriver.Capabilities)} capabilities The session + * capabilities. + * @constructor + */ +webdriver.Session = function(id, capabilities) { + + /** @private {string} */ + this.id_ = id; + + /** @private {!webdriver.Capabilities} */ + this.caps_ = new webdriver.Capabilities().merge(capabilities); +}; + + +/** + * @return {string} This session's ID. + */ +webdriver.Session.prototype.getId = function() { + return this.id_; +}; + + +/** + * @return {!webdriver.Capabilities} This session's capabilities. + */ +webdriver.Session.prototype.getCapabilities = function() { + return this.caps_; +}; + + +/** + * Retrieves the value of a specific capability. + * @param {string} key The capability to retrieve. + * @return {*} The capability value. + */ +webdriver.Session.prototype.getCapability = function(key) { + return this.caps_.get(key); +}; + + +/** + * Returns the JSON representation of this object, which is just the string + * session ID. + * @return {string} The JSON representation of this Session. + */ +webdriver.Session.prototype.toJSON = function() { + return this.getId(); +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/stacktrace.js b/node_modules/selenium-webdriver/lib/webdriver/stacktrace.js new file mode 100644 index 0000000..11bf52c --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/stacktrace.js @@ -0,0 +1,647 @@ +// Copyright 2009 The Closure Library Authors. All Rights Reserved. +// Copyright 2012 Selenium comitters +// Copyright 2012 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Tools for parsing and pretty printing error stack traces. This + * file is based on goog.testing.stacktrace. + */ + +goog.provide('webdriver.stacktrace'); +goog.provide('webdriver.stacktrace.Snapshot'); + +goog.require('goog.array'); +goog.require('goog.string'); +goog.require('goog.userAgent'); + + + +/** + * Stores a snapshot of the stack trace at the time this instance was created. + * The stack trace will always be adjusted to exclude this function call. + * @param {number=} opt_slice The number of frames to remove from the top of + * the generated stack trace. + * @constructor + */ +webdriver.stacktrace.Snapshot = function(opt_slice) { + + /** @private {number} */ + this.slice_ = opt_slice || 0; + + var error; + if (webdriver.stacktrace.CAN_CAPTURE_STACK_TRACE_) { + error = Error(); + Error.captureStackTrace(error, webdriver.stacktrace.Snapshot); + } else { + // Remove 1 extra frame for the call to this constructor. + this.slice_ += 1; + // IE will only create a stack trace when the Error is thrown. + // We use null.x() to throw an exception instead of throw this.error_ + // because the closure compiler may optimize throws to a function call + // in an attempt to minimize the binary size which in turn has the side + // effect of adding an unwanted stack frame. + try { + null.x(); + } catch (e) { + error = e; + } + } + + /** + * The error's stacktrace. This must be accessed immediately to ensure Opera + * computes the context correctly. + * @private {string} + */ + this.stack_ = webdriver.stacktrace.getStack_(error); +}; + + +/** + * Whether the current environment supports the Error.captureStackTrace + * function (as of 10/17/2012, only V8). + * @private {boolean} + * @const + */ +webdriver.stacktrace.CAN_CAPTURE_STACK_TRACE_ = + goog.isFunction(Error.captureStackTrace); + + +/** + * Whether the current browser supports stack traces. + * + * @type {boolean} + * @const + */ +webdriver.stacktrace.BROWSER_SUPPORTED = + webdriver.stacktrace.CAN_CAPTURE_STACK_TRACE_ || (function() { + try { + throw Error(); + } catch (e) { + return !!e.stack; + } + })(); + + +/** + * The parsed stack trace. This list is lazily generated the first time it is + * accessed. + * @private {Array.} + */ +webdriver.stacktrace.Snapshot.prototype.parsedStack_ = null; + + +/** + * @return {!Array.} The parsed stack trace. + */ +webdriver.stacktrace.Snapshot.prototype.getStacktrace = function() { + if (goog.isNull(this.parsedStack_)) { + this.parsedStack_ = webdriver.stacktrace.parse_(this.stack_); + if (this.slice_) { + this.parsedStack_ = goog.array.slice(this.parsedStack_, this.slice_); + } + delete this.slice_; + delete this.stack_; + } + return this.parsedStack_; +}; + + + +/** + * Class representing one stack frame. + * @param {(string|undefined)} context Context object, empty in case of global + * functions or if the browser doesn't provide this information. + * @param {(string|undefined)} name Function name, empty in case of anonymous + * functions. + * @param {(string|undefined)} alias Alias of the function if available. For + * example the function name will be 'c' and the alias will be 'b' if the + * function is defined as a.b = function c() {};. + * @param {(string|undefined)} path File path or URL including line number and + * optionally column number separated by colons. + * @constructor + */ +webdriver.stacktrace.Frame = function(context, name, alias, path) { + + /** @private {string} */ + this.context_ = context || ''; + + /** @private {string} */ + this.name_ = name || ''; + + /** @private {string} */ + this.alias_ = alias || ''; + + /** @private {string} */ + this.path_ = path || ''; + + /** @private {string} */ + this.url_ = this.path_; + + /** @private {number} */ + this.line_ = -1; + + /** @private {number} */ + this.column_ = -1; + + if (path) { + var match = /:(\d+)(?::(\d+))?$/.exec(path); + if (match) { + this.line_ = Number(match[1]); + this.column = Number(match[2] || -1); + this.url_ = path.substr(0, match.index); + } + } +}; + + +/** + * Constant for an anonymous frame. + * @private {!webdriver.stacktrace.Frame} + * @const + */ +webdriver.stacktrace.ANONYMOUS_FRAME_ = + new webdriver.stacktrace.Frame('', '', '', ''); + + +/** + * @return {string} The function name or empty string if the function is + * anonymous and the object field which it's assigned to is unknown. + */ +webdriver.stacktrace.Frame.prototype.getName = function() { + return this.name_; +}; + + +/** + * @return {string} The url or empty string if it is unknown. + */ +webdriver.stacktrace.Frame.prototype.getUrl = function() { + return this.url_; +}; + + +/** + * @return {number} The line number if known or -1 if it is unknown. + */ +webdriver.stacktrace.Frame.prototype.getLine = function() { + return this.line_; +}; + + +/** + * @return {number} The column number if known and -1 if it is unknown. + */ +webdriver.stacktrace.Frame.prototype.getColumn = function() { + return this.column_; +}; + + +/** + * @return {boolean} Whether the stack frame contains an anonymous function. + */ +webdriver.stacktrace.Frame.prototype.isAnonymous = function() { + return !this.name_ || this.context_ == '[object Object]'; +}; + + +/** + * Converts this frame to its string representation using V8's stack trace + * format: http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi + * @return {string} The string representation of this frame. + * @override + */ +webdriver.stacktrace.Frame.prototype.toString = function() { + var context = this.context_; + if (context && context !== 'new ') { + context += '.'; + } + context += this.name_; + context += this.alias_ ? ' [as ' + this.alias_ + ']' : ''; + + var path = this.path_ || ''; + return ' at ' + (context ? context + ' (' + path + ')' : path); +}; + + +/** + * Maximum length of a string that can be matched with a RegExp on + * Firefox 3x. Exceeding this approximate length will cause string.match + * to exceed Firefox's stack quota. This situation can be encountered + * when goog.globalEval is invoked with a long argument; such as + * when loading a module. + * @private {number} + * @const + */ +webdriver.stacktrace.MAX_FIREFOX_FRAMESTRING_LENGTH_ = 500000; + + +/** + * RegExp pattern for JavaScript identifiers. We don't support Unicode + * identifiers defined in ECMAScript v3. + * @private {string} + * @const + */ +webdriver.stacktrace.IDENTIFIER_PATTERN_ = '[a-zA-Z_$][\\w$]*'; + + +/** + * Pattern for a matching the type on a fully-qualified name. Forms an + * optional sub-match on the type. For example, in "foo.bar.baz", will match on + * "foo.bar". + * @private {string} + * @const + */ +webdriver.stacktrace.CONTEXT_PATTERN_ = + '(' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + + '(?:\\.' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + ')*)\\.'; + + +/** + * Pattern for matching a fully qualified name. Will create two sub-matches: + * the type (optional), and the name. For example, in "foo.bar.baz", will + * match on ["foo.bar", "baz"]. + * @private {string} + * @const + */ +webdriver.stacktrace.QUALIFIED_NAME_PATTERN_ = + '(?:' + webdriver.stacktrace.CONTEXT_PATTERN_ + ')?' + + '(' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + ')'; + + +/** + * RegExp pattern for function name alias in the V8 stack trace. + * @private {string} + * @const + */ +webdriver.stacktrace.V8_ALIAS_PATTERN_ = + '(?: \\[as (' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + ')\\])?'; + + +/** + * RegExp pattern for function names and constructor calls in the V8 stack + * trace. + * @private {string} + * @const + */ +webdriver.stacktrace.V8_FUNCTION_NAME_PATTERN_ = + '(?:' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + '|)'; + + +/** + * RegExp pattern for the context of a function call in V8. Creates two + * submatches, only one of which will ever match: either the namespace + * identifier (with optional "new" keyword in the case of a constructor call), + * or just the "new " phrase for a top level constructor call. + * @private {string} + * @const + */ +webdriver.stacktrace.V8_CONTEXT_PATTERN_ = + '(?:((?:new )?(?:\\[object Object\\]|' + + webdriver.stacktrace.IDENTIFIER_PATTERN_ + + '(?:\\.' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + ')*)' + + ')\\.|(new ))'; + + +/** + * RegExp pattern for function call in the V8 stack trace. + * Creates 3 submatches with context object (optional), function name and + * function alias (optional). + * @private {string} + * @const + */ +webdriver.stacktrace.V8_FUNCTION_CALL_PATTERN_ = + ' (?:' + webdriver.stacktrace.V8_CONTEXT_PATTERN_ + ')?' + + '(' + webdriver.stacktrace.V8_FUNCTION_NAME_PATTERN_ + ')' + + webdriver.stacktrace.V8_ALIAS_PATTERN_; + + +/** + * RegExp pattern for an URL + position inside the file. + * @private {string} + * @const + */ +webdriver.stacktrace.URL_PATTERN_ = + '((?:http|https|file)://[^\\s]+|javascript:.*)'; + + +/** + * RegExp pattern for a location string in a V8 stack frame. Creates two + * submatches for the location, one for enclosed in parentheticals and on + * where the location appears alone (which will only occur if the location is + * the only information in the frame). + * @private {string} + * @const + * @see http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi + */ +webdriver.stacktrace.V8_LOCATION_PATTERN_ = ' (?:\\((.*)\\)|(.*))'; + + +/** + * Regular expression for parsing one stack frame in V8. + * @private {!RegExp} + * @const + */ +webdriver.stacktrace.V8_STACK_FRAME_REGEXP_ = new RegExp('^ at' + + '(?:' + webdriver.stacktrace.V8_FUNCTION_CALL_PATTERN_ + ')?' + + webdriver.stacktrace.V8_LOCATION_PATTERN_ + '$'); + + +/** + * RegExp pattern for function names in the Firefox stack trace. + * Firefox has extended identifiers to deal with inner functions and anonymous + * functions: https://bugzilla.mozilla.org/show_bug.cgi?id=433529#c9 + * @private {string} + * @const + */ +webdriver.stacktrace.FIREFOX_FUNCTION_NAME_PATTERN_ = + webdriver.stacktrace.IDENTIFIER_PATTERN_ + '[\\w./<$]*'; + + +/** + * RegExp pattern for function call in the Firefox stack trace. + * Creates a submatch for the function name. + * @private {string} + * @const + */ +webdriver.stacktrace.FIREFOX_FUNCTION_CALL_PATTERN_ = + '(' + webdriver.stacktrace.FIREFOX_FUNCTION_NAME_PATTERN_ + ')?' + + '(?:\\(.*\\))?@'; + + +/** + * Regular expression for parsing one stack frame in Firefox. + * @private {!RegExp} + * @const + */ +webdriver.stacktrace.FIREFOX_STACK_FRAME_REGEXP_ = new RegExp('^' + + webdriver.stacktrace.FIREFOX_FUNCTION_CALL_PATTERN_ + + '(?::0|' + webdriver.stacktrace.URL_PATTERN_ + ')$'); + + +/** + * RegExp pattern for an anonymous function call in an Opera stack frame. + * Creates 2 (optional) submatches: the context object and function name. + * @private {string} + * @const + */ +webdriver.stacktrace.OPERA_ANONYMOUS_FUNCTION_NAME_PATTERN_ = + ''; + + +/** + * RegExp pattern for a function call in an Opera stack frame. + * Creates 3 (optional) submatches: the function name (if not anonymous), + * the aliased context object and the function name (if anonymous). + * @private {string} + * @const + */ +webdriver.stacktrace.OPERA_FUNCTION_CALL_PATTERN_ = + '(?:(?:(' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + ')|' + + webdriver.stacktrace.OPERA_ANONYMOUS_FUNCTION_NAME_PATTERN_ + + ')(?:\\(.*\\)))?@'; + + +/** + * Regular expression for parsing on stack frame in Opera 11.68+ + * @private {!RegExp} + * @const + */ +webdriver.stacktrace.OPERA_STACK_FRAME_REGEXP_ = new RegExp('^' + + webdriver.stacktrace.OPERA_FUNCTION_CALL_PATTERN_ + + webdriver.stacktrace.URL_PATTERN_ + '?$'); + + +/** + * RegExp pattern for function call in a Chakra (IE) stack trace. This + * expression allows for identifiers like 'Anonymous function', 'eval code', + * and 'Global code'. + * @private {string} + * @const + */ +webdriver.stacktrace.CHAKRA_FUNCTION_CALL_PATTERN_ = '(' + + webdriver.stacktrace.IDENTIFIER_PATTERN_ + '(?:\\s+\\w+)*)'; + + +/** + * Regular expression for parsing on stack frame in Chakra (IE). + * @private {!RegExp} + * @const + */ +webdriver.stacktrace.CHAKRA_STACK_FRAME_REGEXP_ = new RegExp('^ at ' + + webdriver.stacktrace.CHAKRA_FUNCTION_CALL_PATTERN_ + + '\\s*(?:\\((.*)\\))$'); + + +/** + * Placeholder for an unparsable frame in a stack trace generated by + * {@link goog.testing.stacktrace}. + * @private {string} + * @const + */ +webdriver.stacktrace.UNKNOWN_CLOSURE_FRAME_ = '> (unknown)'; + + +/** + * Representation of an anonymous frame in a stack trace generated by + * {@link goog.testing.stacktrace}. + * @private {string} + * @const + */ +webdriver.stacktrace.ANONYMOUS_CLOSURE_FRAME_ = '> anonymous'; + + +/** + * Pattern for a function call in a Closure stack trace. Creates three optional + * submatches: the context, function name, and alias. + * @private {string} + * @const + */ +webdriver.stacktrace.CLOSURE_FUNCTION_CALL_PATTERN_ = + webdriver.stacktrace.QUALIFIED_NAME_PATTERN_ + + '(?:\\(.*\\))?' + // Ignore arguments if present. + webdriver.stacktrace.V8_ALIAS_PATTERN_; + + +/** + * Regular expression for parsing a stack frame generated by Closure's + * {@link goog.testing.stacktrace}. + * @private {!RegExp} + * @const + */ +webdriver.stacktrace.CLOSURE_STACK_FRAME_REGEXP_ = new RegExp('^> ' + + '(?:' + webdriver.stacktrace.CLOSURE_FUNCTION_CALL_PATTERN_ + + '(?: at )?)?' + + '(?:(.*:\\d+:\\d+)|' + webdriver.stacktrace.URL_PATTERN_ + ')?$'); + + +/** + * Parses one stack frame. + * @param {string} frameStr The stack frame as string. + * @return {webdriver.stacktrace.Frame} Stack frame object or null if the + * parsing failed. + * @private + */ +webdriver.stacktrace.parseStackFrame_ = function(frameStr) { + var m = frameStr.match(webdriver.stacktrace.V8_STACK_FRAME_REGEXP_); + if (m) { + return new webdriver.stacktrace.Frame( + m[1] || m[2], m[3], m[4], m[5] || m[6]); + } + + if (frameStr.length > + webdriver.stacktrace.MAX_FIREFOX_FRAMESTRING_LENGTH_) { + return webdriver.stacktrace.parseLongFirefoxFrame_(frameStr); + } + + m = frameStr.match(webdriver.stacktrace.FIREFOX_STACK_FRAME_REGEXP_); + if (m) { + return new webdriver.stacktrace.Frame('', m[1], '', m[2]); + } + + m = frameStr.match(webdriver.stacktrace.OPERA_STACK_FRAME_REGEXP_); + if (m) { + return new webdriver.stacktrace.Frame(m[2], m[1] || m[3], '', m[4]); + } + + m = frameStr.match(webdriver.stacktrace.CHAKRA_STACK_FRAME_REGEXP_); + if (m) { + return new webdriver.stacktrace.Frame('', m[1], '', m[2]); + } + + if (frameStr == webdriver.stacktrace.UNKNOWN_CLOSURE_FRAME_ || + frameStr == webdriver.stacktrace.ANONYMOUS_CLOSURE_FRAME_) { + return webdriver.stacktrace.ANONYMOUS_FRAME_; + } + + m = frameStr.match(webdriver.stacktrace.CLOSURE_STACK_FRAME_REGEXP_); + if (m) { + return new webdriver.stacktrace.Frame(m[1], m[2], m[3], m[4] || m[5]); + } + + return null; +}; + + +/** + * Parses a long firefox stack frame. + * @param {string} frameStr The stack frame as string. + * @return {!webdriver.stacktrace.Frame} Stack frame object. + * @private + */ +webdriver.stacktrace.parseLongFirefoxFrame_ = function(frameStr) { + var firstParen = frameStr.indexOf('('); + var lastAmpersand = frameStr.lastIndexOf('@'); + var lastColon = frameStr.lastIndexOf(':'); + var functionName = ''; + if ((firstParen >= 0) && (firstParen < lastAmpersand)) { + functionName = frameStr.substring(0, firstParen); + } + var loc = ''; + if ((lastAmpersand >= 0) && (lastAmpersand + 1 < lastColon)) { + loc = frameStr.substring(lastAmpersand + 1); + } + return new webdriver.stacktrace.Frame('', functionName, '', loc); +}; + + +/** + * Get an error's stack trace with the error string trimmed. + * V8 prepends the string representation of an error to its stack trace. + * This function trims the string so that the stack trace can be parsed + * consistently with the other JS engines. + * @param {(Error|goog.testing.JsUnitException)} error The error. + * @return {string} The stack trace string. + * @private + */ +webdriver.stacktrace.getStack_ = function(error) { + if (!error) { + return ''; + } + var stack = error.stack || error.stackTrace || ''; + var errorStr = error + '\n'; + if (goog.string.startsWith(stack, errorStr)) { + stack = stack.substring(errorStr.length); + } + return stack; +}; + + +/** + * Formats an error's stack trace. + * @param {!(Error|goog.testing.JsUnitException)} error The error to format. + * @return {!(Error|goog.testing.JsUnitException)} The formatted error. + */ +webdriver.stacktrace.format = function(error) { + var stack = webdriver.stacktrace.getStack_(error); + var frames = webdriver.stacktrace.parse_(stack); + + // Older versions of IE simply return [object Error] for toString(), so + // only use that as a last resort. + var errorStr = ''; + if (error.message) { + errorStr = (error.name ? error.name + ': ' : '') + error.message; + } else { + errorStr = error.toString(); + } + + // Ensure the error is in the V8 style with the error's string representation + // prepended to the stack. + error.stack = errorStr + '\n' + frames.join('\n'); + return error; +}; + + +/** + * Parses an Error object's stack trace. + * @param {string} stack The stack trace. + * @return {!Array.} Stack frames. The + * unrecognized frames will be nulled out. + * @private + */ +webdriver.stacktrace.parse_ = function(stack) { + if (!stack) { + return []; + } + + var lines = stack. + replace(/\s*$/, ''). + split('\n'); + var frames = []; + for (var i = 0; i < lines.length; i++) { + var frame = webdriver.stacktrace.parseStackFrame_(lines[i]); + // The first two frames will be: + // webdriver.stacktrace.Snapshot() + // webdriver.stacktrace.get() + // In the case of Opera, sometimes an extra frame is injected in the next + // frame with a reported line number of zero. The next line detects that + // case and skips that frame. + if (!(goog.userAgent.OPERA && i == 2 && frame.getLine() == 0)) { + frames.push(frame || webdriver.stacktrace.ANONYMOUS_FRAME_); + } + } + return frames; +}; + + +/** + * Gets the native stack trace if available otherwise follows the call chain. + * The generated trace will exclude all frames up to and including the call to + * this function. + * @return {!Array.} The frames of the stack trace. + */ +webdriver.stacktrace.get = function() { + return new webdriver.stacktrace.Snapshot(1).getStacktrace(); +}; diff --git a/node_modules/selenium-webdriver/lib/webdriver/testing/asserts.js b/node_modules/selenium-webdriver/lib/webdriver/testing/asserts.js new file mode 100644 index 0000000..bbe979d --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/testing/asserts.js @@ -0,0 +1,485 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Assertions and expectation utilities for use in WebDriver test + * cases. + */ + +goog.provide('webdriver.testing.Assertion'); +goog.provide('webdriver.testing.ContainsMatcher'); +goog.provide('webdriver.testing.NegatedAssertion'); +goog.provide('webdriver.testing.assert'); +goog.provide('webdriver.testing.asserts'); + +goog.require('goog.array'); +goog.require('goog.labs.testing.CloseToMatcher'); +goog.require('goog.labs.testing.EndsWithMatcher'); +goog.require('goog.labs.testing.EqualToMatcher'); +goog.require('goog.labs.testing.EqualsMatcher'); +goog.require('goog.labs.testing.GreaterThanEqualToMatcher'); +goog.require('goog.labs.testing.GreaterThanMatcher'); +goog.require('goog.labs.testing.LessThanEqualToMatcher'); +goog.require('goog.labs.testing.LessThanMatcher'); +goog.require('goog.labs.testing.InstanceOfMatcher'); +goog.require('goog.labs.testing.IsNotMatcher'); +goog.require('goog.labs.testing.IsNullMatcher'); +goog.require('goog.labs.testing.IsNullOrUndefinedMatcher'); +goog.require('goog.labs.testing.IsUndefinedMatcher'); +goog.require('goog.labs.testing.Matcher'); +goog.require('goog.labs.testing.ObjectEqualsMatcher'); +goog.require('goog.labs.testing.RegexMatcher'); +goog.require('goog.labs.testing.StartsWithMatcher'); +goog.require('goog.labs.testing.assertThat'); +goog.require('goog.string'); +goog.require('webdriver.promise'); + + +/** + * Accepts strins or array-like structures that contain {@code value}. + * @param {*} value The value to check for. + * @constructor + * @implements {goog.labs.testing.Matcher} + */ +webdriver.testing.ContainsMatcher = function(value) { + /** @private {*} */ + this.value_ = value; +}; + + +/** @override */ +webdriver.testing.ContainsMatcher.prototype.matches = function(actualValue) { + if (goog.isString(actualValue)) { + return goog.string.contains( + actualValue, /** @type {string} */(this.value_)); + } else { + return goog.array.contains( + /** @type {goog.array.ArrayLike} */(actualValue), this.value_); + } +}; + + +/** @override */ +webdriver.testing.ContainsMatcher.prototype.describe = function(actualValue) { + return actualValue + ' does not contain ' + this.value_; +}; + + + +/** + * Utility for performing assertions against a given {@code value}. If the + * value is a {@link webdriver.promise.Promise}, this assertion will wait + * for it to resolve before applying any matchers. + * @param {*} value The value to wrap and apply matchers to. + * @constructor + */ +webdriver.testing.Assertion = function(value) { + + /** @private {*} */ + this.value_ = value; + + if (!(this instanceof webdriver.testing.NegatedAssertion)) { + /** + * A self reference provided for writing fluent assertions: + * webdriver.testing.assert(x).is.equalTo(y); + * @type {!webdriver.testing.Assertion} + */ + this.is = this; + + /** + * Negates any matchers applied to this instance's value: + * webdriver.testing.assert(x).not.equalTo(y); + * @type {!webdriver.testing.NegatedAssertion} + */ + this.not = new webdriver.testing.NegatedAssertion(value); + } +}; + + +/** + * Wraps an object literal implementing the Matcher interface. This is used + * to appease the Closure compiler, which will not treat an object literal as + * implementing an interface. + * @param {{matches: function(*): boolean, describe: function(): string}} obj + * The object literal to delegate to. + * @constructor + * @implements {goog.labs.testing.Matcher} + * @private + */ +webdriver.testing.Assertion.DelegatingMatcher_ = function(obj) { + + /** @override */ + this.matches = function(value) { + return obj.matches(value); + }; + + /** @override */ + this.describe = function() { + return obj.describe(); + }; +}; + + +/** + * Asserts that the given {@code matcher} accepts the value wrapped by this + * instance. If the wrapped value is a promise, this function will defer + * applying the assertion until the value has been resolved. Otherwise, it + * will be applied immediately. + * @param {!goog.labs.testing.Matcher} matcher The matcher to apply + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The deferred assertion result, or + * {@code null} if the assertion was immediately applied. + * @protected + */ +webdriver.testing.Assertion.prototype.apply = function(matcher, opt_message) { + var result = null; + if (webdriver.promise.isPromise(this.value_)) { + result = webdriver.promise.when(this.value_, function(value) { + goog.labs.testing.assertThat(value, matcher, opt_message); + }); + } else { + goog.labs.testing.assertThat(this.value_, matcher, opt_message); + } + return result; +}; + + +/** + * Asserts that the value managed by this assertion is a number strictly + * greater than {@code value}. + * @param {number} value The minimum value. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.greaterThan = function( + value, opt_message) { + return this.apply( + new goog.labs.testing.GreaterThanMatcher(value), opt_message); +}; + + +/** + * Asserts that the value managed by this assertion is a number >= the given + * value. + * @param {number} value The minimum value. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.greaterThanEqualTo = function( + value, opt_message) { + return this.apply( + new goog.labs.testing.GreaterThanEqualToMatcher(value), opt_message); +}; + + +/** + * Asserts that the value managed by this assertion is a number strictly less + * than the given value. + * @param {number} value The maximum value. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.lessThan = function(value, opt_message) { + return this.apply( + new goog.labs.testing.LessThanMatcher(value), opt_message); +}; + + +/** + * Asserts that the value managed by this assertion is a number <= the given + * value. + * @param {number} value The maximum value. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.lessThanEqualTo = function( + value, opt_message) { + return this.apply( + new goog.labs.testing.LessThanEqualToMatcher(value), opt_message); +}; + + +/** + * Asserts that the wrapped value is a number within a given distance of an + * expected value. + * @param {number} value The expected value. + * @param {number} range The maximum amount the actual value is permitted to + * differ from the expected value. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.closeTo = function( + value, range, opt_message) { + return this.apply( + new goog.labs.testing.CloseToMatcher(value, range), opt_message); +}; + + +/** + * Asserts that the wrapped value is an instance of the given class. + * @param {!Function} ctor The expected class constructor. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.instanceOf = function(ctor, opt_message) { + return this.apply( + new goog.labs.testing.InstanceOfMatcher(ctor), opt_message); +}; + + +/** + * Asserts that the wrapped value is null. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.isNull = function(opt_message) { + return this.apply(new goog.labs.testing.IsNullMatcher(), opt_message); +}; + + +/** + * Asserts that the wrapped value is undefined. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.isUndefined = function(opt_message) { + return this.apply(new goog.labs.testing.IsUndefinedMatcher(), opt_message); +}; + + +/** + * Asserts that the wrapped value is null or undefined. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.isNullOrUndefined = function( + opt_message) { + return this.apply( + new goog.labs.testing.IsNullOrUndefinedMatcher(), opt_message); +}; + + +/** + * Asserts that the wrapped value is a string or array-like structure + * containing the given value. + * @param {*} value The expected value. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.contains = function(value, opt_message) { + return this.apply( + new webdriver.testing.ContainsMatcher(value), opt_message); +}; + + +/** + * Asserts that the wrapped value is a string ending with the given suffix. + * @param {string} suffix The expected suffix. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.endsWith = function( + suffix, opt_message) { + return this.apply( + new goog.labs.testing.EndsWithMatcher(suffix), opt_message); +}; + + +/** + * Asserts that the wrapped value is a string starting with the given prefix. + * @param {string} prefix The expected prefix. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.startsWith = function( + prefix, opt_message) { + return this.apply( + new goog.labs.testing.StartsWithMatcher(prefix), opt_message); +}; + + +/** + * Asserts that the wrapped value is a string that matches the given RegExp. + * @param {!RegExp} regex The regex to test. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.matches = function(regex, opt_message) { + return this.apply(new goog.labs.testing.RegexMatcher(regex), opt_message); +}; + + +/** + * Asserts that the value managed by this assertion is strictly equal to the + * given {@code value}. + * @param {*} value The expected value. + * @param {string=} opt_message A message to include if the matcher does not + * accept the value wrapped by this assertion. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.equalTo = function(value, opt_message) { + return this.apply(webdriver.testing.asserts.equalTo(value), opt_message); +}; + + +/** + * Asserts that the value managed by this assertion is strictly true. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.isTrue = function() { + return this.equalTo(true); +}; + + +/** + * Asserts that the value managed by this assertion is strictly false. + * @return {webdriver.promise.Promise} The assertion result. + */ +webdriver.testing.Assertion.prototype.isFalse = function() { + return this.equalTo(false); +}; + + + +/** + * An assertion that negates any applied matchers. + * @param {*} value The value to perform assertions on. + * @constructor + * @extends {webdriver.testing.Assertion} + */ +webdriver.testing.NegatedAssertion = function(value) { + goog.base(this, value); + this.value = value; +}; +goog.inherits( + webdriver.testing.NegatedAssertion, webdriver.testing.Assertion); + + +/** @override */ +webdriver.testing.NegatedAssertion.prototype.apply = function( + matcher, opt_message) { + matcher = new goog.labs.testing.IsNotMatcher(matcher); + return goog.base(this, 'apply', matcher, opt_message); +}; + + + +/** + * Creates a new assertion. + * @param {*} value The value to perform an assertion on. + * @return {!webdriver.testing.Assertion} The new assertion. + */ +webdriver.testing.assert = function(value) { + return new webdriver.testing.Assertion(value); +}; + + +/** + * Registers a new assertion to expose from the + * {@link webdriver.testing.Assertion} prototype. + * @param {string} name The assertion name. + * @param {(function(new: goog.labs.testing.Matcher, *)| + * {matches: function(*): boolean, + * describe: function(): string})} matcherTemplate Either the + * matcher constructor to use, or an object literal defining a matcher. + */ +webdriver.testing.assert.register = function(name, matcherTemplate) { + webdriver.testing.Assertion.prototype[name] = function(value, opt_message) { + var matcher; + if (goog.isFunction(matcherTemplate)) { + var ctor = /** @type {function(new: goog.labs.testing.Matcher, *)} */ ( + matcherTemplate); + matcher = new ctor(value); + } else { + matcher = new webdriver.testing.Assertion.DelegatingMatcher_(value); + } + return this.apply(matcher, opt_message); + }; +}; + + +/** + * Asserts that a matcher accepts a given value. This function has two + * signatures based on the number of arguments: + * + * Two arguments: + * assertThat(actualValue, matcher) + * Three arguments: + * assertThat(failureMessage, actualValue, matcher) + * + * @param {*} failureMessageOrActualValue Either a failure message or the value + * to apply to the given matcher. + * @param {*} actualValueOrMatcher Either the value to apply to the given + * matcher, or the matcher itself. + * @param {goog.labs.testing.Matcher=} opt_matcher The matcher to use; + * ignored unless this function is invoked with three arguments. + * @return {!webdriver.promise.Promise} The assertion result. + * @deprecated Use webdriver.testing.asserts.assert instead. + */ +webdriver.testing.asserts.assertThat = function( + failureMessageOrActualValue, actualValueOrMatcher, opt_matcher) { + var args = goog.array.slice(arguments, 0); + + var message = args.length > 2 ? args.shift() : ''; + if (message) message += '\n'; + + var actualValue = args.shift(); + var matcher = args.shift(); + + return webdriver.promise.when(actualValue, function(value) { + goog.labs.testing.assertThat(value, matcher, message); + }); +}; + + +/** + * Creates an equality matcher. + * @param {*} expected The expected value. + * @return {!goog.labs.testing.Matcher} The new matcher. + */ +webdriver.testing.asserts.equalTo = function(expected) { + if (goog.isString(expected)) { + return new goog.labs.testing.EqualsMatcher(expected); + } else if (goog.isNumber(expected)) { + return new goog.labs.testing.EqualToMatcher(expected); + } else { + return new goog.labs.testing.ObjectEqualsMatcher( + /** @type {!Object} */ (expected)); + } +}; + + +goog.exportSymbol('assertThat', webdriver.testing.asserts.assertThat); +// Mappings for goog.labs.testing matcher functions to the legacy +// webdriver.testing.asserts matchers. +goog.exportSymbol('contains', containsString); +goog.exportSymbol('equalTo', webdriver.testing.asserts.equalTo); +goog.exportSymbol('equals', webdriver.testing.asserts.equalTo); +goog.exportSymbol('is', webdriver.testing.asserts.equalTo); +goog.exportSymbol('not', isNot); +goog.exportSymbol('or', anyOf); diff --git a/node_modules/selenium-webdriver/lib/webdriver/webdriver.js b/node_modules/selenium-webdriver/lib/webdriver/webdriver.js new file mode 100644 index 0000000..d2d2db2 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/webdriver/webdriver.js @@ -0,0 +1,2132 @@ +// Copyright 2011 Software Freedom Conservancy. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview The heart of the WebDriver JavaScript API. + */ + +goog.provide('webdriver.Alert'); +goog.provide('webdriver.UnhandledAlertError'); +goog.provide('webdriver.WebDriver'); +goog.provide('webdriver.WebElement'); + +goog.require('bot.Error'); +goog.require('bot.ErrorCode'); +goog.require('bot.response'); +goog.require('goog.array'); +goog.require('goog.object'); +goog.require('webdriver.ActionSequence'); +goog.require('webdriver.Command'); +goog.require('webdriver.CommandName'); +goog.require('webdriver.Key'); +goog.require('webdriver.Locator'); +goog.require('webdriver.Session'); +goog.require('webdriver.logging'); +goog.require('webdriver.promise'); + + +////////////////////////////////////////////////////////////////////////////// +// +// webdriver.WebDriver +// +////////////////////////////////////////////////////////////////////////////// + + + +/** + * Creates a new WebDriver client, which provides control over a browser. + * + * Every WebDriver command returns a {@code webdriver.promise.Promise} that + * represents the result of that command. Callbacks may be registered on this + * object to manipulate the command result or catch an expected error. Any + * commands scheduled with a callback are considered sub-commands and will + * execute before the next command in the current frame. For example: + *

      
      + *   var message = [];
      + *   driver.call(message.push, message, 'a').then(function() {
      + *     driver.call(message.push, message, 'b');
      + *   });
      + *   driver.call(message.push, message, 'c');
      + *   driver.call(function() {
      + *     alert('message is abc? ' + (message.join('') == 'abc'));
      + *   });
      + * 
      + * + * @param {!(webdriver.Session|webdriver.promise.Promise)} session Either a + * known session or a promise that will be resolved to a session. + * @param {!webdriver.CommandExecutor} executor The executor to use when + * sending commands to the browser. + * @param {webdriver.promise.ControlFlow=} opt_flow The flow to + * schedule commands through. Defaults to the active flow object. + * @constructor + */ +webdriver.WebDriver = function(session, executor, opt_flow) { + + /** @private {!(webdriver.Session|webdriver.promise.Promise)} */ + this.session_ = session; + + /** @private {!webdriver.CommandExecutor} */ + this.executor_ = executor; + + /** @private {!webdriver.promise.ControlFlow} */ + this.flow_ = opt_flow || webdriver.promise.controlFlow(); +}; + + +/** + * Creates a new WebDriver client for an existing session. + * @param {!webdriver.CommandExecutor} executor Command executor to use when + * querying for session details. + * @param {string} sessionId ID of the session to attach to. + * @return {!webdriver.WebDriver} A new client for the specified session. + */ +webdriver.WebDriver.attachToSession = function(executor, sessionId) { + return webdriver.WebDriver.acquireSession_(executor, + new webdriver.Command(webdriver.CommandName.DESCRIBE_SESSION). + setParameter('sessionId', sessionId), + 'WebDriver.attachToSession()'); +}; + + +/** + * Creates a new WebDriver session. + * @param {!webdriver.CommandExecutor} executor The executor to create the new + * session with. + * @param {!webdriver.Capabilities} desiredCapabilities The desired + * capabilities for the new session. + * @return {!webdriver.WebDriver} The driver for the newly created session. + */ +webdriver.WebDriver.createSession = function(executor, desiredCapabilities) { + return webdriver.WebDriver.acquireSession_(executor, + new webdriver.Command(webdriver.CommandName.NEW_SESSION). + setParameter('desiredCapabilities', desiredCapabilities), + 'WebDriver.createSession()'); +}; + + +/** + * Sends a command to the server that is expected to return the details for a + * {@link webdriver.Session}. This may either be an existing session, or a + * newly created one. + * @param {!webdriver.CommandExecutor} executor Command executor to use when + * querying for session details. + * @param {!webdriver.Command} command The command to send to fetch the session + * details. + * @param {string} description A descriptive debug label for this action. + * @return {!webdriver.WebDriver} A new WebDriver client for the session. + * @private + */ +webdriver.WebDriver.acquireSession_ = function(executor, command, description) { + var session = webdriver.promise.controlFlow().execute(function() { + return webdriver.WebDriver.executeCommand_(executor, command). + then(function(response) { + bot.response.checkResponse(response); + return new webdriver.Session(response['sessionId'], + response['value']); + }); + }, description); + return new webdriver.WebDriver(session, executor); +}; + + +/** + * Converts an object to its JSON representation in the WebDriver wire protocol. + * When converting values of type object, the following steps will be taken: + *
        + *
      1. if the object provides a "toWireValue" function, the return value will + * be returned in its fully resolved state (e.g. this function may return + * promise values)
      2. + *
      3. if the object provides a "toJSON" function, the return value of this + * function will be returned
      4. + *
      5. otherwise, the value of each key will be recursively converted according + * to the rules above.
      6. + *
      + * + * @param {*} obj The object to convert. + * @return {!webdriver.promise.Promise} A promise that will resolve to the + * input value's JSON representation. + * @private + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol + */ +webdriver.WebDriver.toWireValue_ = function(obj) { + switch (goog.typeOf(obj)) { + case 'array': + return webdriver.promise.fullyResolved( + goog.array.map(/** @type {!Array} */ (obj), + webdriver.WebDriver.toWireValue_)); + case 'object': + if (goog.isFunction(obj.toWireValue)) { + return webdriver.promise.fullyResolved(obj.toWireValue()); + } + if (goog.isFunction(obj.toJSON)) { + return webdriver.promise.fulfilled(obj.toJSON()); + } + if (goog.isNumber(obj.nodeType) && goog.isString(obj.nodeName)) { + throw Error([ + 'Invalid argument type: ', obj.nodeName, '(', obj.nodeType, ')' + ].join('')); + } + return webdriver.promise.fullyResolved( + goog.object.map(/** @type {!Object} */ (obj), + webdriver.WebDriver.toWireValue_)); + case 'function': + return webdriver.promise.fulfilled('' + obj); + case 'undefined': + return webdriver.promise.fulfilled(null); + default: + return webdriver.promise.fulfilled(obj); + } +}; + + +/** + * Converts a value from its JSON representation according to the WebDriver wire + * protocol. Any JSON object containing a + * {@code webdriver.WebElement.ELEMENT_KEY} key will be decoded to a + * {@code webdriver.WebElement} object. All other values will be passed through + * as is. + * @param {!webdriver.WebDriver} driver The driver instance to use as the + * parent of any unwrapped {@code webdriver.WebElement} values. + * @param {*} value The value to convert. + * @return {*} The converted value. + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol + * @private + */ +webdriver.WebDriver.fromWireValue_ = function(driver, value) { + if (goog.isArray(value)) { + value = goog.array.map(/**@type {goog.array.ArrayLike}*/ (value), + goog.partial(webdriver.WebDriver.fromWireValue_, driver)); + } else if (value && goog.isObject(value) && !goog.isFunction(value)) { + if (webdriver.WebElement.ELEMENT_KEY in value) { + value = new webdriver.WebElement(driver, + value[webdriver.WebElement.ELEMENT_KEY]); + } else { + value = goog.object.map(/**@type {!Object}*/ (value), + goog.partial(webdriver.WebDriver.fromWireValue_, driver)); + } + } + return value; +}; + + +/** + * Translates a command to its wire-protocol representation before passing it + * to the given {@code executor} for execution. + * @param {!webdriver.CommandExecutor} executor The executor to use. + * @param {!webdriver.Command} command The command to execute. + * @return {!webdriver.promise.Promise} A promise that will resolve with the + * command response. + * @private + */ +webdriver.WebDriver.executeCommand_ = function(executor, command) { + return webdriver.promise.fullyResolved(command.getParameters()). + then(webdriver.WebDriver.toWireValue_). + then(function(parameters) { + command.setParameters(parameters); + return webdriver.promise.checkedNodeCall( + goog.bind(executor.execute, executor, command)); + }); +}; + + +/** + * @return {!webdriver.promise.ControlFlow} The control flow used by this + * instance. + */ +webdriver.WebDriver.prototype.controlFlow = function() { + return this.flow_; +}; + + +/** + * Schedules a {@code webdriver.Command} to be executed by this driver's + * {@code webdriver.CommandExecutor}. + * @param {!webdriver.Command} command The command to schedule. + * @param {string} description A description of the command for debugging. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * with the command result. + * @template T + */ +webdriver.WebDriver.prototype.schedule = function(command, description) { + var self = this; + + checkHasNotQuit(); + command.setParameter('sessionId', this.session_); + + var flow = this.flow_; + return flow.execute(function() { + // A call to WebDriver.quit() may have been scheduled in the same event + // loop as this |command|, which would prevent us from detecting that the + // driver has quit above. Therefore, we need to make another quick check. + // We still check above so we can fail as early as possible. + checkHasNotQuit(); + return webdriver.WebDriver.executeCommand_(self.executor_, command); + }, description).then(function(response) { + try { + bot.response.checkResponse(response); + } catch (ex) { + var value = response['value']; + if (ex.code === bot.ErrorCode.MODAL_DIALOG_OPENED) { + var text = value && value['alert'] ? value['alert']['text'] : ''; + throw new webdriver.UnhandledAlertError(ex.message, + new webdriver.Alert(self, text)); + } + throw ex; + } + return webdriver.WebDriver.fromWireValue_(self, response['value']); + }); + + function checkHasNotQuit() { + if (!self.session_) { + throw new Error('This driver instance does not have a valid session ID ' + + '(did you call WebDriver.quit()?) and may no longer be ' + + 'used.'); + } + } +}; + + +// ---------------------------------------------------------------------------- +// Client command functions: +// ---------------------------------------------------------------------------- + + +/** + * @return {!webdriver.promise.Promise.} A promise for this + * client's session. + */ +webdriver.WebDriver.prototype.getSession = function() { + return webdriver.promise.when(this.session_); +}; + + +/** + * @return {!webdriver.promise.Promise.} A promise + * that will resolve with the this instance's capabilities. + */ +webdriver.WebDriver.prototype.getCapabilities = function() { + return webdriver.promise.when(this.session_, function(session) { + return session.getCapabilities(); + }); +}; + + +/** + * Schedules a command to quit the current session. After calling quit, this + * instance will be invalidated and may no longer be used to issue commands + * against the browser. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the command has completed. + */ +webdriver.WebDriver.prototype.quit = function() { + var result = this.schedule( + new webdriver.Command(webdriver.CommandName.QUIT), + 'WebDriver.quit()'); + // Delete our session ID when the quit command finishes; this will allow us to + // throw an error when attemnpting to use a driver post-quit. + return result.thenFinally(goog.bind(function() { + delete this.session_; + }, this)); +}; + + +/** + * Creates a new action sequence using this driver. The sequence will not be + * scheduled for execution until {@link webdriver.ActionSequence#perform} is + * called. Example: + *
      
      + *   driver.actions().
      + *       mouseDown(element1).
      + *       mouseMove(element2).
      + *       mouseUp().
      + *       perform();
      + * 
      + * @return {!webdriver.ActionSequence} A new action sequence for this instance. + */ +webdriver.WebDriver.prototype.actions = function() { + return new webdriver.ActionSequence(this); +}; + + +/** + * Schedules a command to execute JavaScript in the context of the currently + * selected frame or window. The script fragment will be executed as the body + * of an anonymous function. If the script is provided as a function object, + * that function will be converted to a string for injection into the target + * window. + * + * Any arguments provided in addition to the script will be included as script + * arguments and may be referenced using the {@code arguments} object. + * Arguments may be a boolean, number, string, or {@code webdriver.WebElement}. + * Arrays and objects may also be used as script arguments as long as each item + * adheres to the types previously mentioned. + * + * The script may refer to any variables accessible from the current window. + * Furthermore, the script will execute in the window's context, thus + * {@code document} may be used to refer to the current document. Any local + * variables will not be available once the script has finished executing, + * though global variables will persist. + * + * If the script has a return value (i.e. if the script contains a return + * statement), then the following steps will be taken for resolving this + * functions return value: + *
        + *
      • For a HTML element, the value will resolve to a + * {@code webdriver.WebElement}
      • + *
      • Null and undefined return values will resolve to null
      • + *
      • Booleans, numbers, and strings will resolve as is
      • + *
      • Functions will resolve to their string representation
      • + *
      • For arrays and objects, each member item will be converted according to + * the rules above
      • + *
      + * + * @param {!(string|Function)} script The script to execute. + * @param {...*} var_args The arguments to pass to the script. + * @return {!webdriver.promise.Promise.} A promise that will resolve to the + * scripts return value. + * @template T + */ +webdriver.WebDriver.prototype.executeScript = function(script, var_args) { + if (goog.isFunction(script)) { + script = 'return (' + script + ').apply(null, arguments);'; + } + return this.schedule( + new webdriver.Command(webdriver.CommandName.EXECUTE_SCRIPT). + setParameter('script', script). + setParameter('args', goog.array.slice(arguments, 1)), + 'WebDriver.executeScript()'); +}; + + +/** + * Schedules a command to execute asynchronous JavaScript in the context of the + * currently selected frame or window. The script fragment will be executed as + * the body of an anonymous function. If the script is provided as a function + * object, that function will be converted to a string for injection into the + * target window. + * + * Any arguments provided in addition to the script will be included as script + * arguments and may be referenced using the {@code arguments} object. + * Arguments may be a boolean, number, string, or {@code webdriver.WebElement}. + * Arrays and objects may also be used as script arguments as long as each item + * adheres to the types previously mentioned. + * + * Unlike executing synchronous JavaScript with + * {@code webdriver.WebDriver.prototype.executeScript}, scripts executed with + * this function must explicitly signal they are finished by invoking the + * provided callback. This callback will always be injected into the + * executed function as the last argument, and thus may be referenced with + * {@code arguments[arguments.length - 1]}. The following steps will be taken + * for resolving this functions return value against the first argument to the + * script's callback function: + *
        + *
      • For a HTML element, the value will resolve to a + * {@code webdriver.WebElement}
      • + *
      • Null and undefined return values will resolve to null
      • + *
      • Booleans, numbers, and strings will resolve as is
      • + *
      • Functions will resolve to their string representation
      • + *
      • For arrays and objects, each member item will be converted according to + * the rules above
      • + *
      + * + * Example #1: Performing a sleep that is synchronized with the currently + * selected window: + *
      + * var start = new Date().getTime();
      + * driver.executeAsyncScript(
      + *     'window.setTimeout(arguments[arguments.length - 1], 500);').
      + *     then(function() {
      + *       console.log('Elapsed time: ' + (new Date().getTime() - start) + ' ms');
      + *     });
      + * 
      + * + * Example #2: Synchronizing a test with an AJAX application: + *
      + * var button = driver.findElement(By.id('compose-button'));
      + * button.click();
      + * driver.executeAsyncScript(
      + *     'var callback = arguments[arguments.length - 1];' +
      + *     'mailClient.getComposeWindowWidget().onload(callback);');
      + * driver.switchTo().frame('composeWidget');
      + * driver.findElement(By.id('to')).sendKEys('dog@example.com');
      + * 
      + * + * Example #3: Injecting a XMLHttpRequest and waiting for the result. In this + * example, the inject script is specified with a function literal. When using + * this format, the function is converted to a string for injection, so it + * should not reference any symbols not defined in the scope of the page under + * test. + *
      + * driver.executeAsyncScript(function() {
      + *   var callback = arguments[arguments.length - 1];
      + *   var xhr = new XMLHttpRequest();
      + *   xhr.open("GET", "/resource/data.json", true);
      + *   xhr.onreadystatechange = function() {
      + *     if (xhr.readyState == 4) {
      + *       callback(xhr.resposneText);
      + *     }
      + *   }
      + *   xhr.send('');
      + * }).then(function(str) {
      + *   console.log(JSON.parse(str)['food']);
      + * });
      + * 
      + * + * @param {!(string|Function)} script The script to execute. + * @param {...*} var_args The arguments to pass to the script. + * @return {!webdriver.promise.Promise.} A promise that will resolve to the + * scripts return value. + * @template T + */ +webdriver.WebDriver.prototype.executeAsyncScript = function(script, var_args) { + if (goog.isFunction(script)) { + script = 'return (' + script + ').apply(null, arguments);'; + } + return this.schedule( + new webdriver.Command(webdriver.CommandName.EXECUTE_ASYNC_SCRIPT). + setParameter('script', script). + setParameter('args', goog.array.slice(arguments, 1)), + 'WebDriver.executeScript()'); +}; + + +/** + * Schedules a command to execute a custom function. + * @param {function(...): (T|webdriver.promise.Promise.)} fn The function to + * execute. + * @param {Object=} opt_scope The object in whose scope to execute the function. + * @param {...*} var_args Any arguments to pass to the function. + * @return {!webdriver.promise.Promise.} A promise that will be resolved' + * with the function's result. + * @template T + */ +webdriver.WebDriver.prototype.call = function(fn, opt_scope, var_args) { + var args = goog.array.slice(arguments, 2); + var flow = this.flow_; + return flow.execute(function() { + return webdriver.promise.fullyResolved(args).then(function(args) { + return fn.apply(opt_scope, args); + }); + }, 'WebDriver.call(' + (fn.name || 'function') + ')'); +}; + + +/** + * Schedules a command to wait for a condition to hold, as defined by some + * user supplied function. If any errors occur while evaluating the wait, they + * will be allowed to propagate. + * + *

      In the event a condition returns a {@link webdriver.promise.Promise}, the + * polling loop will wait for it to be resolved and use the resolved value for + * evaluating whether the condition has been satisfied. The resolution time for + * a promise is factored into whether a wait has timed out. + * + * @param {function():boolean} fn The function to evaluate as a wait condition. + * @param {number} timeout How long to wait for the condition to be true. + * @param {string=} opt_message An optional message to use if the wait times + * out. + * @return {!webdriver.promise.Promise} A promise that will be resolved when the + * wait condition has been satisfied. + */ +webdriver.WebDriver.prototype.wait = function(fn, timeout, opt_message) { + return this.flow_.wait(fn, timeout, opt_message); +}; + + +/** + * Schedules a command to make the driver sleep for the given amount of time. + * @param {number} ms The amount of time, in milliseconds, to sleep. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the sleep has finished. + */ +webdriver.WebDriver.prototype.sleep = function(ms) { + return this.flow_.timeout(ms, 'WebDriver.sleep(' + ms + ')'); +}; + + +/** + * Schedules a command to retrieve they current window handle. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with the current window handle. + */ +webdriver.WebDriver.prototype.getWindowHandle = function() { + return this.schedule( + new webdriver.Command(webdriver.CommandName.GET_CURRENT_WINDOW_HANDLE), + 'WebDriver.getWindowHandle()'); +}; + + +/** + * Schedules a command to retrieve the current list of available window handles. + * @return {!webdriver.promise.Promise.>} A promise that will + * be resolved with an array of window handles. + */ +webdriver.WebDriver.prototype.getAllWindowHandles = function() { + return this.schedule( + new webdriver.Command(webdriver.CommandName.GET_WINDOW_HANDLES), + 'WebDriver.getAllWindowHandles()'); +}; + + +/** + * Schedules a command to retrieve the current page's source. The page source + * returned is a representation of the underlying DOM: do not expect it to be + * formatted or escaped in the same way as the response sent from the web + * server. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with the current page source. + */ +webdriver.WebDriver.prototype.getPageSource = function() { + return this.schedule( + new webdriver.Command(webdriver.CommandName.GET_PAGE_SOURCE), + 'WebDriver.getAllWindowHandles()'); +}; + + +/** + * Schedules a command to close the current window. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when this command has completed. + */ +webdriver.WebDriver.prototype.close = function() { + return this.schedule(new webdriver.Command(webdriver.CommandName.CLOSE), + 'WebDriver.close()'); +}; + + +/** + * Schedules a command to navigate to the given URL. + * @param {string} url The fully qualified URL to open. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the document has finished loading. + */ +webdriver.WebDriver.prototype.get = function(url) { + return this.navigate().to(url); +}; + + +/** + * Schedules a command to retrieve the URL of the current page. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with the current URL. + */ +webdriver.WebDriver.prototype.getCurrentUrl = function() { + return this.schedule( + new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL), + 'WebDriver.getCurrentUrl()'); +}; + + +/** + * Schedules a command to retrieve the current page's title. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with the current page's title. + */ +webdriver.WebDriver.prototype.getTitle = function() { + return this.schedule(new webdriver.Command(webdriver.CommandName.GET_TITLE), + 'WebDriver.getTitle()'); +}; + + +/** + * Schedule a command to find an element on the page. If the element cannot be + * found, a {@link bot.ErrorCode.NO_SUCH_ELEMENT} result will be returned + * by the driver. Unlike other commands, this error cannot be suppressed. In + * other words, scheduling a command to find an element doubles as an assert + * that the element is present on the page. To test whether an element is + * present on the page, use {@link #isElementPresent} instead. + * + *

      The search criteria for an element may be defined using one of the + * factories in the {@link webdriver.By} namespace, or as a short-hand + * {@link webdriver.By.Hash} object. For example, the following two statements + * are equivalent: + *

      + * var e1 = driver.findElement(By.id('foo'));
      + * var e2 = driver.findElement({id:'foo'});
      + * 
      + * + *

      You may also provide a custom locator function, which takes as input + * this WebDriver instance and returns a {@link webdriver.WebElement}, or a + * promise that will resolve to a WebElement. For example, to find the first + * visible link on a page, you could write: + *

      + * var link = driver.findElement(firstVisibleLink);
      + *
      + * function firstVisibleLink(driver) {
      + *   var links = driver.findElements(By.tagName('a'));
      + *   return webdriver.promise.filter(links, function(link) {
      + *     return links.isDisplayed();
      + *   }).then(function(visibleLinks) {
      + *     return visibleLinks[0];
      + *   });
      + * }
      + * 
      + * + *

      When running in the browser, a WebDriver cannot manipulate DOM elements + * directly; it may do so only through a {@link webdriver.WebElement} reference. + * This function may be used to generate a WebElement from a DOM element. A + * reference to the DOM element will be stored in a known location and this + * driver will attempt to retrieve it through {@link #executeScript}. If the + * element cannot be found (eg, it belongs to a different document than the + * one this instance is currently focused on), a + * {@link bot.ErrorCode.NO_SUCH_ELEMENT} error will be returned. + * + * @param {!(webdriver.Locator|webdriver.By.Hash|Element|Function)} locator The + * locator to use. + * @return {!webdriver.WebElement} A WebElement that can be used to issue + * commands against the located element. If the element is not found, the + * element will be invalidated and all scheduled commands aborted. + */ +webdriver.WebDriver.prototype.findElement = function(locator) { + var id; + if ('nodeType' in locator && 'ownerDocument' in locator) { + var element = /** @type {!Element} */ (locator); + id = this.findDomElement_(element).then(function(element) { + if (!element) { + throw new bot.Error(bot.ErrorCode.NO_SUCH_ELEMENT, + 'Unable to locate element. Is WebDriver focused on its ' + + 'ownerDocument\'s frame?'); + } + return element; + }); + } else { + locator = webdriver.Locator.checkLocator(locator); + if (goog.isFunction(locator)) { + id = this.findElementInternal_(locator, this); + } else { + var command = new webdriver.Command(webdriver.CommandName.FIND_ELEMENT). + setParameter('using', locator.using). + setParameter('value', locator.value); + id = this.schedule(command, 'WebDriver.findElement(' + locator + ')'); + } + } + return new webdriver.WebElement(this, id); +}; + + +/** + * @param {!Function} locatorFn The locator function to use. + * @param {!(webdriver.WebDriver|webdriver.WebElement)} context The search + * context. + * @return {!webdriver.promise.Promise.} A + * promise that will resolve to a list of WebElements. + * @private + */ +webdriver.WebDriver.prototype.findElementInternal_ = function( + locatorFn, context) { + return this.call(goog.partial(locatorFn, context)).then(function(result) { + if (goog.isArray(result)) { + result = result[0]; + } + if (!(result instanceof webdriver.WebElement)) { + throw new TypeError('Custom locator did not return a WebElement'); + } + return result; + }); +}; + + +/** + * Locates a DOM element so that commands may be issued against it using the + * {@link webdriver.WebElement} class. This is accomplished by storing a + * reference to the element in an object on the element's ownerDocument. + * {@link #executeScript} will then be used to create a WebElement from this + * reference. This requires this driver to currently be focused on the + * ownerDocument's window+frame. + + * @param {!Element} element The element to locate. + * @return {!webdriver.promise.Promise.} A promise that + * will be fulfilled with the located element, or null if the element + * could not be found. + * @private + */ +webdriver.WebDriver.prototype.findDomElement_ = function(element) { + var doc = element.ownerDocument; + var store = doc['$webdriver$'] = doc['$webdriver$'] || {}; + var id = Math.floor(Math.random() * goog.now()).toString(36); + store[id] = element; + element[id] = id; + + function cleanUp() { + delete store[id]; + } + + function lookupElement(id) { + var store = document['$webdriver$']; + if (!store) { + return null; + } + + var element = store[id]; + if (!element || element[id] !== id) { + return null; + } + return element; + } + + /** @type {!webdriver.promise.Promise.} */ + var foundElement = this.executeScript(lookupElement, id); + foundElement.thenFinally(cleanUp); + return foundElement; +}; + + +/** + * Schedules a command to test if an element is present on the page. + * + *

      If given a DOM element, this function will check if it belongs to the + * document the driver is currently focused on. Otherwise, the function will + * test if at least one element can be found with the given search criteria. + * + * @param {!(webdriver.Locator|webdriver.By.Hash|Element| + * Function)} locatorOrElement The locator to use, or the actual + * DOM element to be located by the server. + * @return {!webdriver.promise.Promise.} A promise that will resolve + * with whether the element is present on the page. + */ +webdriver.WebDriver.prototype.isElementPresent = function(locatorOrElement) { + if ('nodeType' in locatorOrElement && 'ownerDocument' in locatorOrElement) { + return this.findDomElement_(/** @type {!Element} */ (locatorOrElement)). + then(function(result) { return !!result; }); + } else { + return this.findElements.apply(this, arguments).then(function(result) { + return !!result.length; + }); + } +}; + + +/** + * Schedule a command to search for multiple elements on the page. + * + * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The locator + * strategy to use when searching for the element. + * @return {!webdriver.promise.Promise.>} A + * promise that will resolve to an array of WebElements. + */ +webdriver.WebDriver.prototype.findElements = function(locator) { + locator = webdriver.Locator.checkLocator(locator); + if (goog.isFunction(locator)) { + return this.findElementsInternal_(locator, this); + } else { + var command = new webdriver.Command(webdriver.CommandName.FIND_ELEMENTS). + setParameter('using', locator.using). + setParameter('value', locator.value); + return this.schedule(command, 'WebDriver.findElements(' + locator + ')'); + } +}; + + +/** + * @param {!Function} locatorFn The locator function to use. + * @param {!(webdriver.WebDriver|webdriver.WebElement)} context The search + * context. + * @return {!webdriver.promise.Promise.>} A + * promise that will resolve to an array of WebElements. + * @private + */ +webdriver.WebDriver.prototype.findElementsInternal_ = function( + locatorFn, context) { + return this.call(goog.partial(locatorFn, context)).then(function(result) { + if (result instanceof webdriver.WebElement) { + return [result]; + } + + if (!goog.isArray(result)) { + return []; + } + + return goog.array.filter(result, function(item) { + return item instanceof webdriver.WebElement; + }); + }); +}; + + +/** + * Schedule a command to take a screenshot. The driver makes a best effort to + * return a screenshot of the following, in order of preference: + *

        + *
      1. Entire page + *
      2. Current window + *
      3. Visible portion of the current frame + *
      4. The screenshot of the entire display containing the browser + *
      + * + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved to the screenshot as a base-64 encoded PNG. + */ +webdriver.WebDriver.prototype.takeScreenshot = function() { + return this.schedule(new webdriver.Command(webdriver.CommandName.SCREENSHOT), + 'WebDriver.takeScreenshot()'); +}; + + +/** + * @return {!webdriver.WebDriver.Options} The options interface for this + * instance. + */ +webdriver.WebDriver.prototype.manage = function() { + return new webdriver.WebDriver.Options(this); +}; + + +/** + * @return {!webdriver.WebDriver.Navigation} The navigation interface for this + * instance. + */ +webdriver.WebDriver.prototype.navigate = function() { + return new webdriver.WebDriver.Navigation(this); +}; + + +/** + * @return {!webdriver.WebDriver.TargetLocator} The target locator interface for + * this instance. + */ +webdriver.WebDriver.prototype.switchTo = function() { + return new webdriver.WebDriver.TargetLocator(this); +}; + + + +/** + * Interface for navigating back and forth in the browser history. + * @param {!webdriver.WebDriver} driver The parent driver. + * @constructor + */ +webdriver.WebDriver.Navigation = function(driver) { + + /** @private {!webdriver.WebDriver} */ + this.driver_ = driver; +}; + + +/** + * Schedules a command to navigate to a new URL. + * @param {string} url The URL to navigate to. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the URL has been loaded. + */ +webdriver.WebDriver.Navigation.prototype.to = function(url) { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.GET). + setParameter('url', url), + 'WebDriver.navigate().to(' + url + ')'); +}; + + +/** + * Schedules a command to move backwards in the browser history. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the navigation event has completed. + */ +webdriver.WebDriver.Navigation.prototype.back = function() { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.GO_BACK), + 'WebDriver.navigate().back()'); +}; + + +/** + * Schedules a command to move forwards in the browser history. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the navigation event has completed. + */ +webdriver.WebDriver.Navigation.prototype.forward = function() { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.GO_FORWARD), + 'WebDriver.navigate().forward()'); +}; + + +/** + * Schedules a command to refresh the current page. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the navigation event has completed. + */ +webdriver.WebDriver.Navigation.prototype.refresh = function() { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.REFRESH), + 'WebDriver.navigate().refresh()'); +}; + + + +/** + * Provides methods for managing browser and driver state. + * @param {!webdriver.WebDriver} driver The parent driver. + * @constructor + */ +webdriver.WebDriver.Options = function(driver) { + + /** @private {!webdriver.WebDriver} */ + this.driver_ = driver; +}; + + +/** + * A JSON description of a browser cookie. + * @typedef {{ + * name: string, + * value: string, + * path: (string|undefined), + * domain: (string|undefined), + * secure: (boolean|undefined), + * expiry: (number|undefined) + * }} + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object + */ +webdriver.WebDriver.Options.Cookie; + + +/** + * Schedules a command to add a cookie. + * @param {string} name The cookie name. + * @param {string} value The cookie value. + * @param {string=} opt_path The cookie path. + * @param {string=} opt_domain The cookie domain. + * @param {boolean=} opt_isSecure Whether the cookie is secure. + * @param {(number|!Date)=} opt_expiry When the cookie expires. If specified as + * a number, should be in milliseconds since midnight, January 1, 1970 UTC. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the cookie has been added to the page. + */ +webdriver.WebDriver.Options.prototype.addCookie = function( + name, value, opt_path, opt_domain, opt_isSecure, opt_expiry) { + // We do not allow '=' or ';' in the name. + if (/[;=]/.test(name)) { + throw Error('Invalid cookie name "' + name + '"'); + } + + // We do not allow ';' in value. + if (/;/.test(value)) { + throw Error('Invalid cookie value "' + value + '"'); + } + + var cookieString = name + '=' + value + + (opt_domain ? ';domain=' + opt_domain : '') + + (opt_path ? ';path=' + opt_path : '') + + (opt_isSecure ? ';secure' : ''); + + var expiry; + if (goog.isDef(opt_expiry)) { + var expiryDate; + if (goog.isNumber(opt_expiry)) { + expiryDate = new Date(opt_expiry); + } else { + expiryDate = /** @type {!Date} */ (opt_expiry); + opt_expiry = expiryDate.getTime(); + } + cookieString += ';expires=' + expiryDate.toUTCString(); + // Convert from milliseconds to seconds. + expiry = Math.floor(/** @type {number} */ (opt_expiry) / 1000); + } + + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.ADD_COOKIE). + setParameter('cookie', { + 'name': name, + 'value': value, + 'path': opt_path, + 'domain': opt_domain, + 'secure': !!opt_isSecure, + 'expiry': expiry + }), + 'WebDriver.manage().addCookie(' + cookieString + ')'); +}; + + +/** + * Schedules a command to delete all cookies visible to the current page. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when all cookies have been deleted. + */ +webdriver.WebDriver.Options.prototype.deleteAllCookies = function() { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.DELETE_ALL_COOKIES), + 'WebDriver.manage().deleteAllCookies()'); +}; + + +/** + * Schedules a command to delete the cookie with the given name. This command is + * a no-op if there is no cookie with the given name visible to the current + * page. + * @param {string} name The name of the cookie to delete. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the cookie has been deleted. + */ +webdriver.WebDriver.Options.prototype.deleteCookie = function(name) { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.DELETE_COOKIE). + setParameter('name', name), + 'WebDriver.manage().deleteCookie(' + name + ')'); +}; + + +/** + * Schedules a command to retrieve all cookies visible to the current page. + * Each cookie will be returned as a JSON object as described by the WebDriver + * wire protocol. + * @return {!webdriver.promise.Promise.< + * !Array.>} A promise that will be + * resolved with the cookies visible to the current page. + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object + */ +webdriver.WebDriver.Options.prototype.getCookies = function() { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.GET_ALL_COOKIES), + 'WebDriver.manage().getCookies()'); +}; + + +/** + * Schedules a command to retrieve the cookie with the given name. Returns null + * if there is no such cookie. The cookie will be returned as a JSON object as + * described by the WebDriver wire protocol. + * @param {string} name The name of the cookie to retrieve. + * @return {!webdriver.promise.Promise.} A + * promise that will be resolved with the named cookie, or {@code null} + * if there is no such cookie. + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object + */ +webdriver.WebDriver.Options.prototype.getCookie = function(name) { + return this.getCookies().then(function(cookies) { + return goog.array.find(cookies, function(cookie) { + return cookie && cookie['name'] == name; + }); + }); +}; + + +/** + * @return {!webdriver.WebDriver.Logs} The interface for managing driver + * logs. + */ +webdriver.WebDriver.Options.prototype.logs = function() { + return new webdriver.WebDriver.Logs(this.driver_); +}; + + +/** + * @return {!webdriver.WebDriver.Timeouts} The interface for managing driver + * timeouts. + */ +webdriver.WebDriver.Options.prototype.timeouts = function() { + return new webdriver.WebDriver.Timeouts(this.driver_); +}; + + +/** + * @return {!webdriver.WebDriver.Window} The interface for managing the + * current window. + */ +webdriver.WebDriver.Options.prototype.window = function() { + return new webdriver.WebDriver.Window(this.driver_); +}; + + + +/** + * An interface for managing timeout behavior for WebDriver instances. + * @param {!webdriver.WebDriver} driver The parent driver. + * @constructor + */ +webdriver.WebDriver.Timeouts = function(driver) { + + /** @private {!webdriver.WebDriver} */ + this.driver_ = driver; +}; + + +/** + * Specifies the amount of time the driver should wait when searching for an + * element if it is not immediately present. + *

      + * When searching for a single element, the driver should poll the page + * until the element has been found, or this timeout expires before failing + * with a {@code bot.ErrorCode.NO_SUCH_ELEMENT} error. When searching + * for multiple elements, the driver should poll the page until at least one + * element has been found or this timeout has expired. + *

      + * Setting the wait timeout to 0 (its default value), disables implicit + * waiting. + *

      + * Increasing the implicit wait timeout should be used judiciously as it + * will have an adverse effect on test run time, especially when used with + * slower location strategies like XPath. + * + * @param {number} ms The amount of time to wait, in milliseconds. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the implicit wait timeout has been set. + */ +webdriver.WebDriver.Timeouts.prototype.implicitlyWait = function(ms) { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.IMPLICITLY_WAIT). + setParameter('ms', ms < 0 ? 0 : ms), + 'WebDriver.manage().timeouts().implicitlyWait(' + ms + ')'); +}; + + +/** + * Sets the amount of time to wait, in milliseconds, for an asynchronous script + * to finish execution before returning an error. If the timeout is less than or + * equal to 0, the script will be allowed to run indefinitely. + * + * @param {number} ms The amount of time to wait, in milliseconds. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the script timeout has been set. + */ +webdriver.WebDriver.Timeouts.prototype.setScriptTimeout = function(ms) { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.SET_SCRIPT_TIMEOUT). + setParameter('ms', ms < 0 ? 0 : ms), + 'WebDriver.manage().timeouts().setScriptTimeout(' + ms + ')'); +}; + + +/** + * Sets the amount of time to wait for a page load to complete before returning + * an error. If the timeout is negative, page loads may be indefinite. + * @param {number} ms The amount of time to wait, in milliseconds. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the timeout has been set. + */ +webdriver.WebDriver.Timeouts.prototype.pageLoadTimeout = function(ms) { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.SET_TIMEOUT). + setParameter('type', 'page load'). + setParameter('ms', ms), + 'WebDriver.manage().timeouts().pageLoadTimeout(' + ms + ')'); +}; + + + +/** + * An interface for managing the current window. + * @param {!webdriver.WebDriver} driver The parent driver. + * @constructor + */ +webdriver.WebDriver.Window = function(driver) { + + /** @private {!webdriver.WebDriver} */ + this.driver_ = driver; +}; + + +/** + * Retrieves the window's current position, relative to the top left corner of + * the screen. + * @return {!webdriver.promise.Promise.<{x: number, y: number}>} A promise that + * will be resolved with the window's position in the form of a + * {x:number, y:number} object literal. + */ +webdriver.WebDriver.Window.prototype.getPosition = function() { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.GET_WINDOW_POSITION). + setParameter('windowHandle', 'current'), + 'WebDriver.manage().window().getPosition()'); +}; + + +/** + * Repositions the current window. + * @param {number} x The desired horizontal position, relative to the left side + * of the screen. + * @param {number} y The desired vertical position, relative to the top of the + * of the screen. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the command has completed. + */ +webdriver.WebDriver.Window.prototype.setPosition = function(x, y) { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.SET_WINDOW_POSITION). + setParameter('windowHandle', 'current'). + setParameter('x', x). + setParameter('y', y), + 'WebDriver.manage().window().setPosition(' + x + ', ' + y + ')'); +}; + + +/** + * Retrieves the window's current size. + * @return {!webdriver.promise.Promise.<{width: number, height: number}>} A + * promise that will be resolved with the window's size in the form of a + * {width:number, height:number} object literal. + */ +webdriver.WebDriver.Window.prototype.getSize = function() { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.GET_WINDOW_SIZE). + setParameter('windowHandle', 'current'), + 'WebDriver.manage().window().getSize()'); +}; + + +/** + * Resizes the current window. + * @param {number} width The desired window width. + * @param {number} height The desired window height. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the command has completed. + */ +webdriver.WebDriver.Window.prototype.setSize = function(width, height) { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.SET_WINDOW_SIZE). + setParameter('windowHandle', 'current'). + setParameter('width', width). + setParameter('height', height), + 'WebDriver.manage().window().setSize(' + width + ', ' + height + ')'); +}; + + +/** + * Maximizes the current window. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the command has completed. + */ +webdriver.WebDriver.Window.prototype.maximize = function() { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.MAXIMIZE_WINDOW). + setParameter('windowHandle', 'current'), + 'WebDriver.manage().window().maximize()'); +}; + + +/** + * Interface for managing WebDriver log records. + * @param {!webdriver.WebDriver} driver The parent driver. + * @constructor + */ +webdriver.WebDriver.Logs = function(driver) { + + /** @private {!webdriver.WebDriver} */ + this.driver_ = driver; +}; + + +/** + * Fetches available log entries for the given type. + * + *

      Note that log buffers are reset after each call, meaning that + * available log entries correspond to those entries not yet returned for a + * given log type. In practice, this means that this call will return the + * available log entries since the last call, or from the start of the + * session. + * + * @param {!webdriver.logging.Type} type The desired log type. + * @return {!webdriver.promise.Promise.>} A + * promise that will resolve to a list of log entries for the specified + * type. + */ +webdriver.WebDriver.Logs.prototype.get = function(type) { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.GET_LOG). + setParameter('type', type), + 'WebDriver.manage().logs().get(' + type + ')'). + then(function(entries) { + return goog.array.map(entries, function(entry) { + if (!(entry instanceof webdriver.logging.Entry)) { + return new webdriver.logging.Entry( + entry['level'], entry['message'], entry['timestamp']); + } + return entry; + }); + }); +}; + + +/** + * Retrieves the log types available to this driver. + * @return {!webdriver.promise.Promise.>} A + * promise that will resolve to a list of available log types. + */ +webdriver.WebDriver.Logs.prototype.getAvailableLogTypes = function() { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.GET_AVAILABLE_LOG_TYPES), + 'WebDriver.manage().logs().getAvailableLogTypes()'); +}; + + + +/** + * An interface for changing the focus of the driver to another frame or window. + * @param {!webdriver.WebDriver} driver The parent driver. + * @constructor + */ +webdriver.WebDriver.TargetLocator = function(driver) { + + /** @private {!webdriver.WebDriver} */ + this.driver_ = driver; +}; + + +/** + * Schedules a command retrieve the {@code document.activeElement} element on + * the current document, or {@code document.body} if activeElement is not + * available. + * @return {!webdriver.WebElement} The active element. + */ +webdriver.WebDriver.TargetLocator.prototype.activeElement = function() { + var id = this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.GET_ACTIVE_ELEMENT), + 'WebDriver.switchTo().activeElement()'); + return new webdriver.WebElement(this.driver_, id); +}; + + +/** + * Schedules a command to switch focus of all future commands to the first frame + * on the page. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the driver has changed focus to the default content. + */ +webdriver.WebDriver.TargetLocator.prototype.defaultContent = function() { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.SWITCH_TO_FRAME). + setParameter('id', null), + 'WebDriver.switchTo().defaultContent()'); +}; + + +/** + * Schedules a command to switch the focus of all future commands to another + * frame on the page. + *

      + * If the frame is specified by a number, the command will switch to the frame + * by its (zero-based) index into the {@code window.frames} collection. + *

      + * If the frame is specified by a string, the command will select the frame by + * its name or ID. To select sub-frames, simply separate the frame names/IDs by + * dots. As an example, "main.child" will select the frame with the name "main" + * and then its child "child". + *

      + * If the specified frame can not be found, the deferred result will errback + * with a {@code bot.ErrorCode.NO_SUCH_FRAME} error. + * @param {string|number} nameOrIndex The frame locator. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the driver has changed focus to the specified frame. + */ +webdriver.WebDriver.TargetLocator.prototype.frame = function(nameOrIndex) { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.SWITCH_TO_FRAME). + setParameter('id', nameOrIndex), + 'WebDriver.switchTo().frame(' + nameOrIndex + ')'); +}; + + +/** + * Schedules a command to switch the focus of all future commands to another + * window. Windows may be specified by their {@code window.name} attribute or + * by its handle (as returned by {@code webdriver.WebDriver#getWindowHandles}). + *

      + * If the specificed window can not be found, the deferred result will errback + * with a {@code bot.ErrorCode.NO_SUCH_WINDOW} error. + * @param {string} nameOrHandle The name or window handle of the window to + * switch focus to. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the driver has changed focus to the specified window. + */ +webdriver.WebDriver.TargetLocator.prototype.window = function(nameOrHandle) { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.SWITCH_TO_WINDOW). + setParameter('name', nameOrHandle), + 'WebDriver.switchTo().window(' + nameOrHandle + ')'); +}; + + +/** + * Schedules a command to change focus to the active alert dialog. This command + * will return a {@link bot.ErrorCode.NO_MODAL_DIALOG_OPEN} error if a modal + * dialog is not currently open. + * @return {!webdriver.Alert} The open alert. + */ +webdriver.WebDriver.TargetLocator.prototype.alert = function() { + var text = this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.GET_ALERT_TEXT), + 'WebDriver.switchTo().alert()'); + return new webdriver.Alert(this.driver_, text); +}; + + +/** + * Simulate pressing many keys at once in a "chord". Takes a sequence of + * {@link webdriver.Key}s or strings, appends each of the values to a string, + * and adds the chord termination key ({@link webdriver.Key.NULL}) and returns + * the resultant string. + * + * Note: when the low-level webdriver key handlers see Keys.NULL, active + * modifier keys (CTRL/ALT/SHIFT/etc) release via a keyup event. + * + * @param {...string} var_args The key sequence to concatenate. + * @return {string} The null-terminated key sequence. + * @see http://code.google.com/p/webdriver/issues/detail?id=79 + */ +webdriver.Key.chord = function(var_args) { + var sequence = goog.array.reduce( + goog.array.slice(arguments, 0), + function(str, key) { + return str + key; + }, ''); + sequence += webdriver.Key.NULL; + return sequence; +}; + + +////////////////////////////////////////////////////////////////////////////// +// +// webdriver.WebElement +// +////////////////////////////////////////////////////////////////////////////// + + + +/** + * Represents a DOM element. WebElements can be found by searching from the + * document root using a {@code webdriver.WebDriver} instance, or by searching + * under another {@code webdriver.WebElement}: + *

      
      + *   driver.get('http://www.google.com');
      + *   var searchForm = driver.findElement(By.tagName('form'));
      + *   var searchBox = searchForm.findElement(By.name('q'));
      + *   searchBox.sendKeys('webdriver');
      + * 
      + * + * The WebElement is implemented as a promise for compatibility with the promise + * API. It will always resolve itself when its internal state has been fully + * resolved and commands may be issued against the element. This can be used to + * catch errors when an element cannot be located on the page: + *
      
      + *   driver.findElement(By.id('not-there')).then(function(element) {
      + *     alert('Found an element that was not expected to be there!');
      + *   }, function(error) {
      + *     alert('The element was not found, as expected');
      + *   });
      + * 
      + * + * @param {!webdriver.WebDriver} driver The parent WebDriver instance for this + * element. + * @param {!(string|webdriver.promise.Promise)} id Either the opaque ID for the + * underlying DOM element assigned by the server, or a promise that will + * resolve to that ID or another WebElement. + * @constructor + * @extends {webdriver.promise.Deferred} + */ +webdriver.WebElement = function(driver, id) { + webdriver.promise.Deferred.call(this, null, driver.controlFlow()); + + /** + * The parent WebDriver instance for this element. + * @private {!webdriver.WebDriver} + */ + this.driver_ = driver; + + // This class is responsible for resolving itself; delete the resolve and + // reject methods so they may not be accessed by consumers of this class. + var fulfill = goog.partial(this.fulfill, this); + var reject = this.reject; + delete this.promise; + delete this.fulfill; + delete this.reject; + + /** + * A promise that resolves to the JSON representation of this WebElement's + * ID, as defined by the WebDriver wire protocol. + * @private {!webdriver.promise.Promise.} + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol + */ + this.id_ = webdriver.promise.when(id, function(id) { + if (id instanceof webdriver.WebElement) { + return id.id_; + } else if (goog.isDef(id[webdriver.WebElement.ELEMENT_KEY])) { + return id; + } + + var json = {}; + json[webdriver.WebElement.ELEMENT_KEY] = id; + return json; + }); + + // This WebElement should not be resolved until its ID has been + // fully resolved. + this.id_.then(fulfill, reject); +}; +goog.inherits(webdriver.WebElement, webdriver.promise.Deferred); + + +/** + * Wire protocol definition of a WebElement ID. + * @typedef {{ELEMENT: string}} + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol + */ +webdriver.WebElement.Id; + + +/** + * The property key used in the wire protocol to indicate that a JSON object + * contains the ID of a WebElement. + * @type {string} + * @const + */ +webdriver.WebElement.ELEMENT_KEY = 'ELEMENT'; + + +/** + * Compares to WebElements for equality. + * @param {!webdriver.WebElement} a A WebElement. + * @param {!webdriver.WebElement} b A WebElement. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved to whether the two WebElements are equal. + */ +webdriver.WebElement.equals = function(a, b) { + if (a == b) { + return webdriver.promise.fulfilled(true); + } + return webdriver.promise.fullyResolved([a.id_, b.id_]).then(function(ids) { + // If the two element's have the same ID, they should be considered + // equal. Otherwise, they may still be equivalent, but we'll need to + // ask the server to check for us. + if (ids[0][webdriver.WebElement.ELEMENT_KEY] == + ids[1][webdriver.WebElement.ELEMENT_KEY]) { + return true; + } + + var command = new webdriver.Command( + webdriver.CommandName.ELEMENT_EQUALS); + command.setParameter('other', b); + return a.schedule_(command, 'webdriver.WebElement.equals()'); + }); +}; + + +/** + * @return {!webdriver.WebDriver} The parent driver for this instance. + */ +webdriver.WebElement.prototype.getDriver = function() { + return this.driver_; +}; + + +/** + * @return {!webdriver.promise.Promise.} A promise + * that resolves to this element's JSON representation as defined by the + * WebDriver wire protocol. + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol + */ +webdriver.WebElement.prototype.toWireValue = function() { + return this.id_; +}; + + +/** + * Schedules a command that targets this element with the parent WebDriver + * instance. Will ensure this element's ID is included in the command parameters + * under the "id" key. + * @param {!webdriver.Command} command The command to schedule. + * @param {string} description A description of the command for debugging. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * with the command result. + * @template T + * @see webdriver.WebDriver.prototype.schedule + * @private + */ +webdriver.WebElement.prototype.schedule_ = function(command, description) { + command.setParameter('id', this.id_); + return this.driver_.schedule(command, description); +}; + + +/** + * Schedule a command to find a descendant of this element. If the element + * cannot be found, a {@code bot.ErrorCode.NO_SUCH_ELEMENT} result will + * be returned by the driver. Unlike other commands, this error cannot be + * suppressed. In other words, scheduling a command to find an element doubles + * as an assert that the element is present on the page. To test whether an + * element is present on the page, use {@code #isElementPresent} instead. + * + *

      The search criteria for an element may be defined using one of the + * factories in the {@link webdriver.By} namespace, or as a short-hand + * {@link webdriver.By.Hash} object. For example, the following two statements + * are equivalent: + *

      + * var e1 = element.findElement(By.id('foo'));
      + * var e2 = element.findElement({id:'foo'});
      + * 
      + * + *

      You may also provide a custom locator function, which takes as input + * this WebDriver instance and returns a {@link webdriver.WebElement}, or a + * promise that will resolve to a WebElement. For example, to find the first + * visible link on a page, you could write: + *

      + * var link = element.findElement(firstVisibleLink);
      + *
      + * function firstVisibleLink(element) {
      + *   var links = element.findElements(By.tagName('a'));
      + *   return webdriver.promise.filter(links, function(link) {
      + *     return links.isDisplayed();
      + *   }).then(function(visibleLinks) {
      + *     return visibleLinks[0];
      + *   });
      + * }
      + * 
      + * + * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The + * locator strategy to use when searching for the element. + * @return {!webdriver.WebElement} A WebElement that can be used to issue + * commands against the located element. If the element is not found, the + * element will be invalidated and all scheduled commands aborted. + */ +webdriver.WebElement.prototype.findElement = function(locator) { + locator = webdriver.Locator.checkLocator(locator); + var id; + if (goog.isFunction(locator)) { + id = this.driver_.findElementInternal_(locator, this); + } else { + var command = new webdriver.Command( + webdriver.CommandName.FIND_CHILD_ELEMENT). + setParameter('using', locator.using). + setParameter('value', locator.value); + id = this.schedule_(command, 'WebElement.findElement(' + locator + ')'); + } + return new webdriver.WebElement(this.driver_, id); +}; + + +/** + * Schedules a command to test if there is at least one descendant of this + * element that matches the given search criteria. + * + * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The + * locator strategy to use when searching for the element. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with whether an element could be located on the page. + */ +webdriver.WebElement.prototype.isElementPresent = function(locator) { + return this.findElements(locator).then(function(result) { + return !!result.length; + }); +}; + + +/** + * Schedules a command to find all of the descendants of this element that + * match the given search criteria. + * + * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The + * locator strategy to use when searching for the elements. + * @return {!webdriver.promise.Promise.>} A + * promise that will resolve to an array of WebElements. + */ +webdriver.WebElement.prototype.findElements = function(locator) { + locator = webdriver.Locator.checkLocator(locator); + if (goog.isFunction(locator)) { + return this.driver_.findElementsInternal_(locator, this); + } else { + var command = new webdriver.Command( + webdriver.CommandName.FIND_CHILD_ELEMENTS). + setParameter('using', locator.using). + setParameter('value', locator.value); + return this.schedule_(command, 'WebElement.findElements(' + locator + ')'); + } +}; + + +/** + * Schedules a command to click on this element. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the click command has completed. + */ +webdriver.WebElement.prototype.click = function() { + return this.schedule_( + new webdriver.Command(webdriver.CommandName.CLICK_ELEMENT), + 'WebElement.click()'); +}; + + +/** + * Schedules a command to type a sequence on the DOM element represented by this + * instance. + *

      + * Modifier keys (SHIFT, CONTROL, ALT, META) are stateful; once a modifier is + * processed in the keysequence, that key state is toggled until one of the + * following occurs: + *

        + *
      • The modifier key is encountered again in the sequence. At this point the + * state of the key is toggled (along with the appropriate keyup/down events). + *
      • + *
      • The {@code webdriver.Key.NULL} key is encountered in the sequence. When + * this key is encountered, all modifier keys current in the down state are + * released (with accompanying keyup events). The NULL key can be used to + * simulate common keyboard shortcuts: + *
        + *     element.sendKeys("text was",
        + *                      webdriver.Key.CONTROL, "a", webdriver.Key.NULL,
        + *                      "now text is");
        + *     // Alternatively:
        + *     element.sendKeys("text was",
        + *                      webdriver.Key.chord(webdriver.Key.CONTROL, "a"),
        + *                      "now text is");
        + * 
      • + *
      • The end of the keysequence is encountered. When there are no more keys + * to type, all depressed modifier keys are released (with accompanying keyup + * events). + *
      • + *
      + * Note: On browsers where native keyboard events are not yet + * supported (e.g. Firefox on OS X), key events will be synthesized. Special + * punctionation keys will be synthesized according to a standard QWERTY en-us + * keyboard layout. + * + * @param {...string} var_args The sequence of keys to + * type. All arguments will be joined into a single sequence (var_args is + * permitted for convenience). + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when all keys have been typed. + */ +webdriver.WebElement.prototype.sendKeys = function(var_args) { + // Coerce every argument to a string. This protects us from users that + // ignore the jsdoc and give us a number (which ends up causing problems on + // the server, which requires strings). + var keys = webdriver.promise.fullyResolved(goog.array.slice(arguments, 0)). + then(function(args) { + return goog.array.map(goog.array.slice(args, 0), function(key) { + return key + ''; + }); + }); + return this.schedule_( + new webdriver.Command(webdriver.CommandName.SEND_KEYS_TO_ELEMENT). + setParameter('value', keys), + 'WebElement.sendKeys(' + keys + ')'); +}; + + +/** + * Schedules a command to query for the tag/node name of this element. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with the element's tag name. + */ +webdriver.WebElement.prototype.getTagName = function() { + return this.schedule_( + new webdriver.Command(webdriver.CommandName.GET_ELEMENT_TAG_NAME), + 'WebElement.getTagName()'); +}; + + +/** + * Schedules a command to query for the computed style of the element + * represented by this instance. If the element inherits the named style from + * its parent, the parent will be queried for its value. Where possible, color + * values will be converted to their hex representation (e.g. #00ff00 instead of + * rgb(0, 255, 0)). + *

      + * Warning: the value returned will be as the browser interprets it, so + * it may be tricky to form a proper assertion. + * + * @param {string} cssStyleProperty The name of the CSS style property to look + * up. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with the requested CSS value. + */ +webdriver.WebElement.prototype.getCssValue = function(cssStyleProperty) { + var name = webdriver.CommandName.GET_ELEMENT_VALUE_OF_CSS_PROPERTY; + return this.schedule_( + new webdriver.Command(name). + setParameter('propertyName', cssStyleProperty), + 'WebElement.getCssValue(' + cssStyleProperty + ')'); +}; + + +/** + * Schedules a command to query for the value of the given attribute of the + * element. Will return the current value, even if it has been modified after + * the page has been loaded. More exactly, this method will return the value of + * the given attribute, unless that attribute is not present, in which case the + * value of the property with the same name is returned. If neither value is + * set, null is returned (for example, the "value" property of a textarea + * element). The "style" attribute is converted as best can be to a + * text representation with a trailing semi-colon. The following are deemed to + * be "boolean" attributes and will return either "true" or null: + * + *

      async, autofocus, autoplay, checked, compact, complete, controls, declare, + * defaultchecked, defaultselected, defer, disabled, draggable, ended, + * formnovalidate, hidden, indeterminate, iscontenteditable, ismap, itemscope, + * loop, multiple, muted, nohref, noresize, noshade, novalidate, nowrap, open, + * paused, pubdate, readonly, required, reversed, scoped, seamless, seeking, + * selected, spellcheck, truespeed, willvalidate + * + *

      Finally, the following commonly mis-capitalized attribute/property names + * are evaluated as expected: + *

        + *
      • "class" + *
      • "readonly" + *
      + * @param {string} attributeName The name of the attribute to query. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with the attribute's value. The returned value will always be + * either a string or null. + */ +webdriver.WebElement.prototype.getAttribute = function(attributeName) { + return this.schedule_( + new webdriver.Command(webdriver.CommandName.GET_ELEMENT_ATTRIBUTE). + setParameter('name', attributeName), + 'WebElement.getAttribute(' + attributeName + ')'); +}; + + +/** + * Get the visible (i.e. not hidden by CSS) innerText of this element, including + * sub-elements, without any leading or trailing whitespace. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with the element's visible text. + */ +webdriver.WebElement.prototype.getText = function() { + return this.schedule_( + new webdriver.Command(webdriver.CommandName.GET_ELEMENT_TEXT), + 'WebElement.getText()'); +}; + + +/** + * Schedules a command to compute the size of this element's bounding box, in + * pixels. + * @return {!webdriver.promise.Promise.<{width: number, height: number}>} A + * promise that will be resolved with the element's size as a + * {@code {width:number, height:number}} object. + */ +webdriver.WebElement.prototype.getSize = function() { + return this.schedule_( + new webdriver.Command(webdriver.CommandName.GET_ELEMENT_SIZE), + 'WebElement.getSize()'); +}; + + +/** + * Schedules a command to compute the location of this element in page space. + * @return {!webdriver.promise.Promise.<{x: number, y: number}>} A promise that + * will be resolved to the element's location as a + * {@code {x:number, y:number}} object. + */ +webdriver.WebElement.prototype.getLocation = function() { + return this.schedule_( + new webdriver.Command(webdriver.CommandName.GET_ELEMENT_LOCATION), + 'WebElement.getLocation()'); +}; + + +/** + * Schedules a command to query whether the DOM element represented by this + * instance is enabled, as dicted by the {@code disabled} attribute. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with whether this element is currently enabled. + */ +webdriver.WebElement.prototype.isEnabled = function() { + return this.schedule_( + new webdriver.Command(webdriver.CommandName.IS_ELEMENT_ENABLED), + 'WebElement.isEnabled()'); +}; + + +/** + * Schedules a command to query whether this element is selected. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with whether this element is currently selected. + */ +webdriver.WebElement.prototype.isSelected = function() { + return this.schedule_( + new webdriver.Command(webdriver.CommandName.IS_ELEMENT_SELECTED), + 'WebElement.isSelected()'); +}; + + +/** + * Schedules a command to submit the form containing this element (or this + * element if it is a FORM element). This command is a no-op if the element is + * not contained in a form. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the form has been submitted. + */ +webdriver.WebElement.prototype.submit = function() { + return this.schedule_( + new webdriver.Command(webdriver.CommandName.SUBMIT_ELEMENT), + 'WebElement.submit()'); +}; + + +/** + * Schedules a command to clear the {@code value} of this element. This command + * has no effect if the underlying DOM element is neither a text INPUT element + * nor a TEXTAREA element. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when the element has been cleared. + */ +webdriver.WebElement.prototype.clear = function() { + return this.schedule_( + new webdriver.Command(webdriver.CommandName.CLEAR_ELEMENT), + 'WebElement.clear()'); +}; + + +/** + * Schedules a command to test whether this element is currently displayed. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with whether this element is currently visible on the page. + */ +webdriver.WebElement.prototype.isDisplayed = function() { + return this.schedule_( + new webdriver.Command(webdriver.CommandName.IS_ELEMENT_DISPLAYED), + 'WebElement.isDisplayed()'); +}; + + +/** + * Schedules a command to retrieve the outer HTML of this element. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with the element's outer HTML. + */ +webdriver.WebElement.prototype.getOuterHtml = function() { + return this.driver_.executeScript(function() { + var element = arguments[0]; + if ('outerHTML' in element) { + return element.outerHTML; + } else { + var div = element.ownerDocument.createElement('div'); + div.appendChild(element.cloneNode(true)); + return div.innerHTML; + } + }, this); +}; + + +/** + * Schedules a command to retrieve the inner HTML of this element. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with the element's inner HTML. + */ +webdriver.WebElement.prototype.getInnerHtml = function() { + return this.driver_.executeScript('return arguments[0].innerHTML', this); +}; + + + +/** + * Represents a modal dialog such as {@code alert}, {@code confirm}, or + * {@code prompt}. Provides functions to retrieve the message displayed with + * the alert, accept or dismiss the alert, and set the response text (in the + * case of {@code prompt}). + * @param {!webdriver.WebDriver} driver The driver controlling the browser this + * alert is attached to. + * @param {!(string|webdriver.promise.Promise.)} text Either the + * message text displayed with this alert, or a promise that will be + * resolved to said text. + * @constructor + * @extends {webdriver.promise.Deferred} + */ +webdriver.Alert = function(driver, text) { + goog.base(this, null, driver.controlFlow()); + + /** @private {!webdriver.WebDriver} */ + this.driver_ = driver; + + // This class is responsible for resolving itself; delete the resolve and + // reject methods so they may not be accessed by consumers of this class. + var fulfill = goog.partial(this.fulfill, this); + var reject = this.reject; + delete this.promise; + delete this.fulfill; + delete this.reject; + + /** @private {!webdriver.promise.Promise.} */ + this.text_ = webdriver.promise.when(text); + + // Make sure this instance is resolved when its displayed text is. + this.text_.then(fulfill, reject); +}; +goog.inherits(webdriver.Alert, webdriver.promise.Deferred); + + +/** + * Retrieves the message text displayed with this alert. For instance, if the + * alert were opened with alert("hello"), then this would return "hello". + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved to the text displayed with this alert. + */ +webdriver.Alert.prototype.getText = function() { + return this.text_; +}; + + +/** + * Accepts this alert. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when this command has completed. + */ +webdriver.Alert.prototype.accept = function() { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.ACCEPT_ALERT), + 'WebDriver.switchTo().alert().accept()'); +}; + + +/** + * Dismisses this alert. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when this command has completed. + */ +webdriver.Alert.prototype.dismiss = function() { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.DISMISS_ALERT), + 'WebDriver.switchTo().alert().dismiss()'); +}; + + +/** + * Sets the response text on this alert. This command will return an error if + * the underlying alert does not support response text (e.g. window.alert and + * window.confirm). + * @param {string} text The text to set. + * @return {!webdriver.promise.Promise.} A promise that will be resolved + * when this command has completed. + */ +webdriver.Alert.prototype.sendKeys = function(text) { + return this.driver_.schedule( + new webdriver.Command(webdriver.CommandName.SET_ALERT_TEXT). + setParameter('text', text), + 'WebDriver.switchTo().alert().sendKeys(' + text + ')'); +}; + + + +/** + * An error returned to indicate that there is an unhandled modal dialog on the + * current page. + * @param {string} message The error message. + * @param {!webdriver.Alert} alert The alert handle. + * @constructor + * @extends {bot.Error} + */ +webdriver.UnhandledAlertError = function(message, alert) { + goog.base(this, bot.ErrorCode.MODAL_DIALOG_OPENED, message); + + /** @private {!webdriver.Alert} */ + this.alert_ = alert; +}; +goog.inherits(webdriver.UnhandledAlertError, bot.Error); + + +/** + * @return {!webdriver.Alert} The open alert. + */ +webdriver.UnhandledAlertError.prototype.getAlert = function() { + return this.alert_; +}; diff --git a/node_modules/selenium-webdriver/net/index.js b/node_modules/selenium-webdriver/net/index.js new file mode 100644 index 0000000..94c4114 --- /dev/null +++ b/node_modules/selenium-webdriver/net/index.js @@ -0,0 +1,80 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var os = require('os'); + + +function getLoInterface() { + var name; + if (process.platform === 'darwin') { + name = 'lo0'; + } else if (process.platform === 'linux') { + name = 'lo'; + } + return name ? os.networkInterfaces()[name] : null; +} + + +/** + * Queries the system network interfaces for an IP address. + * @param {boolean} loopback Whether to find a loopback address. + * @param {string=} opt_family The IP family (IPv4 or IPv6). Defaults to IPv4. + * @return {string} The located IP address or undefined. + */ +function getAddress(loopback, opt_family) { + var family = opt_family || 'IPv4'; + var addresses = []; + + var interfaces; + if (loopback) { + var lo = getLoInterface(); + interfaces = lo ? [lo] : null; + } + interfaces = interfaces || os.networkInterfaces(); + for (var key in interfaces) { + interfaces[key].forEach(function(ipAddress) { + if (ipAddress.family === family && + ipAddress.internal === loopback) { + addresses.push(ipAddress.address); + } + }); + } + return addresses[0]; +} + + +// PUBLIC API + + +/** + * Retrieves the external IP address for this host. + * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4". + * @return {string} The IP address or undefined if not available. + */ +exports.getAddress = function(opt_family) { + return getAddress(false, opt_family); +}; + + +/** + * Retrieves a loopback address for this machine. + * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4". + * @return {string} The IP address or undefined if not available. + */ +exports.getLoopbackAddress = function(opt_family) { + return getAddress(true, opt_family); +}; diff --git a/node_modules/selenium-webdriver/net/portprober.js b/node_modules/selenium-webdriver/net/portprober.js new file mode 100644 index 0000000..ee57f12 --- /dev/null +++ b/node_modules/selenium-webdriver/net/portprober.js @@ -0,0 +1,213 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var exec = require('child_process').exec, + fs = require('fs'), + net = require('net'); + +var promise = require('../index').promise; + + +/** + * The IANA suggested ephemeral port range. + * @type {{min: number, max: number}} + * @const + * @see http://en.wikipedia.org/wiki/Ephemeral_ports + */ +var DEFAULT_IANA_RANGE = {min: 49152, max: 65535}; + + +/** + * The epheremal port range for the current system. Lazily computed on first + * access. + * @type {webdriver.promise.Promise.<{min: number, max: number}>} + */ +var systemRange = null; + + +/** + * Computes the ephemeral port range for the current system. This is based on + * http://stackoverflow.com/a/924337. + * @return {webdriver.promise.Promise.<{min: number, max: number}>} A promise + * that will resolve to the ephemeral port range of the current system. + */ +function findSystemPortRange() { + if (systemRange) { + return systemRange; + } + var range = process.platform === 'win32' ? + findWindowsPortRange() : findUnixPortRange(); + return systemRange = range.thenCatch(function() { + return DEFAULT_IANA_RANGE; + }); +} + + +/** + * Executes a command and returns its output if it succeeds. + * @param {string} cmd The command to execute. + * @return {!webdriver.promise.Promise} A promise that will resolve + * with the command's stdout data. + */ +function execute(cmd) { + var result = promise.defer(); + exec(cmd, function(err, stdout) { + if (err) { + result.reject(err); + } else { + result.fulfill(stdout); + } + }); + return result.promise; +} + + +/** + * Computes the ephemeral port range for a Unix-like system. + * @return {!webdriver.promise.Promise<{min: number, max: number}>} A promise + * that will resolve with the ephemeral port range on the current system. + */ +function findUnixPortRange() { + var cmd; + if (process.platform === 'sunos') { + cmd = + '/usr/sbin/ndd /dev/tcp tcp_smallest_anon_port tcp_largest_anon_port'; + } else if (fs.existsSync('/proc/sys/net/ipv4/ip_local_port_range')) { + // Linux + cmd = 'cat /proc/sys/net/ipv4/ip_local_port_range'; + } else { + cmd = 'sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last' + + ' | sed -e "s/.*:\\s*//"'; + } + + return execute(cmd).then(function(stdout) { + if (!stdout || !stdout.length) return DEFAULT_IANA_RANGE; + var range = stdout.trim().split(/\s+/).map(Number); + if (range.some(isNaN)) return DEFAULT_IANA_RANGE; + return {min: range[0], max: range[1]}; + }); +} + + +/** + * Computes the ephemeral port range for a Windows system. + * @return {!webdriver.promise.Promise<{min: number, max: number}>} A promise + * that will resolve with the ephemeral port range on the current system. + */ +function findWindowsPortRange() { + var deferredRange = promise.defer(); + // First, check if we're running on XP. If this initial command fails, + // we just fallback on the default IANA range. + return execute('cmd.exe /c ver').then(function(stdout) { + if (/Windows XP/.test(stdout)) { + // TODO: Try to read these values from the registry. + return {min: 1025, max: 5000}; + } else { + return execute('netsh int ipv4 show dynamicport tcp'). + then(function(stdout) { + /* > netsh int ipv4 show dynamicport tcp + Protocol tcp Dynamic Port Range + --------------------------------- + Start Port : 49152 + Number of Ports : 16384 + */ + var range = stdout.split(/\n/).filter(function(line) { + return /.*:\s*\d+/.test(line); + }).map(function(line) { + return Number(line.split(/:\s*/)[1]); + }); + + return { + min: range[0], + max: range[0] + range[1] + }; + }); + } + }); +} + + +/** + * Tests if a port is free. + * @param {number} port The port to test. + * @param {string=} opt_host The bound host to test the {@code port} against. + * Defaults to {@code INADDR_ANY}. + * @return {!webdriver.promise.Promise.} A promise that will resolve + * with whether the port is free. + */ +function isFree(port, opt_host) { + var result = promise.defer(function() { + server.cancel(); + }); + + var server = net.createServer().on('error', function(e) { + if (e.code === 'EADDRINUSE') { + result.fulfill(false); + } else { + result.reject(e); + } + }); + + server.listen(port, opt_host, function() { + server.close(function() { + result.fulfill(true); + }); + }); + + return result.promise; +} + + +/** + * @param {string=} opt_host The bound host to test the {@code port} against. + * Defaults to {@code INADDR_ANY}. + * @return {!webdriver.promise.Promise.} A promise that will resolve + * to a free port. If a port cannot be found, the promise will be + * rejected. + */ +function findFreePort(opt_host) { + return findSystemPortRange().then(function(range) { + var attempts = 0; + var deferredPort = promise.defer(); + findPort(); + return deferredPort.promise; + + function findPort() { + attempts += 1; + if (attempts > 10) { + deferredPort.reject(Error('Unable to find a free port')); + } + + var port = Math.floor( + Math.random() * (range.max - range.min) + range.min); + isFree(port, opt_host).then(function(isFree) { + if (isFree) { + deferredPort.fulfill(port); + } else { + findPort(); + } + }); + } + }); +} + + +// PUBLIC API + + +exports.findFreePort = findFreePort; +exports.isFree = isFree; \ No newline at end of file diff --git a/node_modules/selenium-webdriver/package.json b/node_modules/selenium-webdriver/package.json new file mode 100644 index 0000000..beb11ea --- /dev/null +++ b/node_modules/selenium-webdriver/package.json @@ -0,0 +1,36 @@ +{ + "name": "selenium-webdriver", + "version": "2.42.1", + "description": "The official WebDriver JavaScript bindings from the Selenium project", + "keywords": [ + "automation", + "selenium", + "testing", + "webdriver", + "webdriverjs" + ], + "homepage": "https://code.google.com/p/selenium/", + "bugs": { + "url": "https://code.google.com/p/selenium/issues/list" + }, + "main": "./index", + "repository": { + "type": "git", + "url": "https://code.google.com/p/selenium/" + }, + "engines": { + "node": ">= 0.8.x" + }, + "devDependencies": { + "mocha": "~1.10.0" + }, + "scripts": { + "test": "node_modules/mocha/bin/mocha -R list --recursive test" + }, + "readme": "# selenium-webdriver\n\n## Installation\n\nInstall the latest published version using `npm`:\n\n npm install selenium-webdriver\n\nIn addition to the npm package, you will to download the WebDriver\nimplementations you wish to utilize. As of 2.34.0, `selenium-webdriver`\nnatively supports the [ChromeDriver](http://chromedriver.storage.googleapis.com/index.html).\nSimply download a copy and make sure it can be found on your `PATH`. The other\ndrivers (e.g. Firefox, Internet Explorer, and Safari), still require the\n[standalone Selenium server](http://selenium-release.storage.googleapis.com/index.html).\n\n### Running the tests\n\nTo run the tests, you will need to download a copy of the\n[ChromeDriver](http://chromedriver.storage.googleapis.com/index.html) and make\nsure it can be found on your `PATH`.\n\n npm test selenium-webdriver\n\nTo run the tests against multiple browsers, download the\n[Selenium server](http://selenium-release.storage.googleapis.com/index.html) and\nspecify its location through the `SELENIUM_SERVER_JAR` environment variable.\nYou can use the `SELENIUM_BROWSER` environment variable to define a\ncomma-separated list of browsers you wish to test against. For example:\n\n export SELENIUM_SERVER_JAR=path/to/selenium-server-standalone-2.33.0.jar\n SELENIUM_BROWSER=chrome,firefox npm test selenium-webdriver\n\n## Usage\n\n\n var webdriver = require('selenium-webdriver');\n\n var driver = new webdriver.Builder().\n withCapabilities(webdriver.Capabilities.chrome()).\n build();\n\n driver.get('http://www.google.com');\n driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');\n driver.findElement(webdriver.By.name('btnG')).click();\n driver.wait(function() {\n return driver.getTitle().then(function(title) {\n return title === 'webdriver - Google Search';\n });\n }, 1000);\n\n driver.quit();\n\n## Documentation\n\nAPI documentation is included in the docs module. The API documentation for the\ncurrent release are also available online from the [Selenium project](http://selenium.googlecode.com/git/docs/api/javascript/index.html \"API docs\"). A full user guide is available on the\n[Selenium project wiki](http://code.google.com/p/selenium/wiki/WebDriverJs \"User guide\").\n\n## Issues\n\nPlease report any issues using the [Selenium issue tracker](https://code.google.com/p/selenium/issues/list).\n\n## License\n\nCopyright 2009-2014 Software Freedom Conservancy\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n", + "readmeFilename": "README.md", + "_id": "selenium-webdriver@2.42.1", + "_shasum": "61984d1583b89c80a9f3bf31623d00bcc82a8d0e", + "_from": "selenium-webdriver@", + "_resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-2.42.1.tgz" +} diff --git a/node_modules/selenium-webdriver/phantomjs.js b/node_modules/selenium-webdriver/phantomjs.js new file mode 100644 index 0000000..bee3572 --- /dev/null +++ b/node_modules/selenium-webdriver/phantomjs.js @@ -0,0 +1,164 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var fs = require('fs'), + util = require('util'); + +var webdriver = require('./index'), + LogLevel = webdriver.logging.LevelName, + executors = require('./executors'), + io = require('./io'), + portprober = require('./net/portprober'), + remote = require('./remote'); + + +/** + * Name of the PhantomJS executable. + * @type {string} + * @const + */ +var PHANTOMJS_EXE = + process.platform === 'win32' ? 'phantomjs.exe' : 'phantomjs'; + + +/** + * Capability that designates the location of the PhantomJS executable to use. + * @type {string} + * @const + */ +var BINARY_PATH_CAPABILITY = 'phantomjs.binary.path'; + + +/** + * Capability that designates the CLI arguments to pass to PhantomJS. + * @type {string} + * @const + */ +var CLI_ARGS_CAPABILITY = 'phantomjs.cli.args'; + + +/** + * Default log file to use if one is not specified through CLI args. + * @type {string} + * @const + */ +var DEFAULT_LOG_FILE = 'phantomjsdriver.log'; + + +/** + * Finds the PhantomJS executable. + * @param {string=} opt_exe Path to the executable to use. + * @return {string} The located executable. + * @throws {Error} If the executable cannot be found on the PATH, or if the + * provided executable path does not exist. + */ +function findExecutable(opt_exe) { + var exe = opt_exe || io.findInPath(PHANTOMJS_EXE, true); + if (!exe) { + throw Error( + 'The PhantomJS executable could not be found on the current PATH. ' + + 'Please download the latest version from ' + + 'http://phantomjs.org/download.html and ensure it can be found on ' + + 'your PATH. For more information, see ' + + 'https://github.com/ariya/phantomjs/wiki'); + } + if (!fs.existsSync(exe)) { + throw Error('File does not exist: ' + exe); + } + return exe; +} + + +/** + * Maps WebDriver logging level name to those recognised by PhantomJS. + * @type {!Object.} + * @const + */ +var WEBDRIVER_TO_PHANTOMJS_LEVEL = (function() { + var map = {}; + map[LogLevel.ALL] = map[LogLevel.DEBUG] = 'DEBUG'; + map[LogLevel.INFO] = 'INFO'; + map[LogLevel.WARNING] = 'WARN'; + map[LogLevel.SEVERE] = map[LogLevel.OFF] = 'ERROR'; + return map; +})(); + + +/** + * Creates a new PhantomJS WebDriver client. + * @param {webdriver.Capabilities=} opt_capabilities The desired capabilities. + * @return {!webdriver.WebDriver} A new WebDriver instance. + */ +function createDriver(opt_capabilities) { + var capabilities = opt_capabilities || webdriver.Capabilities.phantomjs(); + var exe = findExecutable(capabilities.get(BINARY_PATH_CAPABILITY)); + var args = ['--webdriver-logfile=' + DEFAULT_LOG_FILE]; + + var logPrefs = capabilities.get(webdriver.Capability.LOGGING_PREFS); + if (logPrefs && logPrefs[webdriver.logging.Type.DRIVER]) { + var level = WEBDRIVER_TO_PHANTOMJS_LEVEL[ + logPrefs[webdriver.logging.Type.DRIVER]]; + if (level) { + args.push('--webdriver-loglevel=' + level); + } + } + + var proxy = capabilities.get(webdriver.Capability.PROXY); + if (proxy) { + switch (proxy.proxyType) { + case 'manual': + if (proxy.httpProxy) { + args.push( + '--proxy-type=http', + '--proxy=http://' + proxy.httpProxy); + } + break; + case 'pac': + throw Error('PhantomJS does not support Proxy PAC files'); + case 'system': + args.push('--proxy-type=system'); + break; + case 'direct': + args.push('--proxy-type=none'); + break; + } + } + args = args.concat(capabilities.get(CLI_ARGS_CAPABILITY) || []); + + var port = portprober.findFreePort(); + var service = new remote.DriverService(exe, { + port: port, + args: webdriver.promise.when(port, function(port) { + args.push('--webdriver=' + port); + return args; + }) + }); + + var executor = executors.createExecutor(service.start()); + var driver = webdriver.WebDriver.createSession(executor, capabilities); + var boundQuit = driver.quit.bind(driver); + driver.quit = function() { + return boundQuit().thenFinally(service.kill.bind(service)); + }; + return driver; +} + + +// PUBLIC API + + +exports.createDriver = createDriver; diff --git a/node_modules/selenium-webdriver/proxy.js b/node_modules/selenium-webdriver/proxy.js new file mode 100644 index 0000000..0341346 --- /dev/null +++ b/node_modules/selenium-webdriver/proxy.js @@ -0,0 +1,115 @@ +// Copyright 2013 Selenium committers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Defines functions for configuring a webdriver proxy: + *
      
      + * var webdriver = require('selenium-webdriver'),
      + *     proxy = require('selenium-webdriver/proxy');
      + *
      + * var driver = new webdriver.Builder()
      + *     .withCapabilities(webdriver.Capabilities.chrome())
      + *     .setProxy(proxy.manual({http: 'host:1234'}))
      + *     .build();
      + * 
      + */ + +'use strict'; + +var util = require('util'); + + +/** + * Proxy configuration object, as defined by the WebDriver wire protocol. + * @typedef {( + * {proxyType: string}| + * {proxyType: string, + * proxyAutoconfigUrl: string}| + * {proxyType: string, + * ftpProxy: string, + * httpProxy: string, + * sslProxy: string, + * noProxy: string})} + */ +var ProxyConfig; + + + +// PUBLIC API + + +/** + * Configures WebDriver to bypass all browser proxies. + * @return {!ProxyConfig} A new proxy configuration object. + */ +exports.direct = function() { + return {proxyType: 'direct'}; +}; + + +/** + * Manually configures the browser proxy. The following options are + * supported: + *
        + *
      • {@code ftp}: Proxy host to use for FTP requests + *
      • {@code http}: Proxy host to use for HTTP requests + *
      • {@code https}: Proxy host to use for HTTPS requests + *
      • {@code bypass}: A list of hosts requests should directly connect to, + * bypassing any other proxies for that request. May be specified as a + * comma separated string, or a list of strings. + *
      + * + * Behavior is undefined for FTP, HTTP, and HTTPS requests if the + * corresponding key is omitted from the configuration options. + * + * @param {{ftp: (string|undefined), + * http: (string|undefined), + * https: (string|undefined), + * bypass: (string|!Array.|undefined)}} options Proxy + * configuration options. + * @return {!ProxyConfig} A new proxy configuration object. + */ +exports.manual = function(options) { + return { + proxyType: 'manual', + ftpProxy: options.ftp, + httpProxy: options.http, + sslProxy: options.https, + noProxy: util.isArray(options.bypass) ? + options.bypass.join(',') : options.bypass + }; +}; + + +/** + * Configures WebDriver to configure the browser proxy using the PAC file at + * the given URL. + * @param {string} url URL for the PAC proxy to use. + * @return {!ProxyConfig} A new proxy configuration object. + */ +exports.pac = function(url) { + return { + proxyType: 'pac', + proxyAutoconfigUrl: url + }; +}; + + +/** + * Configures WebDriver to use the current system's proxy. + * @return {!ProxyConfig} A new proxy configuration object. + */ +exports.system = function() { + return {proxyType: 'system'}; +}; diff --git a/node_modules/selenium-webdriver/remote/index.js b/node_modules/selenium-webdriver/remote/index.js new file mode 100644 index 0000000..71d62f5 --- /dev/null +++ b/node_modules/selenium-webdriver/remote/index.js @@ -0,0 +1,332 @@ +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var spawn = require('child_process').spawn, + os = require('os'), + path = require('path'), + url = require('url'), + util = require('util'); + +var promise = require('../').promise, + httpUtil = require('../http/util'), + net = require('../net'), + portprober = require('../net/portprober'); + + + +/** + * Configuration options for a DriverService instance. + *
        + *
      • + *
      • {@code loopback} - Whether the service should only be accessed on this + * host's loopback address. + *
      • {@code port} - The port to start the server on (must be > 0). If the + * port is provided as a promise, the service will wait for the promise to + * resolve before starting. + *
      • {@code args} - The arguments to pass to the service. If a promise is + * provided, the service will wait for it to resolve before starting. + *
      • {@code path} - The base path on the server for the WebDriver wire + * protocol (e.g. '/wd/hub'). Defaults to '/'. + *
      • {@code env} - The environment variables that should be visible to the + * server process. Defaults to inheriting the current process's + * environment. + *
      • {@code stdio} - IO configuration for the spawned server process. For + * more information, refer to the documentation of + * {@code child_process.spawn}. + *
      + * + * @typedef {{ + * port: (number|!webdriver.promise.Promise.), + * args: !(Array.|webdriver.promise.Promise.>), + * path: (string|undefined), + * env: (!Object.|undefined), + * stdio: (string|!Array.|undefined) + * }} + */ +var ServiceOptions; + + +/** + * Manages the life and death of a native executable WebDriver server. + * + *

      It is expected that the driver server implements the + * WebDriver + * Wire Protocol. Furthermore, the managed server should support multiple + * concurrent sessions, so that this class may be reused for multiple clients. + * + * @param {string} executable Path to the executable to run. + * @param {!ServiceOptions} options Configuration options for the service. + * @constructor + */ +function DriverService(executable, options) { + + /** @private {string} */ + this.executable_ = executable; + + /** @private {boolean} */ + this.loopbackOnly_ = !!options.loopback; + + /** @private {(number|!webdriver.promise.Promise.)} */ + this.port_ = options.port; + + /** + * @private {!(Array.|webdriver.promise.Promise.>)} + */ + this.args_ = options.args; + + /** @private {string} */ + this.path_ = options.path || '/'; + + /** @private {!Object.} */ + this.env_ = options.env || process.env; + + /** @private {(string|!Array.)} */ + this.stdio_ = options.stdio || 'ignore'; +} + + +/** + * The default amount of time, in milliseconds, to wait for the server to + * start. + * @type {number} + */ +DriverService.DEFAULT_START_TIMEOUT_MS = 30 * 1000; + + +/** @private {child_process.ChildProcess} */ +DriverService.prototype.process_ = null; + + +/** + * Promise that resolves to the server's address or null if the server has not + * been started. + * @private {webdriver.promise.Promise.} + */ +DriverService.prototype.address_ = null; + + +/** + * Promise that tracks the status of shutting down the server, or null if the + * server is not currently shutting down. + * @private {webdriver.promise.Promise} + */ +DriverService.prototype.shutdownHook_ = null; + + +/** + * @return {!webdriver.promise.Promise.} A promise that resolves to + * the server's address. + * @throws {Error} If the server has not been started. + */ +DriverService.prototype.address = function() { + if (this.address_) { + return this.address_; + } + throw Error('Server has not been started.'); +}; + + +/** + * @return {boolean} Whether the underlying service process is running. + */ +DriverService.prototype.isRunning = function() { + return !!this.address_; +}; + + +/** + * Starts the server if it is not already running. + * @param {number=} opt_timeoutMs How long to wait, in milliseconds, for the + * server to start accepting requests. Defaults to 30 seconds. + * @return {!webdriver.promise.Promise.} A promise that will resolve + * to the server's base URL when it has started accepting requests. If the + * timeout expires before the server has started, the promise will be + * rejected. + */ +DriverService.prototype.start = function(opt_timeoutMs) { + if (this.address_) { + return this.address_; + } + + var timeout = opt_timeoutMs || DriverService.DEFAULT_START_TIMEOUT_MS; + + var self = this; + this.address_ = promise.defer(); + this.address_.fulfill(promise.when(this.port_, function(port) { + if (port <= 0) { + throw Error('Port must be > 0: ' + port); + } + return promise.when(self.args_, function(args) { + self.process_ = spawn(self.executable_, args, { + env: self.env_, + stdio: self.stdio_ + }).once('exit', onServerExit); + + // This process should not wait on the spawned child, however, we do + // want to ensure the child is killed when this process exits. + self.process_.unref(); + process.once('exit', killServer); + + var serverUrl = url.format({ + protocol: 'http', + hostname: !self.loopbackOnly_ && net.getAddress() || + net.getLoopbackAddress(), + port: port, + pathname: self.path_ + }); + + return httpUtil.waitForServer(serverUrl, timeout).then(function() { + return serverUrl; + }); + }); + })); + + return this.address_; + + function onServerExit(code, signal) { + self.address_.reject(code == null ? + Error('Server was killed with ' + signal) : + Error('Server exited with ' + code)); + + if (self.shutdownHook_) { + self.shutdownHook_.fulfill(); + } + + self.shutdownHook_ = null; + self.address_ = null; + self.process_ = null; + process.removeListener('exit', killServer); + } + + function killServer() { + process.removeListener('exit', killServer); + self.process_ && self.process_.kill('SIGTERM'); + } +}; + + +/** + * Stops the service if it is not currently running. This function will kill + * the server immediately. To synchronize with the active control flow, use + * {@link #stop()}. + * @return {!webdriver.promise.Promise} A promise that will be resolved when + * the server has been stopped. + */ +DriverService.prototype.kill = function() { + if (!this.address_) { + return promise.fulfilled(); // Not currently running. + } + + if (!this.shutdownHook_) { + // No process: still starting; wait on address. + // Otherwise, kill the process now. Exit handler will resolve the + // shutdown hook. + if (this.process_) { + this.shutdownHook_ = promise.defer(); + this.process_.kill('SIGTERM'); + } else { + var self = this; + this.shutdownHook_ = this.address_.thenFinally(function() { + self.process_ && self.process_.kill('SIGTERM'); + }); + } + } + + return this.shutdownHook_; +}; + + +/** + * Schedules a task in the current control flow to stop the server if it is + * currently running. + * @return {!webdriver.promise.Promise} A promise that will be resolved when + * the server has been stopped. + */ +DriverService.prototype.stop = function() { + return promise.controlFlow().execute(this.kill.bind(this)); +}; + + + +/** + * Manages the life and death of the Selenium standalone server. The server + * may be obtained from http://selenium-release.storage.googleapis.com/index.html. + * @param {string} jar Path to the Selenium server jar. + * @param {!SeleniumServer.Options} options Configuration options for the + * server. + * @throws {Error} If an invalid port is specified. + * @constructor + * @extends {DriverService} + */ +function SeleniumServer(jar, options) { + if (options.port < 0) + throw Error('Port must be >= 0: ' + options.port); + + var port = options.port || portprober.findFreePort(); + var args = promise.when(options.jvmArgs || [], function(jvmArgs) { + return promise.when(options.args || [], function(args) { + return promise.when(port, function(port) { + return jvmArgs.concat(['-jar', jar, '-port', port]).concat(args); + }); + }); + }); + + DriverService.call(this, 'java', { + port: port, + args: args, + path: '/wd/hub', + env: options.env, + stdio: options.stdio + }); +} +util.inherits(SeleniumServer, DriverService); + + +/** + * Options for the Selenium server: + *

        + *
      • {@code port} - The port to start the server on (must be > 0). If the + * port is provided as a promise, the service will wait for the promise to + * resolve before starting. + *
      • {@code args} - The arguments to pass to the service. If a promise is + * provided, the service will wait for it to resolve before starting. + *
      • {@code jvmArgs} - The arguments to pass to the JVM. If a promise is + * provided, the service will wait for it to resolve before starting. + *
      • {@code env} - The environment variables that should be visible to the + * server process. Defaults to inheriting the current process's + * environment. + *
      • {@code stdio} - IO configuration for the spawned server process. For + * more information, refer to the documentation of + * {@code child_process.spawn}. + *
      + * + * @typedef {{ + * port: (number|!webdriver.promise.Promise.), + * args: !(Array.|webdriver.promise.Promise.>), + * jvmArgs: (!Array.| + * !webdriver.promise.Promise.>| + * undefined), + * env: (!Object.|undefined), + * stdio: (string|!Array.|undefined) + * }} + */ +SeleniumServer.Options; + + +// PUBLIC API + +exports.DriverService = DriverService; +exports.SeleniumServer = SeleniumServer; diff --git a/node_modules/selenium-webdriver/test/chrome/options_test.js b/node_modules/selenium-webdriver/test/chrome/options_test.js new file mode 100644 index 0000000..2398ddf --- /dev/null +++ b/node_modules/selenium-webdriver/test/chrome/options_test.js @@ -0,0 +1,213 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var fs = require('fs'); + +var webdriver = require('../..'), + chrome = require('../../chrome'), + proxy = require('../../proxy'), + assert = require('../../testing/assert'); + +var test = require('../../lib/test'); + + +describe('chrome.Options', function() { + + describe('fromCapabilities', function() { + + it('should return a new Options instance if none were defined', + function() { + var options = chrome.Options.fromCapabilities( + new webdriver.Capabilities()); + assert(options).instanceOf(chrome.Options); + }); + + it('should return options instance if present', function() { + var options = new chrome.Options(); + var caps = options.toCapabilities(); + assert(caps).instanceOf(webdriver.Capabilities); + assert(chrome.Options.fromCapabilities(caps)).equalTo(options); + }); + + it('should rebuild options from wire representation', function() { + var caps = webdriver.Capabilities.chrome().set('chromeOptions', { + args: ['a', 'b'], + extensions: [1, 2], + binary: 'binaryPath', + logFile: 'logFilePath', + detach: true, + localState: 'localStateValue', + prefs: 'prefsValue' + }); + + var options = chrome.Options.fromCapabilities(caps); + + assert(options.args_.length).equalTo(2); + assert(options.args_[0]).equalTo('a'); + assert(options.args_[1]).equalTo('b'); + assert(options.extensions_.length).equalTo(2); + assert(options.extensions_[0]).equalTo(1); + assert(options.extensions_[1]).equalTo(2); + assert(options.binary_).equalTo('binaryPath'); + assert(options.logFile_).equalTo('logFilePath'); + assert(options.detach_).equalTo(true); + assert(options.localState_).equalTo('localStateValue'); + assert(options.prefs_).equalTo('prefsValue'); + }); + + it('should rebuild options from incomplete wire representation', + function() { + var caps = webdriver.Capabilities.chrome().set('chromeOptions', { + logFile: 'logFilePath' + }); + + var options = chrome.Options.fromCapabilities(caps); + var json = options.toJSON(); + + assert(json.args.length).equalTo(0); + assert(json.binary).isUndefined(); + assert(json.detach).isFalse(); + assert(json.extensions.length).equalTo(0); + assert(json.localState).isUndefined(); + assert(json.logFile).equalTo('logFilePath'); + assert(json.prefs).isUndefined(); + }); + + it('should extract supported WebDriver capabilities', function() { + var proxyPrefs = proxy.direct(); + var logPrefs = {}; + var caps = webdriver.Capabilities.chrome(). + set(webdriver.Capability.PROXY, proxyPrefs). + set(webdriver.Capability.LOGGING_PREFS, logPrefs); + + var options = chrome.Options.fromCapabilities(caps); + assert(options.proxy_).equalTo(proxyPrefs); + assert(options.logPrefs_).equalTo(logPrefs); + }); + }); + + describe('addArguments', function() { + it('takes var_args', function() { + var options = new chrome.Options(); + assert(options.args_.length).equalTo(0); + + options.addArguments('a', 'b'); + assert(options.args_.length).equalTo(2); + assert(options.args_[0]).equalTo('a'); + assert(options.args_[1]).equalTo('b'); + }); + + it('flattens input arrays', function() { + var options = new chrome.Options(); + assert(options.args_.length).equalTo(0); + + options.addArguments(['a', 'b'], 'c', [1, 2], 3); + assert(options.args_.length).equalTo(6); + assert(options.args_[0]).equalTo('a'); + assert(options.args_[1]).equalTo('b'); + assert(options.args_[2]).equalTo('c'); + assert(options.args_[3]).equalTo(1); + assert(options.args_[4]).equalTo(2); + assert(options.args_[5]).equalTo(3); + }); + }); + + describe('addExtensions', function() { + it('takes var_args', function() { + var options = new chrome.Options(); + assert(options.extensions_.length).equalTo(0); + + options.addExtensions('a', 'b'); + assert(options.extensions_.length).equalTo(2); + assert(options.extensions_[0]).equalTo('a'); + assert(options.extensions_[1]).equalTo('b'); + }); + + it('flattens input arrays', function() { + var options = new chrome.Options(); + assert(options.extensions_.length).equalTo(0); + + options.addExtensions(['a', 'b'], 'c', [1, 2], 3); + assert(options.extensions_.length).equalTo(6); + assert(options.extensions_[0]).equalTo('a'); + assert(options.extensions_[1]).equalTo('b'); + assert(options.extensions_[2]).equalTo('c'); + assert(options.extensions_[3]).equalTo(1); + assert(options.extensions_[4]).equalTo(2); + assert(options.extensions_[5]).equalTo(3); + }); + }); + + describe('toJSON', function() { + it('base64 encodes extensions', function() { + var expected = fs.readFileSync(__filename, 'base64'); + var wire = new chrome.Options().addExtensions(__filename).toJSON(); + assert(wire.extensions.length).equalTo(1); + assert(wire.extensions[0]).equalTo(expected); + }); + }); + + describe('toCapabilities', function() { + it('returns a new capabilities object if one is not provided', function() { + var options = new chrome.Options(); + var caps = options.toCapabilities(); + assert(caps.get('browserName')).equalTo('chrome'); + assert(caps.get('chromeOptions')).equalTo(options); + }); + + it('adds to input capabilities object', function() { + var caps = webdriver.Capabilities.firefox(); + var options = new chrome.Options(); + assert(options.toCapabilities(caps)).equalTo(caps); + assert(caps.get('browserName')).equalTo('firefox'); + assert(caps.get('chromeOptions')).equalTo(options); + }); + + it('sets generic driver capabilities', function() { + var proxyPrefs = {}; + var loggingPrefs = {}; + var options = new chrome.Options(). + setLoggingPreferences(loggingPrefs). + setProxy(proxyPrefs); + + var caps = options.toCapabilities(); + assert(caps.get('proxy')).equalTo(proxyPrefs); + assert(caps.get('loggingPrefs')).equalTo(loggingPrefs); + }); + }); +}); + +test.suite(function(env) { + env.autoCreateDriver = false; + + describe('options', function() { + test.it('can start Chrome with custom args', function() { + var options = new chrome.Options(). + addArguments('user-agent=foo;bar'); + + var driver = env.builder(). + setChromeOptions(options). + build(); + + driver.get(test.Pages.ajaxyPage); + + var userAgent = driver.executeScript( + 'return window.navigator.userAgent'); + assert(userAgent).equalTo('foo;bar'); + }); + }); +}, {browsers: ['chrome']}); \ No newline at end of file diff --git a/node_modules/selenium-webdriver/test/cookie_test.js b/node_modules/selenium-webdriver/test/cookie_test.js new file mode 100644 index 0000000..700e424 --- /dev/null +++ b/node_modules/selenium-webdriver/test/cookie_test.js @@ -0,0 +1,198 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var assert = require('assert'), + url = require('url'); + +var test = require('../lib/test'), + fileserver = require('../lib/test/fileserver'), + Browser = test.Browser, + Pages = test.Pages; + + +test.suite(function(env) { + var driver; + beforeEach(function() { driver = env.driver; }); + + test.ignore(env.browsers(Browser.SAFARI)). // Cookie handling is broken. + describe('Cookie Management;', function() { + + test.beforeEach(function() { + driver.get(fileserver.Pages.ajaxyPage); + driver.manage().deleteAllCookies(); + assertHasCookies(); + }); + + test.it('can add new cookies', function() { + var cookie = createCookieSpec(); + + driver.manage().addCookie(cookie.name, cookie.value); + driver.manage().getCookie(cookie.name).then(function(actual) { + assert.equal(actual.value, cookie.value); + }); + }); + + test.it('can get all cookies', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + + driver.manage().addCookie(cookie1.name, cookie1.value); + driver.manage().addCookie(cookie2.name, cookie2.value); + + assertHasCookies(cookie1, cookie2); + }); + + test.ignore(env.browsers(Browser.OPERA)). + it('only returns cookies visible to the current page', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + + driver.manage().addCookie(cookie1.name, cookie1.value); + + var pageUrl = fileserver.whereIs('page/1'); + driver.get(pageUrl); + driver.manage().addCookie( + cookie2.name, cookie2.value, url.parse(pageUrl).pathname); + assertHasCookies(cookie1, cookie2); + + driver.get(fileserver.Pages.ajaxyPage); + assertHasCookies(cookie1); + + driver.get(pageUrl); + assertHasCookies(cookie1, cookie2); + }); + + test.it('can delete all cookies', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + + driver.executeScript( + 'document.cookie = arguments[0] + "=" + arguments[1];' + + 'document.cookie = arguments[2] + "=" + arguments[3];', + cookie1.name, cookie1.value, cookie2.name, cookie2.value); + assertHasCookies(cookie1, cookie2); + + driver.manage().deleteAllCookies(); + assertHasCookies(); + }); + + test.it('can delete cookies by name', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + + driver.executeScript( + 'document.cookie = arguments[0] + "=" + arguments[1];' + + 'document.cookie = arguments[2] + "=" + arguments[3];', + cookie1.name, cookie1.value, cookie2.name, cookie2.value); + assertHasCookies(cookie1, cookie2); + + driver.manage().deleteCookie(cookie1.name); + assertHasCookies(cookie2); + }); + + test.it('should only delete cookie with exact name', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + var cookie3 = {name: cookie1.name + 'xx', value: cookie1.value}; + + driver.executeScript( + 'document.cookie = arguments[0] + "=" + arguments[1];' + + 'document.cookie = arguments[2] + "=" + arguments[3];' + + 'document.cookie = arguments[4] + "=" + arguments[5];', + cookie1.name, cookie1.value, cookie2.name, cookie2.value, + cookie3.name, cookie3.value); + assertHasCookies(cookie1, cookie2, cookie3); + + driver.manage().deleteCookie(cookie1.name); + assertHasCookies(cookie2, cookie3); + }); + + test.it('can delete cookies set higher in the path', function() { + var cookie = createCookieSpec(); + var childUrl = fileserver.whereIs('child/childPage.html'); + var grandchildUrl = fileserver.whereIs( + 'child/grandchild/grandchildPage.html'); + + driver.get(childUrl); + driver.manage().addCookie(cookie.name, cookie.value); + assertHasCookies(cookie); + + driver.get(grandchildUrl); + assertHasCookies(cookie); + + driver.manage().deleteCookie(cookie.name); + assertHasCookies(); + + driver.get(childUrl); + assertHasCookies(); + }); + + test.ignore(env.browsers( + Browser.ANDROID, Browser.FIREFOX, Browser.IE, Browser.OPERA)). + it('should retain cookie expiry', function() { + var cookie = createCookieSpec(); + var expirationDelay = 5 * 1000; + var futureTime = Date.now() + expirationDelay; + + driver.manage().addCookie( + cookie.name, cookie.value, null, null, false, futureTime); + driver.manage().getCookie(cookie.name).then(function(actual) { + assert.equal(actual.value, cookie.value); + // expiry times are exchanged in seconds since January 1, 1970 UTC. + assert.equal(actual.expiry, Math.floor(futureTime / 1000)); + }); + + driver.sleep(expirationDelay); + assertHasCookies(); + }); + }); + + function createCookieSpec() { + return { + name: getRandomString(), + value: getRandomString() + }; + } + + function buildCookieMap(cookies) { + var map = {}; + cookies.forEach(function(cookie) { + map[cookie.name] = cookie; + }); + return map; + } + + function assertHasCookies(var_args) { + var expected = Array.prototype.slice.call(arguments, 0); + driver.manage().getCookies().then(function(cookies) { + assert.equal(cookies.length, expected.length, + 'Wrong # of cookies.' + + '\n Expected: ' + JSON.stringify(expected) + + '\n Was : ' + JSON.stringify(cookies)); + + var map = buildCookieMap(cookies); + for (var i = 0; i < expected.length; ++i) { + assert.equal(expected[i].value, map[expected[i].name].value); + } + }); + } + + function getRandomString() { + var x = 1234567890; + return Math.floor(Math.random() * x).toString(36); + } +}); diff --git a/node_modules/selenium-webdriver/test/element_finding_test.js b/node_modules/selenium-webdriver/test/element_finding_test.js new file mode 100644 index 0000000..d1e95f9 --- /dev/null +++ b/node_modules/selenium-webdriver/test/element_finding_test.js @@ -0,0 +1,346 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var fail = require('assert').fail; + +var By = require('..').By, + error = require('..').error, + test = require('../lib/test'), + assert = require('../testing/assert'), + Browser = test.Browser, + Pages = test.Pages; + + +test.suite(function(env) { + var browsers = env.browsers, + waitForTitleToBe = env.waitForTitleToBe; + + var driver; + beforeEach(function() { driver = env.driver; }); + + describe('finding elements', function() { + + test.it( + 'should work after loading multiple pages in a row', + function() { + driver.get(Pages.formPage); + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.linkText('click me')).click(); + waitForTitleToBe('We Arrive Here'); + }); + + describe('By.id()', function() { + test.it('should work', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.id('linkId')).click(); + waitForTitleToBe('We Arrive Here'); + }); + + test.it('should fail if ID not present on page', function() { + driver.get(Pages.formPage); + driver.findElement(By.id('nonExistantButton')). + then(fail, function(e) { + assert(e.code).equalTo(error.ErrorCode.NO_SUCH_ELEMENT); + }); + }); + + test.ignore(browsers(Browser.ANDROID)).it( + 'should find multiple elements by ID even though that ' + + 'is malformed HTML', + function() { + driver.get(Pages.nestedPage); + driver.findElements(By.id('2')).then(function(elements) { + assert(elements.length).equalTo(8); + }); + }); + }); + + describe('By.linkText()', function() { + test.it('should be able to click on link identified by text', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.linkText('click me')).click(); + waitForTitleToBe('We Arrive Here'); + }); + + test.it( + 'should be able to find elements by partial link text', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.partialLinkText('ick me')).click(); + waitForTitleToBe('We Arrive Here'); + }); + + test.it('should work when link text contains equals sign', function() { + driver.get(Pages.xhtmlTestPage); + var id = driver.findElement(By.linkText('Link=equalssign')). + getAttribute('id'); + assert(id).equalTo('linkWithEqualsSign'); + }); + + test.it('matches by partial text when containing equals sign', + function() { + driver.get(Pages.xhtmlTestPage); + var id = driver.findElement(By.partialLinkText('Link=')). + getAttribute('id'); + assert(id).equalTo('linkWithEqualsSign'); + }); + + test.it('works when searching for multiple and text contains =', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.linkText('Link=equalssign')). + then(function(elements) { + assert(elements.length).equalTo(1); + return elements[0].getAttribute('id'); + }). + then(function(id) { + assert(id).equalTo('linkWithEqualsSign'); + }); + }); + + test.it( + 'works when searching for multiple with partial text containing =', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.partialLinkText('Link=')). + then(function(elements) { + assert(elements.length).equalTo(1); + return elements[0].getAttribute('id'); + }). + then(function(id) { + assert(id).equalTo('linkWithEqualsSign'); + }); + }); + + test.it('should be able to find multiple exact matches', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.linkText('click me')). + then(function(elements) { + assert(elements.length).equalTo(2); + }); + }); + + test.it('should be able to find multiple partial matches', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.partialLinkText('ick me')). + then(function(elements) { + assert(elements.length).equalTo(2); + }); + }); + + test.ignore(browsers(Browser.OPERA)). + it('works on XHTML pages', function() { + driver.get(test.whereIs('actualXhtmlPage.xhtml')); + + var el = driver.findElement(By.linkText('Foo')); + assert(el.getText()).equalTo('Foo'); + }); + }); + + describe('By.name()', function() { + test.it('should work', function() { + driver.get(Pages.formPage); + + var el = driver.findElement(By.name('checky')); + assert(el.getAttribute('value')).equalTo('furrfu'); + }); + + test.it('should find multiple elements with same name', function() { + driver.get(Pages.nestedPage); + driver.findElements(By.name('checky')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + }); + + test.it( + 'should be able to find elements that do not support name property', + function() { + driver.get(Pages.nestedPage); + driver.findElement(By.name('div1')); + // Pass if this does not return an error. + }); + + test.it('shoudl be able to find hidden elements by name', function() { + driver.get(Pages.formPage); + driver.findElement(By.name('hidden')); + // Pass if this does not return an error. + }); + }); + + describe('By.className()', function() { + test.it('should work', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('extraDiv')); + assert(el.getText()).startsWith('Another div starts here.'); + }); + + test.it('should work when name is first name among many', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('nameA')); + assert(el.getText()).equalTo('An H2 title'); + }); + + test.it('should work when name is last name among many', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('nameC')); + assert(el.getText()).equalTo('An H2 title'); + }); + + test.it('should work when name is middle of many', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('nameBnoise')); + assert(el.getText()).equalTo('An H2 title'); + }); + + test.it('should work when name surrounded by whitespace', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('spaceAround')); + assert(el.getText()).equalTo('Spaced out'); + }); + + test.it('should fail if queried name only partially matches', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.className('nameB')). + then(fail, function(e) { + assert(e.code).equalTo(error.ErrorCode.NO_SUCH_ELEMENT); + }); + }); + + test.it('should be able to find multiple matches', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.className('nameC')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + }); + + test.it('does not permit compound class names', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.className('a b')).then(fail, pass); + driver.findElements(By.className('a b')).then(fail, pass); + function pass() {} + }); + }); + + describe('By.xpath()', function() { + test.it('should work with multiple matches', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.xpath('//div')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + }); + + test.it('should work for selectors using contains keyword', function() { + driver.get(Pages.nestedPage); + driver.findElement(By.xpath('//a[contains(., "hello world")]')); + // Pass if no error. + }); + }); + + describe('By.tagName()', function() { + test.it('works', function() { + driver.get(Pages.formPage); + + var el = driver.findElement(By.tagName('input')); + assert(el.getTagName()).equalTo('input'); + }); + + test.it('can find multiple elements', function() { + driver.get(Pages.formPage); + driver.findElements(By.tagName('input')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + }); + }); + + describe('By.css()', function() { + test.it('works', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.css('div.content')); + // Pass if no error. + }); + + test.it('can find multiple elements', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.css('p')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + // Pass if no error. + }); + + test.it( + 'should find first matching element when searching by ' + + 'compound CSS selector', + function() { + driver.get(Pages.xhtmlTestPage); + var el = driver.findElement(By.css('div.extraDiv, div.content')); + assert(el.getAttribute('class')).equalTo('content'); + }); + + test.it('should be able to find multiple elements by compound selector', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.css('div.extraDiv, div.content')). + then(function(elements) { + assertClassIs(elements[0], 'content'); + assertClassIs(elements[1], 'extraDiv'); + + function assertClassIs(el, expected) { + assert(el.getAttribute('class')).equalTo(expected); + } + }); + }); + + // IE only supports short version option[selected]. + test.ignore(browsers(Browser.IE)). + it('should be able to find element by boolean attribute', function() { + driver.get(test.whereIs( + 'locators_tests/boolean_attribute_selected.html')); + + var el = driver.findElement(By.css('option[selected="selected"]')); + assert(el.getAttribute('value')).equalTo('two'); + }); + + test.it( + 'should be able to find element with short ' + + 'boolean attribute selector', + function() { + driver.get(test.whereIs( + 'locators_tests/boolean_attribute_selected.html')); + + var el = driver.findElement(By.css('option[selected]')); + assert(el.getAttribute('value')).equalTo('two'); + }); + + test.it( + 'should be able to find element with short boolean attribute ' + + 'selector on HTML4 page', + function() { + driver.get(test.whereIs( + 'locators_tests/boolean_attribute_selected_html4.html')); + + var el = driver.findElement(By.css('option[selected]')); + assert(el.getAttribute('value')).equalTo('two'); + }); + }); + }); +}); diff --git a/node_modules/selenium-webdriver/test/http/http_test.js b/node_modules/selenium-webdriver/test/http/http_test.js new file mode 100644 index 0000000..eafc6ad --- /dev/null +++ b/node_modules/selenium-webdriver/test/http/http_test.js @@ -0,0 +1,88 @@ +// Copyright 2014 Selenium committers +// Copyright 2014 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var assert = require('assert'); + +var HttpClient = require('../../http').HttpClient; +var HttpRequest = require('../../_base').require('webdriver.http.Request'); +var Server = require('../../lib/test/httpserver').Server; +var promise = require('../..').promise; +var test = require('../../lib/test'); + +describe('HttpClient', function() { + var server = new Server(function(req, res) { + if (req.method == 'GET' && req.url == '/echo') { + res.writeHead(200, req.headers); + res.end(); + + } else if (req.method == 'GET' && req.url == '/redirect') { + res.writeHead(303, {'Location': server.url('/hello')}); + res.end(); + + } else if (req.method == 'GET' && req.url == '/hello') { + res.writeHead(200, {'content-type': 'text/plain'}); + res.end('hello, world!'); + + } else if (req.method == 'GET' && req.url == '/badredirect') { + res.writeHead(303, {}); + res.end(); + + } else { + res.writeHead(404, {}); + res.end(); + } + }); + + test.before(server.start.bind(server)); + test.after(server.stop.bind(server)); + + test.it('can send a basic HTTP request', function() { + var request = new HttpRequest('GET', '/echo'); + request.headers['Foo'] = 'Bar'; + + var client = new HttpClient(server.url()); + return promise.checkedNodeCall(client.send.bind(client, request)) + .then(function(response) { + assert.equal(200, response.status); + assert.equal( + 'application/json; charset=utf-8', response.headers['accept']); + assert.equal('Bar', response.headers['foo']); + assert.equal('0', response.headers['content-length']); + assert.equal('keep-alive', response.headers['connection']); + assert.equal(server.host(), response.headers['host']); + }); + }); + + test.it('automatically follows redirects', function() { + var request = new HttpRequest('GET', '/redirect'); + var client = new HttpClient(server.url()); + return promise.checkedNodeCall(client.send.bind(client, request)) + .then(function(response) { + assert.equal(200, response.status); + assert.equal('text/plain', response.headers['content-type']); + assert.equal('hello, world!', response.body); + }); + }); + + test.it('handles malformed redirect responses', function() { + var request = new HttpRequest('GET', '/badredirect'); + var client = new HttpClient(server.url()); + return promise.checkedNodeCall(client.send.bind(client, request)). + thenCatch(function(err) { + assert.ok(/Failed to parse "Location"/.test(err.message), + 'Not the expected error: ' + err.message); + }); + }); +}); diff --git a/node_modules/selenium-webdriver/test/http/util_test.js b/node_modules/selenium-webdriver/test/http/util_test.js new file mode 100644 index 0000000..37835b4 --- /dev/null +++ b/node_modules/selenium-webdriver/test/http/util_test.js @@ -0,0 +1,181 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var assert = require('assert'), + http = require('http'); + +var util = require('../../http/util'); + +describe('selenium-webdriver/http/util', function() { + + var server, baseUrl; + + var status, value, responseCode; + + function startServer(done) { + if (server) return done(); + + server = http.createServer(function(req, res) { + var data = JSON.stringify({status: status, value: value}); + res.writeHead(responseCode, { + 'Content-Type': 'application/json; charset=utf-8', + 'Content-Length': Buffer.byteLength(data, 'utf8') + }); + res.end(data); + }); + + server.listen(0, '127.0.0.1', function(e) { + if (e) return done(e); + + var addr = server.address(); + baseUrl = 'http://' + addr.address + ':' + addr.port; + done(); + }); + } + + function killServer(done) { + if (!server) return done(); + server.close(done); + server = null; + } + + after(killServer); + + beforeEach(function(done) { + status = 0; + value = 'abc123'; + responseCode = 200; + startServer(done); + }); + + describe('#getStatus', function() { + it('should return value field on success', function(done) { + util.getStatus(baseUrl).then(function(response) { + assert.equal('abc123', response); + }).thenFinally(done); + }); + + it('should fail if response object is not success', function(done) { + status = 1; + util.getStatus(baseUrl).then(function() { + throw Error('expected a failure'); + }, function(err) { + assert.equal(status, err.code); + assert.equal(value, err.message); + }).thenFinally(done); + }); + + it('should fail if the server is not listening', function(done) { + killServer(function(e) { + if(e) return done(e); + + util.getStatus(baseUrl).then(function() { + throw Error('expected a failure'); + }, function() { + // Expected. + }).thenFinally(done); + }); + }); + + it('should fail if HTTP status is not 200', function(done) { + status = 1; + responseCode = 404; + util.getStatus(baseUrl).then(function() { + throw Error('expected a failure'); + }, function(err) { + assert.equal(status, err.code); + assert.equal(value, err.message); + }).thenFinally(done); + }); + }); + + describe('#waitForServer', function() { + it('resolves when server is ready', function(done) { + status = 1; + setTimeout(function() { status = 0; }, 50); + util.waitForServer(baseUrl, 100). + then(function() {}). // done needs no argument to pass. + thenFinally(done); + }); + + it('should fail if server does not become ready', function(done) { + status = 1; + util.waitForServer(baseUrl, 50). + then(function() { done('Expected to time out'); }, + function() { done(); }); + }); + + it('can cancel wait', function(done) { + status = 1; + var err = Error('cancelled!'); + var isReady = util.waitForServer(baseUrl, 200). + then(function() { done('Did not expect to succeed'); }). + then(null, function(e) { + assert.equal(err, e); + }). + then(function() { done(); }, done); + + setTimeout(function() { + isReady.cancel(err); + }, 50); + }); + }); + + describe('#waitForUrl', function() { + it('succeeds when URL returns 2xx', function(done) { + responseCode = 404; + setTimeout(function() { responseCode = 200; }, 50); + + util.waitForUrl(baseUrl, 200). + then(function() {}). // done needs no argument to pass. + thenFinally(done); + }); + + it('fails if URL always returns 4xx', function(done) { + responseCode = 404; + + util.waitForUrl(baseUrl, 50). + then(function() { done('Expected to time out'); }, + function() { done(); }); + }); + + it('fails if cannot connect to server', function(done) { + killServer(function(e) { + if (e) return done(e); + + util.waitForUrl(baseUrl, 50). + then(function() { done('Expected to time out'); }, + function() { done(); }); + }); + }); + + it('can cancel wait', function(done) { + responseCode = 404; + var err = Error('cancelled!'); + var isReady = util.waitForUrl(baseUrl, 200). + then(function() { done('Did not expect to succeed'); }). + then(null, function(e) { + assert.equal(err, e); + }). + then(function() { done(); }, done); + + setTimeout(function() { + isReady.cancel(err); + }, 50); + }); + }); +}); diff --git a/node_modules/selenium-webdriver/test/net/portprober_test.js b/node_modules/selenium-webdriver/test/net/portprober_test.js new file mode 100644 index 0000000..ae58cb6 --- /dev/null +++ b/node_modules/selenium-webdriver/test/net/portprober_test.js @@ -0,0 +1,127 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var assert = require('assert'), + net = require('net'); + +var promise = require('../..').promise, + portprober = require('../../net/portprober'); + +describe('isFree', function() { + + var server; + + beforeEach(function() { + server = net.createServer(function(){}); + }) + + afterEach(function(done) { + if (!server) return done(); + server.close(function() { + done(); + }); + }); + + it('should work for INADDR_ANY', function(done) { + server.listen(0, function() { + var port = server.address().port; + assertPortNotfree(port).then(function() { + var done = promise.defer(); + server.close(function() { + server = null; + done.fulfill(assertPortIsFree(port)); + }); + return done.promise; + }).then(function() { done(); }, done); + }); + }); + + it('should work for a specific host', function(done) { + var host = '127.0.0.1'; + server.listen(0, host, function() { + var port = server.address().port; + assertPortNotfree(port, host).then(function() { + var done = promise.defer(); + server.close(function() { + server = null; + done.fulfill(assertPortIsFree(port, host)); + }); + return done.promise; + }).then(function() { done(); }, done); + }); + }); +}); + +describe('findFreePort', function() { + var server; + + beforeEach(function() { + server = net.createServer(function(){}); + }) + + afterEach(function(done) { + if (!server) return done(); + server.close(function() { + done(); + }); + }); + + it('should work for INADDR_ANY', function(done) { + portprober.findFreePort().then(function(port) { + server.listen(port, function() { + assertPortNotfree(port).then(function() { + var done = promise.defer(); + server.close(function() { + server = null; + done.fulfill(assertPortIsFree(port)); + }); + return done.promise; + }).then(function() { done(); }, done); + }); + }); + }); + + it('should work for a specific host', function(done) { + var host = '127.0.0.1'; + portprober.findFreePort(host).then(function(port) { + server.listen(port, host, function() { + assertPortNotfree(port, host).then(function() { + var done = promise.defer(); + server.close(function() { + server = null; + done.fulfill(assertPortIsFree(port, host)); + }); + return done.promise; + }).then(function() { done(); }, done); + }); + }); + }); +}); + + +function assertPortIsFree(port, opt_host) { + return portprober.isFree(port, opt_host).then(function(free) { + assert.ok(free, 'port should be free'); + }); +} + + +function assertPortNotfree(port, opt_host) { + return portprober.isFree(port, opt_host).then(function(free) { + assert.ok(!free, 'port should is not free'); + }); +} diff --git a/node_modules/selenium-webdriver/test/page_loading_test.js b/node_modules/selenium-webdriver/test/page_loading_test.js new file mode 100644 index 0000000..812faae --- /dev/null +++ b/node_modules/selenium-webdriver/test/page_loading_test.js @@ -0,0 +1,152 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var By = require('..').By, + ErrorCode = require('..').error.ErrorCode, + assert = require('../testing/assert'), + test = require('../lib/test'), + Browser = test.Browser, + Pages = test.Pages; + + +test.suite(function(env) { + var browsers = env.browsers, + waitForTitleToBe = env.waitForTitleToBe; + + var driver; + beforeEach(function() { driver = env.driver; }); + + test.it('should wait for document to be loaded', function() { + driver.get(Pages.simpleTestPage); + assert(driver.getTitle()).equalTo('Hello WebDriver'); + }); + + test.it('should follow redirects sent in the http response headers', + function() { + driver.get(Pages.redirectPage); + assert(driver.getTitle()).equalTo('We Arrive Here'); + }); + + test.ignore(browsers(Browser.ANDROID)).it('should follow meta redirects', + function() { + driver.get(Pages.metaRedirectPage); + assert(driver.getTitle()).equalTo('We Arrive Here'); + }); + + test.it('should be able to get a fragment on the current page', function() { + driver.get(Pages.xhtmlTestPage); + driver.get(Pages.xhtmlTestPage + '#text'); + driver.findElement(By.id('id1')); + }); + + test.ignore(browsers(Browser.ANDROID, Browser.IOS)). + it('should wait for all frames to load in a frameset', function() { + driver.get(Pages.framesetPage); + driver.switchTo().frame(0); + + driver.findElement(By.css('span#pageNumber')).getText().then(function(txt) { + assert(txt.trim()).equalTo('1'); + }); + + driver.switchTo().defaultContent(); + driver.switchTo().frame(1); + driver.findElement(By.css('span#pageNumber')).getText().then(function(txt) { + assert(txt.trim()).equalTo('2'); + }); + }); + + test.ignore(browsers(Browser.ANDROID, Browser.SAFARI)). + it('should be able to navigate back in browser history', function() { + driver.get(Pages.formPage); + + driver.findElement(By.id('imageButton')).click(); + waitForTitleToBe('We Arrive Here'); + + driver.navigate().back(); + assert(driver.getTitle()).equalTo('We Leave From Here'); + }); + + test.ignore(browsers(Browser.SAFARI)). + it('should be able to navigate back in presence of iframes', function() { + driver.get(Pages.xhtmlTestPage); + + driver.findElement(By.name('sameWindow')).click(); + waitForTitleToBe('This page has iframes'); + + driver.navigate().back(); + assert(driver.getTitle()).equalTo('XHTML Test Page'); + }); + + test.ignore(browsers(Browser.ANDROID, Browser.SAFARI)). + it('should be able to navigate forwards in browser history', function() { + driver.get(Pages.formPage); + + driver.findElement(By.id('imageButton')).click(); + waitForTitleToBe('We Arrive Here'); + + driver.navigate().back(); + waitForTitleToBe('We Leave From Here'); + + driver.navigate().forward(); + waitForTitleToBe('We Arrive Here'); + }); + + test.it('should be able to refresh a page', function() { + driver.get(Pages.xhtmlTestPage); + + driver.navigate().refresh(); + + assert(driver.getTitle()).equalTo('XHTML Test Page'); + }); + + test.it('should return title of page if set', function() { + driver.get(Pages.xhtmlTestPage); + assert(driver.getTitle()).equalTo('XHTML Test Page'); + + driver.get(Pages.simpleTestPage); + assert(driver.getTitle()).equalTo('Hello WebDriver'); + }); + + // Only implemented in Firefox. + test.ignore(browsers( + Browser.ANDROID, + Browser.CHROME, + Browser.IE, + Browser.IOS, + Browser.OPERA, + Browser.PHANTOMJS, + Browser.SAFARI)). + it('should timeout if page load timeout is set', function() { + driver.call(function() { + driver.manage().timeouts().pageLoadTimeout(1); + driver.get(Pages.sleepingPage + '?time=3'). + then(function() { + throw Error('Should have timed out on page load'); + }, function(e) { + assert(e.code).equalTo(ErrorCode.SCRIPT_TIMEOUT); + }); + }).then(resetPageLoad, function(err) { + resetPageLoad().thenFinally(function() { + throw err; + }); + }); + + function resetPageLoad() { + return driver.manage().timeouts().pageLoadTimeout(-1); + } + }); +}); diff --git a/node_modules/selenium-webdriver/test/proxy_test.js b/node_modules/selenium-webdriver/test/proxy_test.js new file mode 100644 index 0000000..89d66dd --- /dev/null +++ b/node_modules/selenium-webdriver/test/proxy_test.js @@ -0,0 +1,157 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var http = require('http'), + url = require('url'); + +var promise = require('..').promise, + proxy = require('../proxy'), + assert = require('../testing/assert'), + test = require('../lib/test'), + Server = require('../lib/test/httpserver').Server, + Browser = test.Browser, + Pages = test.Pages; + + +test.suite(function(env) { + env.autoCreateDriver = false; + + function writeResponse(res, body, encoding, contentType) { + res.writeHead(200, { + 'Content-Length': Buffer.byteLength(body, encoding), + 'Content-Type': contentType + }); + res.end(body); + } + + function writePacFile(res) { + writeResponse(res, [ + 'function FindProxyForURL(url, host) {', + ' if (shExpMatch(url, "' + goodbyeServer.url('*') + '")) {', + ' return "DIRECT";', + ' }', + ' return "PROXY ' + proxyServer.host() + '";', + '}' + ].join('\n'), 'ascii', 'application/x-javascript-config'); + } + + var proxyServer = new Server(function(req, res) { + var pathname = url.parse(req.url).pathname; + if (pathname === '/proxy.pac') { + return writePacFile(res); + } + + writeResponse(res, [ + '', + 'Proxy page', + '

      This is the proxy landing page

      ' + ].join(''), 'utf8', 'text/html; charset=UTF-8'); + }); + + var helloServer = new Server(function(req, res) { + writeResponse(res, [ + '', + 'Hello', + '

      Hello, world!

      ' + ].join(''), 'utf8', 'text/html; charset=UTF-8'); + }); + + var goodbyeServer = new Server(function(req, res) { + writeResponse(res, [ + '', + 'Goodbye', + '

      Goodbye, world!

      ' + ].join(''), 'utf8', 'text/html; charset=UTF-8'); + }); + + test.before(proxyServer.start.bind(proxyServer)); + test.before(helloServer.start.bind(helloServer)); + test.before(goodbyeServer.start.bind(helloServer)); + + test.after(proxyServer.stop.bind(proxyServer)); + test.after(helloServer.stop.bind(helloServer)); + test.after(goodbyeServer.stop.bind(goodbyeServer)); + + test.afterEach(env.dispose.bind(env)); + + test.ignore(env.browsers(Browser.SAFARI)). // Proxy support not implemented. + describe('manual proxy settings', function() { + // phantomjs 1.9.1 in webdriver mode does not appear to respect proxy + // settings. + test.ignore(env.browsers(Browser.PHANTOMJS)). + it('can configure HTTP proxy host', function() { + var driver = env.builder(). + setProxy(proxy.manual({ + http: proxyServer.host() + })). + build(); + + driver.get(helloServer.url()); + assert(driver.getTitle()).equalTo('Proxy page'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('This is the proxy landing page'); + }); + + // PhantomJS does not support bypassing the proxy for individual hosts. + test.ignore(env.browsers(Browser.PHANTOMJS)). + it('can bypass proxy for specific hosts', function() { + var driver = env.builder(). + setProxy(proxy.manual({ + http: proxyServer.host(), + bypass: helloServer.host() + })). + build(); + + driver.get(helloServer.url()); + assert(driver.getTitle()).equalTo('Hello'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('Hello, world!'); + + driver.get(goodbyeServer.url()); + assert(driver.getTitle()).equalTo('Proxy page'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('This is the proxy landing page'); + }); + + // TODO: test ftp and https proxies. + }); + + // PhantomJS does not support PAC file proxy configuration. + // Safari does not support proxies. + test.ignore(env.browsers(Browser.PHANTOMJS, Browser.SAFARI)). + describe('pac proxy settings', function() { + test.it('can configure proxy through PAC file', function() { + var driver = env.builder(). + setProxy(proxy.pac(proxyServer.url('/proxy.pac'))). + build(); + + driver.get(helloServer.url()); + assert(driver.getTitle()).equalTo('Proxy page'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('This is the proxy landing page'); + + driver.get(goodbyeServer.url()); + assert(driver.getTitle()).equalTo('Goodbye'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('Goodbye, world!'); + }); + }); + + // TODO: figure out how to test direct and system proxy settings. + describe.skip('direct proxy settings', function() {}); + describe.skip('system proxy settings', function() {}); +}); diff --git a/node_modules/selenium-webdriver/test/stale_element_test.js b/node_modules/selenium-webdriver/test/stale_element_test.js new file mode 100644 index 0000000..81dacc7 --- /dev/null +++ b/node_modules/selenium-webdriver/test/stale_element_test.js @@ -0,0 +1,63 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var fail = require('assert').fail; + +var By = require('..').By, + error = require('..').error, + assert = require('../testing/assert'), + test = require('../lib/test'), + Browser = test.Browser, + Pages = test.Pages; + + +test.suite(function(env) { + var driver; + beforeEach(function() { driver = env.driver; }); + + test.it( + 'dynamically removing elements from the DOM trigger a ' + + 'StaleElementReferenceError', + function() { + driver.get(Pages.javascriptPage); + + var toBeDeleted = driver.findElement(By.id('deleted')); + assert(toBeDeleted.isDisplayed()).isTrue(); + + driver.findElement(By.id('delete')).click(); + driver.wait(function() { + return toBeDeleted.isDisplayed(). + then(function() { return false; }). + then(null, function(e) { + if (e.code === error.ErrorCode.STALE_ELEMENT_REFERENCE) { + return true; + } + throw e; + }); + }, 5000, 'Element should be stale at this point'); + }); + + test.it('an element found in a different frame is stale', function() { + driver.get(Pages.missedJsReferencePage); + driver.switchTo().frame('inner'); + var el = driver.findElement(By.id('oneline')); + driver.switchTo().defaultContent(); + el.getText().then(fail, function(e) { + assert(e.code).equalTo(error.ErrorCode.STALE_ELEMENT_REFERENCE); + }); + }); +}); \ No newline at end of file diff --git a/node_modules/selenium-webdriver/test/tag_name_test.js b/node_modules/selenium-webdriver/test/tag_name_test.js new file mode 100644 index 0000000..c4f1672 --- /dev/null +++ b/node_modules/selenium-webdriver/test/tag_name_test.js @@ -0,0 +1,29 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var By = require('..').By, + assert = require('../testing/assert'), + test = require('../lib/test'); + + +test.suite(function(env) { + test.it('should return lower case tag name', function() { + env.driver.get(test.Pages.formPage); + assert(env.driver.findElement(By.id('cheese')).getTagName()). + equalTo('input'); + }); +}); diff --git a/node_modules/selenium-webdriver/test/testing/index_test.js b/node_modules/selenium-webdriver/test/testing/index_test.js new file mode 100644 index 0000000..bcd1d69 --- /dev/null +++ b/node_modules/selenium-webdriver/test/testing/index_test.js @@ -0,0 +1,41 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var assert = require('assert'); + +var test = require('../../testing'); + +describe('Mocha Integration', function() { + + describe('beforeEach properly binds "this"', function() { + beforeEach(function() { this.x = 1; }); + test.beforeEach(function() { this.x = 2; }); + it('', function() { assert.equal(this.x, 2); }); + }); + + describe('afterEach properly binds "this"', function() { + it('', function() { this.x = 1; }); + test.afterEach(function() { this.x = 2; }); + afterEach(function() { assert.equal(this.x, 2); }); + }); + + describe('it properly binds "this"', function() { + beforeEach(function() { this.x = 1; }); + test.it('', function() { this.x = 2; }); + afterEach(function() { assert.equal(this.x, 2); }); + }); +}); diff --git a/node_modules/selenium-webdriver/test/window_test.js b/node_modules/selenium-webdriver/test/window_test.js new file mode 100644 index 0000000..2abd10e --- /dev/null +++ b/node_modules/selenium-webdriver/test/window_test.js @@ -0,0 +1,107 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var assert = require('../testing/assert'), + test = require('../lib/test'), + Browser = test.Browser; + + +test.suite(function(env) { + var driver; + beforeEach(function() { + driver = env.driver; + driver.switchTo().defaultContent(); + }); + + test.it('can set size of the current window', function() { + changeSizeBy(-20, -20); + }); + + test.it('can set size of the current window from frame', function() { + driver.get(test.Pages.framesetPage); + driver.switchTo().frame('fourth'); + changeSizeBy(-20, -20); + }); + + test.it('can set size of the current window from iframe', function() { + driver.get(test.Pages.iframePage); + driver.switchTo().frame('iframe1-name'); + changeSizeBy(-20, -20); + }); + + test.it('can set the window position of the current window', function() { + driver.manage().window().getPosition().then(function(position) { + driver.manage().window().setSize(640, 480); + driver.manage().window().setPosition(position.x + 10, position.y + 10); + + // For phantomjs, setPosition is a no-op and the "window" stays at (0, 0) + if (env.browser === Browser.PHANTOMJS) { + driver.manage().window().getPosition().then(function(position) { + assert(position.x).equalTo(0); + assert(position.y).equalTo(0); + }); + } else { + driver.wait(forPositionToBe(position.x + 10, position.y + 10), 1000); + } + }); + }); + + test.it('can set the window position from a frame', function() { + driver.get(test.Pages.iframePage); + driver.switchTo().frame('iframe1-name'); + driver.manage().window().getPosition().then(function(position) { + driver.manage().window().setSize(640, 480); + driver.manage().window().setPosition(position.x + 10, position.y + 10); + + // For phantomjs, setPosition is a no-op and the "window" stays at (0, 0) + if (env.browser === Browser.PHANTOMJS) { + driver.manage().window().getPosition().then(function(position) { + assert(position.x).equalTo(0); + assert(position.y).equalTo(0); + }); + } else { + driver.wait(forPositionToBe(position.x + 10, position.y + 10), 1000); + } + }); + }); + + function changeSizeBy(dx, dy) { + driver.manage().window().getSize().then(function(size) { + driver.manage().window().setSize(size.width + dx, size.height + dy); + driver.wait(forSizeToBe(size.width + dx, size.height + dy), 1000); + }) + } + + function forSizeToBe(w, h) { + return function() { + return driver.manage().window().getSize().then(function(size) { + return size.width === w && size.height === h; + }); + }; + } + + function forPositionToBe(x, y) { + return function() { + return driver.manage().window().getPosition().then(function(position) { + return position.x === x && + // On OSX, the window height may be bumped down 22px for the top + // status bar. + (position.y >= y && position.y <= (y + 22)); + }); + }; + } +}); diff --git a/node_modules/selenium-webdriver/testing/assert.js b/node_modules/selenium-webdriver/testing/assert.js new file mode 100644 index 0000000..80fcda3 --- /dev/null +++ b/node_modules/selenium-webdriver/testing/assert.js @@ -0,0 +1,43 @@ +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Defines a library that simplifies writing assertions against + * promised values. + * + *
      + *
      + * NOTE: This module is considered experimental and is subject to + * change, or removal, at any time! + *
      + *
      + * + * Sample usage: + *
      
      + * var driver = new webdriver.Builder().build();
      + * driver.get('http://www.google.com');
      + *
      + * assert(driver.getTitle()).equalTo('Google');
      + * 
      + */ + +var base = require('../_base'), + assert = base.require('webdriver.testing.assert'); + + +// PUBLIC API + + +/** @type {webdriver.testing.assert.} */ +module.exports = assert; diff --git a/node_modules/selenium-webdriver/testing/index.js b/node_modules/selenium-webdriver/testing/index.js new file mode 100644 index 0000000..f6831bc --- /dev/null +++ b/node_modules/selenium-webdriver/testing/index.js @@ -0,0 +1,248 @@ +// Copyright 2013 Selenium committers +// Copyright 2013 Software Freedom Conservancy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Provides wrappers around the following global functions from + * Mocha's BDD interface: + *
        + *
      • after + *
      • afterEach + *
      • before + *
      • beforeEach + *
      • it + *
      • it.only + *
      • it.skip + *
      • xit + *
      + * + *

      The provided wrappers leverage the {@link webdriver.promise.ControlFlow} + * to simplify writing asynchronous tests: + *

      
      + * var webdriver = require('selenium-webdriver'),
      + *     portprober = require('selenium-webdriver/net/portprober'),
      + *     remote = require('selenium-webdriver/remote'),
      + *     test = require('selenium-webdriver/testing');
      + *
      + * test.describe('Google Search', function() {
      + *   var driver, server;
      + *
      + *   test.before(function() {
      + *     server = new remote.SeleniumServer(
      + *         'path/to/selenium-server-standalone.jar',
      + *         {port: portprober.findFreePort()});
      + *     server.start();
      + *
      + *     driver = new webdriver.Builder().
      + *         withCapabilities({'browserName': 'firefox'}).
      + *         usingServer(server.address()).
      + *         build();
      + *   });
      + *
      + *   test.after(function() {
      + *     driver.quit();
      + *     server.stop();
      + *   });
      + *
      + *   test.it('should append query to title', function() {
      + *     driver.get('http://www.google.com');
      + *     driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
      + *     driver.findElement(webdriver.By.name('btnG')).click();
      + *     driver.wait(function() {
      + *       return driver.getTitle().then(function(title) {
      + *         return 'webdriver - Google Search' === title;
      + *       });
      + *     }, 1000, 'Waiting for title to update');
      + *   });
      + * });
      + * 
      + * + *

      You may conditionally suppress a test function using the exported + * "ignore" function. If the provided predicate returns true, the attached + * test case will be skipped: + *

      
      + *   test.ignore(maybe()).it('is flaky', function() {
      + *     if (Math.random() < 0.5) throw Error();
      + *   });
      + *
      + *   function maybe() { return Math.random() < 0.5; }
      + * 
      + */ + +var promise = require('..').promise; +var flow = promise.controlFlow(); + + +/** + * Wraps a function so that all passed arguments are ignored. + * @param {!Function} fn The function to wrap. + * @return {!Function} The wrapped function. + */ +function seal(fn) { + return function() { + fn(); + }; +} + + +/** + * Wraps a function on Mocha's BDD interface so it runs inside a + * webdriver.promise.ControlFlow and waits for the flow to complete before + * continuing. + * @param {!Function} globalFn The function to wrap. + * @return {!Function} The new function. + */ +function wrapped(globalFn) { + return function() { + switch (arguments.length) { + case 1: + globalFn(asyncTestFn(arguments[0])); + break; + + case 2: + globalFn(arguments[0], asyncTestFn(arguments[1])); + break; + + default: + throw Error('Invalid # arguments: ' + arguments.length); + } + }; + + function asyncTestFn(fn) { + var ret = function(done) { + this.timeout(0); + var timeout = this.timeout; + this.timeout = undefined; // Do not let tests change the timeout. + try { + var testFn = fn.bind(this); + flow.execute(function() { + var done = promise.defer(); + promise.asap(testFn(done.reject), done.fulfill, done.reject); + return done.promise; + }).then(seal(done), done); + } finally { + this.timeout = timeout; + } + }; + + ret.toString = function() { + return fn.toString(); + }; + + return ret; + } +} + + +/** + * Ignores the test chained to this function if the provided predicate returns + * true. + * @param {function(): boolean} predicateFn A predicate to call to determine + * if the test should be suppressed. This function MUST be synchronous. + * @return {!Object} An object with wrapped versions of {@link #it()} and + * {@link #describe()} that ignore tests as indicated by the predicate. + */ +function ignore(predicateFn) { + var describe = wrap(exports.xdescribe, exports.describe); + describe.only = wrap(exports.xdescribe, exports.describe.only); + + var it = wrap(exports.xit, exports.it); + it.only = wrap(exports.xit, exports.it.only); + + return { + describe: describe, + it: it + }; + + function wrap(onSkip, onRun) { + return function(title, fn) { + if (predicateFn()) { + onSkip(title, fn); + } else { + onRun(title, fn); + } + }; + } +} + + +// PUBLIC API + +/** + * Registers a new test suite. + * @param {string} name The suite name. + * @param {function()=} fn The suite function, or {@code undefined} to define + * a pending test suite. + */ +exports.describe = global.describe; + +/** + * Defines a suppressed test suite. + * @param {string} name The suite name. + * @param {function()=} fn The suite function, or {@code undefined} to define + * a pending test suite. + */ +exports.xdescribe = global.xdescribe; +exports.describe.skip = global.describe.skip; + +/** + * Register a function to call after the current suite finishes. + * @param {function()} fn . + */ +exports.after = wrapped(global.after); + +/** + * Register a function to call after each test in a suite. + * @param {function()} fn . + */ +exports.afterEach = wrapped(global.afterEach); + +/** + * Register a function to call before the current suite starts. + * @param {function()} fn . + */ +exports.before = wrapped(global.before); + +/** + * Register a function to call before each test in a suite. + * @param {function()} fn . + */ +exports.beforeEach = wrapped(global.beforeEach); + +/** + * Add a test to the current suite. + * @param {string} name The test name. + * @param {function()=} fn The test function, or {@code undefined} to define + * a pending test case. + */ +exports.it = wrapped(global.it); + +/** + * An alias for {@link #it()} that flags the test as the only one that should + * be run within the current suite. + * @param {string} name The test name. + * @param {function()=} fn The test function, or {@code undefined} to define + * a pending test case. + */ +exports.iit = exports.it.only = wrapped(global.it.only); + +/** + * Adds a test to the current suite while suppressing it so it is not run. + * @param {string} name The test name. + * @param {function()=} fn The test function, or {@code undefined} to define + * a pending test case. + */ +exports.xit = exports.it.skip = wrapped(global.xit); + +exports.ignore = ignore; diff --git a/package.json b/package.json index e541def..81ad978 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "none", "devDependencies": { "grunt": "^0.4.5", - "grunt-contrib-connect": "^0.8.0" + "grunt-contrib-connect": "^0.8.0", + "selenium-webdriver": "^2.42.1" } }