From 8c6e8352ce5e76f45a883d2a48a6da03b22a0681 Mon Sep 17 00:00:00 2001 From: Jason Leyba Date: Fri, 12 Sep 2014 11:43:09 -0700 Subject: [PATCH] Update js docs for 2.43.1 --- docs/api/javascript/class_bot_Error.html | 6 +- .../api/javascript/class_goog_Disposable.html | 37 +++ docs/api/javascript/class_goog_Uri.html | 47 ++-- .../javascript/class_goog_Uri_QueryData.html | 26 +- .../class_goog_asserts_AssertionError.html | 2 +- .../class_goog_async_run_WorkItem_.html | 1 + .../javascript/class_goog_debug_Error.html | 2 +- .../class_goog_debug_LogBuffer.html | 2 + .../class_goog_debug_LogRecord.html | 12 + .../javascript/class_goog_debug_Logger.html | 59 +++++ .../class_goog_debug_Logger_Level.html | 32 +++ .../javascript/class_goog_dom_DomHelper.html | 104 ++++++++ .../class_goog_events_BrowserEvent.html | 25 ++ .../javascript/class_goog_events_Event.html | 16 ++ .../javascript/class_goog_events_EventId.html | 10 + .../class_goog_events_EventTarget.html | 68 +++++ .../class_goog_events_Listener.html | 6 + .../class_goog_events_ListenerMap.html | 23 ++ .../class_goog_iter_GroupByIterator_.html | 2 +- .../javascript/class_goog_iter_Iterator.html | 2 +- .../class_goog_json_Serializer.html | 4 +- .../class_goog_labs_testing_AllOfMatcher.html | 2 +- .../class_goog_labs_testing_AnyOfMatcher.html | 2 +- ...lass_goog_labs_testing_CloseToMatcher.html | 2 +- ...og_labs_testing_ContainsStringMatcher.html | 2 +- ...ass_goog_labs_testing_EndsWithMatcher.html | 2 +- ...ting_EqualToIgnoringWhitespaceMatcher.html | 2 +- ...lass_goog_labs_testing_EqualToMatcher.html | 2 +- ...class_goog_labs_testing_EqualsMatcher.html | 2 +- ...abs_testing_GreaterThanEqualToMatcher.html | 2 +- ..._goog_labs_testing_GreaterThanMatcher.html | 2 +- ..._goog_labs_testing_HasPropertyMatcher.html | 2 +- ...s_goog_labs_testing_InstanceOfMatcher.html | 2 +- .../class_goog_labs_testing_IsNotMatcher.html | 2 +- ...class_goog_labs_testing_IsNullMatcher.html | 2 +- ...labs_testing_IsNullOrUndefinedMatcher.html | 2 +- ..._goog_labs_testing_IsUndefinedMatcher.html | 2 +- ...g_labs_testing_LessThanEqualToMatcher.html | 2 +- ...ass_goog_labs_testing_LessThanMatcher.html | 2 +- .../class_goog_labs_testing_MatcherError.html | 2 +- ...goog_labs_testing_ObjectEqualsMatcher.html | 2 +- .../class_goog_labs_testing_RegexMatcher.html | 2 +- ...s_goog_labs_testing_StartsWithMatcher.html | 2 +- ..._testing_StringContainsInOrderMatcher.html | 2 +- docs/api/javascript/class_goog_math_Box.html | 23 ++ .../class_goog_math_Coordinate.html | 22 ++ docs/api/javascript/class_goog_math_Rect.html | 34 +++ docs/api/javascript/class_goog_math_Size.html | 10 + .../class_goog_net_DefaultXmlHttpFactory.html | 2 +- .../class_goog_net_WrapperXmlHttpFactory.html | 2 +- .../class_goog_net_XmlHttpFactory.html | 2 +- .../javascript/class_goog_structs_Map.html | 2 +- .../javascript/class_goog_structs_Set.html | 28 +++ .../class_goog_testing_AsyncTestCase.html | 81 ++++++ ...syncTestCase_ControlBreakingException.html | 1 + .../class_goog_testing_FunctionCall.html | 2 + .../class_goog_testing_JsUnitException.html | 2 + ...og_testing_LooseExpectationCollection.html | 4 + .../class_goog_testing_LooseMock.html | 25 ++ .../javascript/class_goog_testing_Mock.html | 29 +++ .../class_goog_testing_MockClock.html | 66 +++++ .../class_goog_testing_MockControl.html | 22 ++ .../class_goog_testing_MockExpectation.html | 3 + ...ass_goog_testing_ObjectPropertyString.html | 3 + .../class_goog_testing_PropertyReplacer.html | 46 ++++ .../class_goog_testing_StrictMock.html | 23 ++ .../class_goog_testing_TestCase.html | 85 +++++++ .../class_goog_testing_TestCase_Error.html | 1 + .../class_goog_testing_TestCase_Result.html | 5 + .../class_goog_testing_TestCase_Test.html | 2 + ..._goog_testing_TestCase_protectedDate_.html | 3 + .../class_goog_testing_TestRunner.html | 17 ++ .../class_goog_testing_events_Event.html | 6 + ..._testing_mockmatchers_ArgumentMatcher.html | 9 + ...g_testing_mockmatchers_IgnoreArgument.html | 8 + ..._goog_testing_mockmatchers_InstanceOf.html | 6 + ...oog_testing_mockmatchers_ObjectEquals.html | 5 + ...goog_testing_mockmatchers_RegexpMatch.html | 6 + ...oog_testing_mockmatchers_SaveArgument.html | 8 + ...lass_goog_testing_mockmatchers_TypeOf.html | 6 + .../class_goog_testing_stacktrace_Frame.html | 6 + .../class_webdriver_AbstractBuilder.html | 8 +- .../class_webdriver_ActionSequence.html | 2 +- .../api/javascript/class_webdriver_Alert.html | 85 +------ .../class_webdriver_AlertPromise.html | 20 ++ .../javascript/class_webdriver_Builder.html | 6 +- .../class_webdriver_Capabilities.html | 22 +- .../javascript/class_webdriver_Command.html | 2 +- .../class_webdriver_EventEmitter.html | 2 +- .../class_webdriver_FirefoxDomExecutor.html | 2 +- .../javascript/class_webdriver_Locator.html | 2 +- .../javascript/class_webdriver_Session.html | 2 +- .../class_webdriver_UnhandledAlertError.html | 7 +- .../javascript/class_webdriver_WebDriver.html | 92 +++---- .../class_webdriver_WebDriver_Logs.html | 6 +- .../class_webdriver_WebDriver_Navigation.html | 10 +- .../class_webdriver_WebDriver_Options.html | 18 +- ...ass_webdriver_WebDriver_TargetLocator.html | 14 +- .../class_webdriver_WebDriver_Timeouts.html | 8 +- .../class_webdriver_WebDriver_Window.html | 12 +- .../class_webdriver_WebElement.html | 125 ++-------- .../class_webdriver_WebElementPromise.html | 147 +++++++++++ .../class_webdriver_http_CorsClient.html | 2 +- .../class_webdriver_http_Executor.html | 2 +- .../class_webdriver_http_Request.html | 2 +- .../class_webdriver_http_Response.html | 2 +- .../class_webdriver_http_XhrClient.html | 2 +- .../class_webdriver_logging_Entry.html | 6 +- .../class_webdriver_logging_Preferences.html | 2 + ..._webdriver_promise_CanceledTaskError_.html | 4 +- .../class_webdriver_promise_ControlFlow.html | 48 ++-- .../class_webdriver_promise_Deferred.html | 75 +----- .../class_webdriver_promise_Frame_.html | 85 +------ .../class_webdriver_promise_Node_.html | 75 +----- .../class_webdriver_promise_Promise.html | 65 +---- .../class_webdriver_promise_Task_.html | 75 +----- .../class_webdriver_stacktrace_Frame.html | 2 +- .../class_webdriver_stacktrace_Snapshot.html | 2 +- .../class_webdriver_testing_Assertion.html | 2 +- ..._testing_Assertion_DelegatingMatcher_.html | 2 +- ...ass_webdriver_testing_ContainsMatcher.html | 2 +- ...ss_webdriver_testing_NegatedAssertion.html | 2 +- .../class_webdriver_testing_TestCase.html | 76 ++++++ docs/api/javascript/dossier.js | 10 +- docs/api/javascript/enum_bot_ErrorCode.html | 2 +- docs/api/javascript/enum_bot_Error_State.html | 2 +- .../enum_goog_Disposable_MonitoringMode.html | 6 + .../enum_goog_dom_BrowserFeature.html | 8 + .../javascript/enum_goog_dom_NodeType.html | 2 +- .../api/javascript/enum_goog_dom_TagName.html | 2 + ..._goog_events_BrowserEvent_MouseButton.html | 1 + .../enum_goog_events_BrowserFeature.html | 4 + ...num_goog_events_CaptureSimulationMode.html | 3 + .../enum_goog_events_EventType.html | 1 + .../javascript/enum_goog_events_KeyCodes.html | 22 ++ .../enum_goog_net_XmlHttp_OptionType.html | 2 +- .../enum_goog_net_XmlHttp_ReadyState.html | 2 +- .../javascript/enum_goog_string_Unicode.html | 2 +- .../enum_goog_testing_TestCase_Order.html | 2 + .../enum_goog_uri_utils_CharCode_.html | 2 +- .../enum_goog_uri_utils_ComponentIndex.html | 2 +- ...num_goog_uri_utils_StandardQueryParam.html | 2 +- .../javascript/enum_webdriver_Browser.html | 2 +- .../api/javascript/enum_webdriver_Button.html | 2 +- .../javascript/enum_webdriver_Capability.html | 14 +- .../enum_webdriver_CommandName.html | 2 +- ...bdriver_FirefoxDomExecutor_Attribute_.html | 2 +- ...bdriver_FirefoxDomExecutor_EventType_.html | 2 +- docs/api/javascript/enum_webdriver_Key.html | 4 +- .../enum_webdriver_logging_Level.html | 2 +- .../enum_webdriver_logging_LevelName.html | 1 - .../enum_webdriver_logging_Type.html | 2 +- ...bdriver_promise_ControlFlow_EventType.html | 4 +- ...num_webdriver_promise_Deferred_State_.html | 2 +- docs/api/javascript/index.html | 2 +- ...nterface_goog_debug_EntryPointMonitor.html | 11 + ...interface_goog_disposable_IDisposable.html | 3 + .../interface_goog_events_Listenable.html | 84 +++++++ .../interface_goog_events_ListenableKey.html | 2 + .../interface_goog_labs_testing_Matcher.html | 2 +- .../interface_goog_net_XhrLike.html | 2 +- .../interface_goog_structs_Collection.html | 1 + .../interface_goog_testing_MockInterface.html | 3 + .../interface_webdriver_CommandExecutor.html | 2 +- .../interface_webdriver_http_Client.html | 2 +- .../interface_webdriver_promise_Thenable.html | 65 +++++ docs/api/javascript/license.html | 2 +- .../javascript/module_selenium-webdriver.html | 4 +- .../module_selenium-webdriver__base.html | 4 +- ...elenium-webdriver__base_class_Context.html | 3 + .../module_selenium-webdriver_builder.html | 2 +- ...enium-webdriver_builder_class_Builder.html | 67 ++++- .../module_selenium-webdriver_chrome.html | 9 +- ...elenium-webdriver_chrome_class_Driver.html | 5 + ...lenium-webdriver_chrome_class_Options.html | 6 +- ...webdriver_chrome_class_ServiceBuilder.html | 4 +- ...odule_selenium-webdriver_docs_dossier.html | 1 - .../module_selenium-webdriver_docs_types.html | 1 - .../module_selenium-webdriver_error.html | 2 +- .../module_selenium-webdriver_executors.html | 2 +- .../module_selenium-webdriver_firefox.html | 1 + ...ule_selenium-webdriver_firefox_binary.html | 1 + ...webdriver_firefox_binary_class_Binary.html | 4 + ...lenium-webdriver_firefox_class_Driver.html | 6 + ...enium-webdriver_firefox_class_Options.html | 4 + ..._selenium-webdriver_firefox_extension.html | 3 + ...le_selenium-webdriver_firefox_profile.html | 4 + ...bdriver_firefox_profile_class_Profile.html | 18 ++ .../module_selenium-webdriver_http.html | 2 +- ...enium-webdriver_http_class_HttpClient.html | 5 +- .../module_selenium-webdriver_http_util.html | 2 +- .../module_selenium-webdriver_io.html | 9 +- .../module_selenium-webdriver_io_exec.html | 10 + .../module_selenium-webdriver_net.html | 2 +- ...ule_selenium-webdriver_net_portprober.html | 2 +- .../module_selenium-webdriver_phantomjs.html | 3 +- ...nium-webdriver_phantomjs_class_Driver.html | 3 + .../module_selenium-webdriver_proxy.html | 6 +- .../module_selenium-webdriver_remote.html | 4 +- ...-webdriver_remote_class_DriverService.html | 20 +- ...webdriver_remote_class_SeleniumServer.html | 20 +- .../module_selenium-webdriver_testing.html | 18 +- ...ule_selenium-webdriver_testing_assert.html | 2 +- ...mespace_PRIMITIVE_EQUALITY_PREDICATES.html | 1 + docs/api/javascript/namespace_bot.html | 2 +- docs/api/javascript/namespace_bot_json.html | 2 +- .../javascript/namespace_bot_response.html | 2 +- .../javascript/namespace_bot_userAgent.html | 2 +- docs/api/javascript/namespace_goog.html | 153 +++++++----- docs/api/javascript/namespace_goog_array.html | 64 ++--- .../javascript/namespace_goog_asserts.html | 20 +- docs/api/javascript/namespace_goog_async.html | 14 ++ .../namespace_goog_async_nextTick.html | 11 + .../javascript/namespace_goog_async_run.html | 9 + docs/api/javascript/namespace_goog_debug.html | 28 ++- .../namespace_goog_debug_LogManager.html | 10 + ...mespace_goog_debug_entryPointRegistry.html | 17 ++ .../namespace_goog_defineClass.html | 16 ++ .../javascript/namespace_goog_disposable.html | 1 + docs/api/javascript/namespace_goog_dom.html | 233 +++++++++++++++++- .../javascript/namespace_goog_dom_vendor.html | 4 + .../api/javascript/namespace_goog_events.html | 97 ++++++++ .../javascript/namespace_goog_functions.html | 2 +- docs/api/javascript/namespace_goog_iter.html | 2 +- docs/api/javascript/namespace_goog_json.html | 10 +- docs/api/javascript/namespace_goog_labs.html | 2 +- .../namespace_goog_labs_testing.html | 2 +- .../namespace_goog_labs_userAgent.html | 2 +- ...namespace_goog_labs_userAgent_browser.html | 12 +- .../namespace_goog_labs_userAgent_engine.html | 2 +- .../namespace_goog_labs_userAgent_util.html | 2 +- docs/api/javascript/namespace_goog_math.html | 4 +- docs/api/javascript/namespace_goog_net.html | 2 +- .../namespace_goog_net_XmlHttp.html | 2 +- .../namespace_goog_net_XmlHttpDefines.html | 2 +- .../api/javascript/namespace_goog_object.html | 42 ++-- .../javascript/namespace_goog_reflect.html | 7 + .../api/javascript/namespace_goog_string.html | 52 ++-- .../javascript/namespace_goog_structs.html | 4 +- docs/api/javascript/namespace_goog_style.html | 211 ++++++++++++++++ .../javascript/namespace_goog_testing.html | 28 +++ .../namespace_goog_testing_MethodMock.html | 3 + .../namespace_goog_testing_asserts.html | 15 ++ .../namespace_goog_testing_events.html | 80 ++++++ .../namespace_goog_testing_jsunit.html | 1 + .../namespace_goog_testing_mockmatchers.html | 9 + .../namespace_goog_testing_stacktrace.html | 29 +++ .../namespace_goog_testing_watchers.html | 1 + docs/api/javascript/namespace_goog_uri.html | 2 +- .../javascript/namespace_goog_uri_utils.html | 67 ++--- .../javascript/namespace_goog_userAgent.html | 2 +- .../namespace_goog_userAgent_product.html | 2 +- docs/api/javascript/namespace_webdriver.html | 9 +- .../javascript/namespace_webdriver_By.html | 2 +- .../javascript/namespace_webdriver_http.html | 2 +- .../namespace_webdriver_logging.html | 4 +- .../namespace_webdriver_process.html | 2 +- .../namespace_webdriver_promise.html | 71 ++++-- .../namespace_webdriver_stacktrace.html | 29 +-- .../namespace_webdriver_testing.html | 3 +- .../namespace_webdriver_testing_assert.html | 2 +- .../namespace_webdriver_testing_asserts.html | 2 +- docs/api/javascript/source/_base.js.src.html | 2 +- .../api/javascript/source/builder.js.src.html | 2 +- docs/api/javascript/source/chrome.js.src.html | 2 +- .../source/docs/dossier.js.src.html | 1 - .../javascript/source/docs/types.js.src.html | 1 - docs/api/javascript/source/error.js.src.html | 2 +- .../javascript/source/executors.js.src.html | 2 +- .../source/firefox/binary.js.src.html | 1 + .../source/firefox/extension.js.src.html | 1 + .../source/firefox/index.js.src.html | 1 + .../source/firefox/profile.js.src.html | 1 + .../javascript/source/http/index.js.src.html | 2 +- .../javascript/source/http/util.js.src.html | 2 +- docs/api/javascript/source/index.js.src.html | 2 +- .../api/javascript/source/io/exec.js.src.html | 1 + .../javascript/source/io/index.js.src.html | 2 +- .../source/lib/atoms/error.js.src.html | 2 +- .../source/lib/atoms/json.js.src.html | 2 +- .../source/lib/atoms/response.js.src.html | 2 +- .../source/lib/atoms/userAgent.js.src.html | 2 +- .../source/lib/goog/array/array.js.src.html | 2 +- .../lib/goog/asserts/asserts.js.src.html | 2 +- .../lib/goog/async/nexttick.js.src.html | 1 + .../source/lib/goog/async/run.js.src.html | 1 + .../source/lib/goog/base.js.src.html | 2 +- .../source/lib/goog/debug/debug.js.src.html | 1 + .../goog/debug/entrypointregistry.js.src.html | 1 + .../source/lib/goog/debug/error.js.src.html | 2 +- .../lib/goog/debug/logbuffer.js.src.html | 1 + .../source/lib/goog/debug/logger.js.src.html | 1 + .../lib/goog/debug/logrecord.js.src.html | 1 + .../source/lib/goog/deps.js.src.html | 2 +- .../goog/disposable/disposable.js.src.html | 1 + .../goog/disposable/idisposable.js.src.html | 1 + .../lib/goog/dom/browserfeature.js.src.html | 1 + .../source/lib/goog/dom/dom.js.src.html | 1 + .../source/lib/goog/dom/nodetype.js.src.html | 2 +- .../source/lib/goog/dom/tagname.js.src.html | 1 + .../source/lib/goog/dom/vendor.js.src.html | 1 + .../lib/goog/events/browserevent.js.src.html | 1 + .../goog/events/browserfeature.js.src.html | 1 + .../source/lib/goog/events/event.js.src.html | 1 + .../lib/goog/events/eventid.js.src.html | 1 + .../source/lib/goog/events/events.js.src.html | 1 + .../lib/goog/events/eventtarget.js.src.html | 1 + .../lib/goog/events/eventtype.js.src.html | 1 + .../lib/goog/events/keycodes.js.src.html | 1 + .../lib/goog/events/listenable.js.src.html | 1 + .../lib/goog/events/listener.js.src.html | 1 + .../lib/goog/events/listenermap.js.src.html | 1 + .../lib/goog/functions/functions.js.src.html | 2 +- .../source/lib/goog/iter/iter.js.src.html | 2 +- .../source/lib/goog/json/json.js.src.html | 2 +- .../goog/labs/testing/assertthat.js.src.html | 2 +- .../labs/testing/logicmatcher.js.src.html | 2 +- .../lib/goog/labs/testing/matcher.js.src.html | 2 +- .../labs/testing/numbermatcher.js.src.html | 2 +- .../labs/testing/objectmatcher.js.src.html | 2 +- .../labs/testing/stringmatcher.js.src.html | 2 +- .../goog/labs/useragent/browser.js.src.html | 2 +- .../goog/labs/useragent/engine.js.src.html | 2 +- .../lib/goog/labs/useragent/util.js.src.html | 2 +- .../source/lib/goog/math/box.js.src.html | 1 + .../lib/goog/math/coordinate.js.src.html | 1 + .../source/lib/goog/math/math.js.src.html | 2 +- .../source/lib/goog/math/rect.js.src.html | 1 + .../source/lib/goog/math/size.js.src.html | 1 + .../net/wrapperxmlhttpfactory.js.src.html | 2 +- .../source/lib/goog/net/xhrlike.js.src.html | 2 +- .../source/lib/goog/net/xmlhttp.js.src.html | 2 +- .../lib/goog/net/xmlhttpfactory.js.src.html | 2 +- .../source/lib/goog/object/object.js.src.html | 2 +- .../lib/goog/reflect/reflect.js.src.html | 1 + .../source/lib/goog/string/string.js.src.html | 2 +- .../lib/goog/structs/collection.js.src.html | 1 + .../source/lib/goog/structs/map.js.src.html | 2 +- .../source/lib/goog/structs/set.js.src.html | 1 + .../lib/goog/structs/structs.js.src.html | 2 +- .../source/lib/goog/style/style.js.src.html | 1 + .../lib/goog/testing/asserts.js.src.html | 1 + .../goog/testing/asynctestcase.js.src.html | 1 + .../goog/testing/events/events.js.src.html | 1 + .../lib/goog/testing/functionmock.js.src.html | 1 + .../lib/goog/testing/jsunit.js.src.html | 1 + .../lib/goog/testing/loosemock.js.src.html | 1 + .../source/lib/goog/testing/mock.js.src.html | 1 + .../lib/goog/testing/mockclock.js.src.html | 1 + .../lib/goog/testing/mockcontrol.js.src.html | 1 + .../goog/testing/mockinterface.js.src.html | 1 + .../lib/goog/testing/mockmatchers.js.src.html | 1 + .../testing/objectpropertystring.js.src.html | 1 + .../goog/testing/propertyreplacer.js.src.html | 1 + .../goog/testing/recordfunction.js.src.html | 1 + .../lib/goog/testing/stacktrace.js.src.html | 1 + .../lib/goog/testing/strictmock.js.src.html | 1 + .../lib/goog/testing/testcase.js.src.html | 1 + .../lib/goog/testing/testrunner.js.src.html | 1 + .../lib/goog/testing/watchers.js.src.html | 1 + .../source/lib/goog/uri/uri.js.src.html | 2 +- .../source/lib/goog/uri/utils.js.src.html | 2 +- .../lib/goog/useragent/product.js.src.html | 2 +- .../useragent/product_isversion.js.src.html | 2 +- .../lib/goog/useragent/useragent.js.src.html | 2 +- .../lib/webdriver/abstractbuilder.js.src.html | 2 +- .../lib/webdriver/actionsequence.js.src.html | 2 +- .../source/lib/webdriver/builder.js.src.html | 2 +- .../source/lib/webdriver/button.js.src.html | 2 +- .../lib/webdriver/capabilities.js.src.html | 2 +- .../source/lib/webdriver/command.js.src.html | 2 +- .../source/lib/webdriver/events.js.src.html | 2 +- .../webdriver/firefoxdomexecutor.js.src.html | 2 +- .../lib/webdriver/http/corsclient.js.src.html | 2 +- .../lib/webdriver/http/http.js.src.html | 2 +- .../lib/webdriver/http/xhrclient.js.src.html | 2 +- .../source/lib/webdriver/key.js.src.html | 2 +- .../source/lib/webdriver/locators.js.src.html | 2 +- .../source/lib/webdriver/logging.js.src.html | 2 +- .../source/lib/webdriver/process.js.src.html | 2 +- .../source/lib/webdriver/promise.js.src.html | 2 +- .../source/lib/webdriver/session.js.src.html | 2 +- .../lib/webdriver/stacktrace.js.src.html | 2 +- .../lib/webdriver/testing/asserts.js.src.html | 2 +- .../webdriver/testing/testcase.js.src.html | 1 + .../lib/webdriver/webdriver.js.src.html | 2 +- .../javascript/source/net/index.js.src.html | 2 +- .../source/net/portprober.js.src.html | 2 +- .../javascript/source/phantomjs.js.src.html | 2 +- docs/api/javascript/source/proxy.js.src.html | 2 +- .../source/remote/index.js.src.html | 2 +- .../source/testing/assert.js.src.html | 2 +- .../source/testing/index.js.src.html | 2 +- docs/api/javascript/types.js | 2 +- 394 files changed, 3270 insertions(+), 1166 deletions(-) create mode 100644 docs/api/javascript/class_goog_Disposable.html create mode 100644 docs/api/javascript/class_goog_async_run_WorkItem_.html create mode 100644 docs/api/javascript/class_goog_debug_LogBuffer.html create mode 100644 docs/api/javascript/class_goog_debug_LogRecord.html create mode 100644 docs/api/javascript/class_goog_debug_Logger.html create mode 100644 docs/api/javascript/class_goog_debug_Logger_Level.html create mode 100644 docs/api/javascript/class_goog_dom_DomHelper.html create mode 100644 docs/api/javascript/class_goog_events_BrowserEvent.html create mode 100644 docs/api/javascript/class_goog_events_Event.html create mode 100644 docs/api/javascript/class_goog_events_EventId.html create mode 100644 docs/api/javascript/class_goog_events_EventTarget.html create mode 100644 docs/api/javascript/class_goog_events_Listener.html create mode 100644 docs/api/javascript/class_goog_events_ListenerMap.html create mode 100644 docs/api/javascript/class_goog_math_Box.html create mode 100644 docs/api/javascript/class_goog_math_Coordinate.html create mode 100644 docs/api/javascript/class_goog_math_Rect.html create mode 100644 docs/api/javascript/class_goog_math_Size.html create mode 100644 docs/api/javascript/class_goog_structs_Set.html create mode 100644 docs/api/javascript/class_goog_testing_AsyncTestCase.html create mode 100644 docs/api/javascript/class_goog_testing_AsyncTestCase_ControlBreakingException.html create mode 100644 docs/api/javascript/class_goog_testing_FunctionCall.html create mode 100644 docs/api/javascript/class_goog_testing_JsUnitException.html create mode 100644 docs/api/javascript/class_goog_testing_LooseExpectationCollection.html create mode 100644 docs/api/javascript/class_goog_testing_LooseMock.html create mode 100644 docs/api/javascript/class_goog_testing_Mock.html create mode 100644 docs/api/javascript/class_goog_testing_MockClock.html create mode 100644 docs/api/javascript/class_goog_testing_MockControl.html create mode 100644 docs/api/javascript/class_goog_testing_MockExpectation.html create mode 100644 docs/api/javascript/class_goog_testing_ObjectPropertyString.html create mode 100644 docs/api/javascript/class_goog_testing_PropertyReplacer.html create mode 100644 docs/api/javascript/class_goog_testing_StrictMock.html create mode 100644 docs/api/javascript/class_goog_testing_TestCase.html create mode 100644 docs/api/javascript/class_goog_testing_TestCase_Error.html create mode 100644 docs/api/javascript/class_goog_testing_TestCase_Result.html create mode 100644 docs/api/javascript/class_goog_testing_TestCase_Test.html create mode 100644 docs/api/javascript/class_goog_testing_TestCase_protectedDate_.html create mode 100644 docs/api/javascript/class_goog_testing_TestRunner.html create mode 100644 docs/api/javascript/class_goog_testing_events_Event.html create mode 100644 docs/api/javascript/class_goog_testing_mockmatchers_ArgumentMatcher.html create mode 100644 docs/api/javascript/class_goog_testing_mockmatchers_IgnoreArgument.html create mode 100644 docs/api/javascript/class_goog_testing_mockmatchers_InstanceOf.html create mode 100644 docs/api/javascript/class_goog_testing_mockmatchers_ObjectEquals.html create mode 100644 docs/api/javascript/class_goog_testing_mockmatchers_RegexpMatch.html create mode 100644 docs/api/javascript/class_goog_testing_mockmatchers_SaveArgument.html create mode 100644 docs/api/javascript/class_goog_testing_mockmatchers_TypeOf.html create mode 100644 docs/api/javascript/class_goog_testing_stacktrace_Frame.html create mode 100644 docs/api/javascript/class_webdriver_AlertPromise.html create mode 100644 docs/api/javascript/class_webdriver_WebElementPromise.html create mode 100644 docs/api/javascript/class_webdriver_logging_Preferences.html create mode 100644 docs/api/javascript/class_webdriver_testing_TestCase.html create mode 100644 docs/api/javascript/enum_goog_Disposable_MonitoringMode.html create mode 100644 docs/api/javascript/enum_goog_dom_BrowserFeature.html create mode 100644 docs/api/javascript/enum_goog_dom_TagName.html create mode 100644 docs/api/javascript/enum_goog_events_BrowserEvent_MouseButton.html create mode 100644 docs/api/javascript/enum_goog_events_BrowserFeature.html create mode 100644 docs/api/javascript/enum_goog_events_CaptureSimulationMode.html create mode 100644 docs/api/javascript/enum_goog_events_EventType.html create mode 100644 docs/api/javascript/enum_goog_events_KeyCodes.html create mode 100644 docs/api/javascript/enum_goog_testing_TestCase_Order.html delete mode 100644 docs/api/javascript/enum_webdriver_logging_LevelName.html create mode 100644 docs/api/javascript/interface_goog_debug_EntryPointMonitor.html create mode 100644 docs/api/javascript/interface_goog_disposable_IDisposable.html create mode 100644 docs/api/javascript/interface_goog_events_Listenable.html create mode 100644 docs/api/javascript/interface_goog_events_ListenableKey.html create mode 100644 docs/api/javascript/interface_goog_structs_Collection.html create mode 100644 docs/api/javascript/interface_goog_testing_MockInterface.html create mode 100644 docs/api/javascript/interface_webdriver_promise_Thenable.html create mode 100644 docs/api/javascript/module_selenium-webdriver__base_class_Context.html create mode 100644 docs/api/javascript/module_selenium-webdriver_chrome_class_Driver.html delete mode 100644 docs/api/javascript/module_selenium-webdriver_docs_dossier.html delete mode 100644 docs/api/javascript/module_selenium-webdriver_docs_types.html create mode 100644 docs/api/javascript/module_selenium-webdriver_firefox.html create mode 100644 docs/api/javascript/module_selenium-webdriver_firefox_binary.html create mode 100644 docs/api/javascript/module_selenium-webdriver_firefox_binary_class_Binary.html create mode 100644 docs/api/javascript/module_selenium-webdriver_firefox_class_Driver.html create mode 100644 docs/api/javascript/module_selenium-webdriver_firefox_class_Options.html create mode 100644 docs/api/javascript/module_selenium-webdriver_firefox_extension.html create mode 100644 docs/api/javascript/module_selenium-webdriver_firefox_profile.html create mode 100644 docs/api/javascript/module_selenium-webdriver_firefox_profile_class_Profile.html create mode 100644 docs/api/javascript/module_selenium-webdriver_io_exec.html create mode 100644 docs/api/javascript/module_selenium-webdriver_phantomjs_class_Driver.html create mode 100644 docs/api/javascript/namespace_PRIMITIVE_EQUALITY_PREDICATES.html create mode 100644 docs/api/javascript/namespace_goog_async.html create mode 100644 docs/api/javascript/namespace_goog_async_nextTick.html create mode 100644 docs/api/javascript/namespace_goog_async_run.html create mode 100644 docs/api/javascript/namespace_goog_debug_LogManager.html create mode 100644 docs/api/javascript/namespace_goog_debug_entryPointRegistry.html create mode 100644 docs/api/javascript/namespace_goog_defineClass.html create mode 100644 docs/api/javascript/namespace_goog_disposable.html create mode 100644 docs/api/javascript/namespace_goog_dom_vendor.html create mode 100644 docs/api/javascript/namespace_goog_events.html create mode 100644 docs/api/javascript/namespace_goog_reflect.html create mode 100644 docs/api/javascript/namespace_goog_style.html create mode 100644 docs/api/javascript/namespace_goog_testing.html create mode 100644 docs/api/javascript/namespace_goog_testing_MethodMock.html create mode 100644 docs/api/javascript/namespace_goog_testing_asserts.html create mode 100644 docs/api/javascript/namespace_goog_testing_events.html create mode 100644 docs/api/javascript/namespace_goog_testing_jsunit.html create mode 100644 docs/api/javascript/namespace_goog_testing_mockmatchers.html create mode 100644 docs/api/javascript/namespace_goog_testing_stacktrace.html create mode 100644 docs/api/javascript/namespace_goog_testing_watchers.html delete mode 100644 docs/api/javascript/source/docs/dossier.js.src.html delete mode 100644 docs/api/javascript/source/docs/types.js.src.html create mode 100644 docs/api/javascript/source/firefox/binary.js.src.html create mode 100644 docs/api/javascript/source/firefox/extension.js.src.html create mode 100644 docs/api/javascript/source/firefox/index.js.src.html create mode 100644 docs/api/javascript/source/firefox/profile.js.src.html create mode 100644 docs/api/javascript/source/io/exec.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/async/nexttick.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/async/run.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/debug/debug.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/debug/entrypointregistry.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/debug/logbuffer.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/debug/logger.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/debug/logrecord.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/disposable/disposable.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/disposable/idisposable.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/dom/browserfeature.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/dom/dom.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/dom/tagname.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/dom/vendor.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/events/browserevent.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/events/browserfeature.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/events/event.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/events/eventid.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/events/events.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/events/eventtarget.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/events/eventtype.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/events/keycodes.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/events/listenable.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/events/listener.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/events/listenermap.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/math/box.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/math/coordinate.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/math/rect.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/math/size.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/reflect/reflect.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/structs/collection.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/structs/set.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/style/style.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/asserts.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/asynctestcase.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/events/events.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/functionmock.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/jsunit.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/loosemock.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/mock.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/mockclock.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/mockcontrol.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/mockinterface.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/mockmatchers.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/objectpropertystring.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/propertyreplacer.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/recordfunction.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/stacktrace.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/strictmock.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/testcase.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/testrunner.js.src.html create mode 100644 docs/api/javascript/source/lib/goog/testing/watchers.js.src.html create mode 100644 docs/api/javascript/source/lib/webdriver/testing/testcase.js.src.html diff --git a/docs/api/javascript/class_bot_Error.html b/docs/api/javascript/class_bot_Error.html index 2171f78d1eadc..fa876eca1cd06 100644 --- a/docs/api/javascript/class_bot_Error.html +++ b/docs/api/javascript/class_bot_Error.html @@ -1,6 +1,6 @@ -bot.Error

Class bot.Error

code »
Error
+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. + 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 + 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/docs/api/javascript/class_goog_Disposable.html b/docs/api/javascript/class_goog_Disposable.html new file mode 100644 index 0000000000000..0ab639e550ff8 --- /dev/null +++ b/docs/api/javascript/class_goog_Disposable.html @@ -0,0 +1,37 @@ +goog.Disposable

Class goog.Disposable

code »
All implemented interfaces:
goog.disposable.IDisposable

Class that provides the basic implementation for disposable objects. If your + class holds one or more references to COM objects, DOM nodes, or other + disposable objects, it should extend this class or implement the disposable + interface (defined in goog.disposable.IDisposable).

Constructor

goog.Disposable ( )

Enumerations

Show:

Instance Methods

code »<T> addOnDisposeCallback ( callback, opt_scope )

Invokes a callback function when this object is disposed. Callbacks are + invoked in the order in which they were added.

Parameters
callback: function(this: T): ?
The callback function.
opt_scope: T=
An optional scope to call the callback in.
code »dispose ( )void

Disposes of the object. If the object hasn't already been disposed of, calls + #disposeInternal. Classes that extend goog.Disposable should + override #disposeInternal in order to delete references to COM + objects, DOM nodes, and other disposable objects. Reentrant.

Returns
Nothing.

Deletes or nulls out any references to COM objects, DOM nodes, or other + disposable objects. Classes that extend goog.Disposable should + override this method. + Not reentrant. To avoid calling it twice, it must only be called from the + subclass' disposeInternal method. Everywhere else the public + dispose method must be used. + For example: +

+   mypackage.MyClass = function() {
+     mypackage.MyClass.base(this, 'constructor');
+     // Constructor logic specific to MyClass.
+     ...
+   };
+   goog.inherits(mypackage.MyClass, goog.Disposable);
+
+   mypackage.MyClass.prototype.disposeInternal = function() {
+     // Dispose logic specific to MyClass.
+     ...
+     // Call superclass's disposeInternal at the end of the subclass's, like
+     // in C++, to avoid hard-to-catch issues.
+     mypackage.MyClass.base(this, 'disposeInternal');
+   };
+ 
Deprecated: Use #isDisposed instead.
Returns
Whether the object has been disposed of.
Returns
Whether the object has been disposed of.

Associates a disposable object with this object so that they will be disposed + together.

Parameters
disposable: goog.disposable.IDisposable
that will be disposed when + this object is disposed.

Instance Properties

If monitoring the goog.Disposable instances is enabled, stores the creation + stack trace of the Disposable instance.

Whether the object has been disposed of.

Callbacks to invoke when this object is disposed.

Static Functions

Clears the registry of undisposed objects but doesn't dispose of them.

Returns
All goog.Disposable objects that + haven't been disposed of.

Returns True if we can verify the object is disposed. + Calls isDisposed on the argument if it supports it. If obj + is not an object with an isDisposed() method, return false.

Parameters
obj: *
The object to investigate.
Returns
True if we can verify the object is disposed.

Static Properties

Maps the unique ID of every undisposed goog.Disposable object to + the object itself.

Compiler Constants

\ No newline at end of file diff --git a/docs/api/javascript/class_goog_Uri.html b/docs/api/javascript/class_goog_Uri.html index 37ab0402a060a..1474bcbff21d3 100644 --- a/docs/api/javascript/class_goog_Uri.html +++ b/docs/api/javascript/class_goog_Uri.html @@ -1,8 +1,14 @@ -goog.Uri

Class goog.Uri

code »

This class contains setters and getters for the parts of the URI. +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. + Reserved characters (see RFC 3986 section 2.2) can be present in + their percent-encoded form in scheme, domain, and path URI components and + will not be auto-decoded. For example: + goog.Uri.parse('rel%61tive/path%2fto/resource').getPath() will + return relative/path%2fto/resource. + 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. @@ -11,16 +17,16 @@ 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 + 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 + 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 ?. + 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 + 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:
@@ -31,27 +37,29 @@ 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. + 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 + 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, + 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 + 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.
code »goog.Uri.decodeOrEmpty_ ( val, opt_preserveReserved )string

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

Parameters
val: (string|undefined)
Value to decode.
opt_preserveReserved: boolean=
If true, restricted characters will + not be decoded.
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, opt_removeDoubleEncoding )?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(). + appear in extra.

Parameters
unescapedPart: *
The string to encode.
extra: RegExp
A character set of characters in [\01-\177].
opt_removeDoubleEncoding: boolean=
If true, remove double percent + encoding.
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. + 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.
code »goog.Uri.removeDoubleEncoding_ ( doubleEncodedString )string

Removes double percent-encoding from a string.

Parameters
doubleEncodedString: string
String
Returns
String with double encoding removed.

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. @@ -59,5 +67,6 @@ 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 + 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. + Colon is included due to RFC 3986 3.3.

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/docs/api/javascript/class_goog_Uri_QueryData.html b/docs/api/javascript/class_goog_Uri_QueryData.html index 4e5c64f93bf3c..f24f8dd4b0b09 100644 --- a/docs/api/javascript/class_goog_Uri_QueryData.html +++ b/docs/api/javascript/class_goog_Uri_QueryData.html @@ -1,34 +1,34 @@ -goog.Uri.QueryData

Class goog.Uri.QueryData

code »

Class used to represent URI query parameters. It is essentially a hash of +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 + 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 + 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 + 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. + 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. + 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 + 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 + 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 + name in #get.Returns
The populated query data instance.
\ No newline at end of file diff --git a/docs/api/javascript/class_goog_asserts_AssertionError.html b/docs/api/javascript/class_goog_asserts_AssertionError.html index a435077782f26..9b81597a86e74 100644 --- a/docs/api/javascript/class_goog_asserts_AssertionError.html +++ b/docs/api/javascript/class_goog_asserts_AssertionError.html @@ -1,4 +1,4 @@ goog.asserts.AssertionError

Class goog.asserts.AssertionError

code »
Errorgoog.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 + use this to uniquely identify the assertion.

Static Properties

\ No newline at end of file diff --git a/docs/api/javascript/class_goog_async_run_WorkItem_.html b/docs/api/javascript/class_goog_async_run_WorkItem_.html new file mode 100644 index 0000000000000..4cb9c4dc280bb --- /dev/null +++ b/docs/api/javascript/class_goog_async_run_WorkItem_.html @@ -0,0 +1 @@ +goog.async.run.WorkItem_

Class goog.async.run.WorkItem_

code »

Constructor

goog.async.run.WorkItem_ ( fn, scope )
Parameters
fn
scope
Show:

Instance Methods

Instance Properties

code »scope : (Object|null|undefined)
\ No newline at end of file diff --git a/docs/api/javascript/class_goog_debug_Error.html b/docs/api/javascript/class_goog_debug_Error.html index 15eb56f7014be..0cf370c077303 100644 --- a/docs/api/javascript/class_goog_debug_Error.html +++ b/docs/api/javascript/class_goog_debug_Error.html @@ -1,2 +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 + └ 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/docs/api/javascript/class_goog_debug_LogBuffer.html b/docs/api/javascript/class_goog_debug_LogBuffer.html new file mode 100644 index 0000000000000..51f289c253ae1 --- /dev/null +++ b/docs/api/javascript/class_goog_debug_LogBuffer.html @@ -0,0 +1,2 @@ +goog.debug.LogBuffer

Class goog.debug.LogBuffer

code »

Creates the log buffer.

Constructor

goog.debug.LogBuffer ( )

Classes

goog.debug.LogBuffer.instance_
Creates the log buffer.
Show:

Instance Methods

code »addRecord ( level, msg, loggerName )!goog.debug.LogRecord

Adds a log record to the buffer, possibly overwriting the oldest record.

Parameters
level: goog.debug.Logger.Level
One of the level identifiers.
msg: string
The string message.
loggerName: string
The name of the source logger.
Returns
The log record.

Removes all buffered log records.

Calls the given function for each buffered log record, starting with the + oldest one.

Parameters
func: function(!goog.debug.LogRecord)
The function to call.

Instance Properties

The array to store the records.

The index of the most recently added record or -1 if there are no records.

Whether the buffer is at capacity.

Static Functions

A static method that always returns the same instance of LogBuffer.

Returns
The LogBuffer singleton instance.
Returns
Whether the log buffer is enabled.

Static Properties

Compiler Constants

\ No newline at end of file diff --git a/docs/api/javascript/class_goog_debug_LogRecord.html b/docs/api/javascript/class_goog_debug_LogRecord.html new file mode 100644 index 0000000000000..32c248eab93f0 --- /dev/null +++ b/docs/api/javascript/class_goog_debug_LogRecord.html @@ -0,0 +1,12 @@ +goog.debug.LogRecord

Class goog.debug.LogRecord

code »

LogRecord objects are used to pass logging requests between + the logging framework and individual log Handlers.

Constructor

goog.debug.LogRecord ( level, msg, loggerName, opt_time, opt_sequenceNumber )
Parameters
level: goog.debug.Logger.Level
One of the level identifiers.
msg: string
The string message.
loggerName: string
The name of the source logger.
opt_time: number=
Time this log record was created if other than now. + If 0, we use #goog.now.
opt_sequenceNumber: number=
Sequence number of this log record. This + should only be passed in when restoring a log record from persistence.
Show:

Instance Methods

Get the exception that is part of the log record.

Returns
the exception.

Get the exception text that is part of the log record.

Returns
Exception text.

Get the logging message level, for example Level.SEVERE.

Returns
the logging message level.

Get the source Logger's name.

Returns
source logger name (may be null).

Get the "raw" log message, before localization or formatting.

Returns
the raw message string.

Get event time in milliseconds since 1970.

Returns
event time in millis since 1970.

Get the sequence number. +

+ Sequence numbers are normally assigned in the LogRecord + constructor, which assigns unique sequence numbers to + each new LogRecord in increasing order.

Returns
the sequence number.
code »reset ( level, msg, loggerName, opt_time, opt_sequenceNumber )

Sets all fields of the log record.

Parameters
level: goog.debug.Logger.Level
One of the level identifiers.
msg: string
The string message.
loggerName: string
The name of the source logger.
opt_time: number=
Time this log record was created if other than now. + If 0, we use #goog.now.
opt_sequenceNumber: number=
Sequence number of this log record. This + should only be passed in when restoring a log record from persistence.
code »setException ( exception )

Set the exception that is part of the log record.

Parameters
exception: Object
the exception.

Set the exception text that is part of the log record.

Parameters
text: string
The exception text.
code »setLevel ( level )

Set the logging message level, for example Level.SEVERE.

Parameters
level: goog.debug.Logger.Level
the logging message level.
code »setLoggerName ( loggerName )

Get the source Logger's name.

Parameters
loggerName: string
source logger name (may be null).

Set the "raw" log message, before localization or formatting.

Parameters
msg: string
the raw message string.

Set event time in milliseconds since 1970.

Parameters
time: number
event time in millis since 1970.

Instance Properties

Exception text associated with the record

Exception associated with the record

Level of the LogRecord

Name of the logger that created the record.

Message associated with the record

Sequence number for the LogRecord. Each record has a unique sequence number + that is greater than all log records created before it.

Time the LogRecord was created.

Static Properties

A sequence counter for assigning increasing sequence numbers to LogRecord + objects.

Compiler Constants

\ No newline at end of file diff --git a/docs/api/javascript/class_goog_debug_Logger.html b/docs/api/javascript/class_goog_debug_Logger.html new file mode 100644 index 0000000000000..6d70260a296e1 --- /dev/null +++ b/docs/api/javascript/class_goog_debug_Logger.html @@ -0,0 +1,59 @@ +goog.debug.Logger

Class goog.debug.Logger

code »

The Logger is an object used for logging debug messages. Loggers are + normally named, using a hierarchical dot-separated namespace. Logger names + can be arbitrary strings, but they should normally be based on the package + name or class name of the logged component, such as goog.net.BrowserChannel. + + The Logger object is loosely based on the java class + java.util.logging.Logger. It supports different levels of filtering for + different loggers. + + The logger object should never be instantiated by application code. It + should always use the goog.debug.Logger.getLogger function.

Constructor

goog.debug.Logger ( name )
Parameters
name: string
The name of the Logger.

Classes

goog.debug.Logger.Level
The Level class defines a set of standard logging levels that + can be used to control logging output.
Show:

Instance Methods

code »addChild_ ( name, logger )

Adds a child to this logger. This is used for setting up the logger tree.

Parameters
name: string
The leaf name of the child.
logger: goog.debug.Logger
The child logger.
code »addHandler ( handler )

Adds a handler to the logger. This doesn't use the event system because + we want to be able to add logging to the event system.

Parameters
handler: Function
Handler function to add.
code »callPublish_ ( logRecord )

Calls the handlers for publish.

Parameters
logRecord: goog.debug.LogRecord
The log record to publish.
code »config ( msg, opt_exception )

Logs a message at the Logger.Level.CONFIG level. + If the logger is currently enabled for the given message level then the + given message is forwarded to all the registered output Handler objects.

Parameters
msg: goog.debug.Loggable
The message to log.
opt_exception: Error=
An exception associated with the message.
code »doLogRecord_ ( logRecord )

Logs a LogRecord.

Parameters
logRecord: goog.debug.LogRecord
A log record to log.
code »fine ( msg, opt_exception )

Logs a message at the Logger.Level.FINE level. + If the logger is currently enabled for the given message level then the + given message is forwarded to all the registered output Handler objects.

Parameters
msg: goog.debug.Loggable
The message to log.
opt_exception: Error=
An exception associated with the message.
code »finer ( msg, opt_exception )

Logs a message at the Logger.Level.FINER level. + If the logger is currently enabled for the given message level then the + given message is forwarded to all the registered output Handler objects.

Parameters
msg: goog.debug.Loggable
The message to log.
opt_exception: Error=
An exception associated with the message.
code »finest ( msg, opt_exception )

Logs a message at the Logger.Level.FINEST level. + If the logger is currently enabled for the given message level then the + given message is forwarded to all the registered output Handler objects.

Parameters
msg: goog.debug.Loggable
The message to log.
opt_exception: Error=
An exception associated with the message.

Returns the children of this logger as a map of the child name to the logger.

Returns
The map where the keys are the child leaf names and the + values are the Logger objects.

Returns the effective level of the logger based on its ancestors' levels.

Returns
The level.

Gets the log level specifying which message levels will be logged by this + logger. Message levels lower than this value will be discarded. + The level value Level.OFF can be used to turn off logging. If the level + is null, it means that this node should inherit its level from its nearest + ancestor with a specific (non-null) level value.

Returns
The level.
code »getLogRecord ( level, msg, opt_exception, opt_fnStackContext )!goog.debug.LogRecord

Creates a new log record and adds the exception (if present) to it.

Parameters
level: goog.debug.Logger.Level
One of the level identifiers.
msg: string
The string message.
opt_exception: (Error|Object)=
An exception associated with the + message.
opt_fnStackContext: Function=
A function to use as the base + of the stack trace used in the log record.
Returns
A log record.

Gets the name of this logger.

Returns
The name of this logger.

Returns the parent of this logger.

Returns
The parent logger or null if this is the root.
code »info ( msg, opt_exception )

Logs a message at the Logger.Level.INFO level. + If the logger is currently enabled for the given message level then the + given message is forwarded to all the registered output Handler objects.

Parameters
msg: goog.debug.Loggable
The message to log.
opt_exception: Error=
An exception associated with the message.

Checks if a message of the given level would actually be logged by this + logger. This check is based on the Loggers effective level, which may be + inherited from its parent.

Parameters
level: goog.debug.Logger.Level
The level to check.
Returns
Whether the message would be logged.
code »log ( level, msg, opt_exception )

Logs a message. If the logger is currently enabled for the + given message level then the given message is forwarded to all the + registered output Handler objects.

Parameters
level: goog.debug.Logger.Level
One of the level identifiers.
msg: goog.debug.Loggable
The message to log.
opt_exception: (Error|Object)=
An exception associated with the + message.
code »logRecord ( logRecord )

Logs a LogRecord. If the logger is currently enabled for the + given message level then the given message is forwarded to all the + registered output Handler objects.

Parameters
logRecord: goog.debug.LogRecord
A log record to log.

Removes a handler from the logger. This doesn't use the event system because + we want to be able to add logging to the event system.

Parameters
handler: Function
Handler function to remove.
Returns
Whether the handler was removed.
code »setLevel ( level )

Set the log level specifying which message levels will be logged by this + logger. Message levels lower than this value will be discarded. + The level value Level.OFF can be used to turn off logging. If the new level + is null, it means that this node should inherit its level from its nearest + ancestor with a specific (non-null) level value.

Parameters
level: goog.debug.Logger.Level
The new level.

Sets the parent of this logger. This is used for setting up the logger tree.

Parameters
parent: goog.debug.Logger
The parent logger.
code »severe ( msg, opt_exception )

Logs a message at the Logger.Level.SEVERE level. + If the logger is currently enabled for the given message level then the + given message is forwarded to all the registered output Handler objects.

Parameters
msg: goog.debug.Loggable
The message to log.
opt_exception: Error=
An exception associated with the message.
code »shout ( msg, opt_exception )

Logs a message at the Logger.Level.SHOUT level. + If the logger is currently enabled for the given message level then the + given message is forwarded to all the registered output Handler objects.

Parameters
msg: goog.debug.Loggable
The message to log.
opt_exception: Error=
An exception associated with the message.
code »warning ( msg, opt_exception )

Logs a message at the Logger.Level.WARNING level. + If the logger is currently enabled for the given message level then the + given message is forwarded to all the registered output Handler objects.

Parameters
msg: goog.debug.Loggable
The message to log.
opt_exception: Error=
An exception associated with the message.

Instance Properties

Map of children loggers. The keys are the leaf names of the children and + the values are the child loggers.

Handlers that are listening to this logger.

Level that this logger only filters above. Null indicates it should + inherit from the parent.

Name of the Logger. Generally a dot-separated namespace

Static Functions

Deprecated: use goog.log instead. http://go/goog-debug-logger-deprecated

Finds or creates a logger for a named subsystem. If a logger has already been + created with the given name it is returned. Otherwise a new logger is + created. If a new logger is created its log level will be configured based + on the LogManager configuration and it will configured to also send logging + output to its parent's handlers. It will be registered in the LogManager + global namespace.

Parameters
name: string
A name for the logger. This should be a dot-separated + name and should normally be based on the package name or class name of the + subsystem, such as goog.net.BrowserChannel.
Returns
The named logger.

Logs a message to profiling tools, if available. + https://developers.google.com/web-toolkit/speedtracer/logging-api + http://msdn.microsoft.com/en-us/library/dd433074(VS.85).aspx

Parameters
msg: string
The message to log.

Static Properties

Compiler Constants

\ No newline at end of file diff --git a/docs/api/javascript/class_goog_debug_Logger_Level.html b/docs/api/javascript/class_goog_debug_Logger_Level.html new file mode 100644 index 0000000000000..3454ffdc60aa8 --- /dev/null +++ b/docs/api/javascript/class_goog_debug_Logger_Level.html @@ -0,0 +1,32 @@ +goog.debug.Logger.Level

Class goog.debug.Logger.Level

code »

The Level class defines a set of standard logging levels that + can be used to control logging output. The logging Level objects + are ordered and are specified by ordered integers. Enabling logging + at a given level also enables logging at all higher levels. +

+ Clients should normally use the predefined Level constants such + as Level.SEVERE. +

+ The levels in descending order are: +

    +
  • SEVERE (highest value) +
  • WARNING +
  • INFO +
  • CONFIG +
  • FINE +
  • FINER +
  • FINEST (lowest value) +
+ In addition there is a level OFF that can be used to turn + off logging, and a level ALL that can be used to enable + logging of all messages.

Constructor

goog.debug.Logger.Level ( name, value )
Parameters
name: string
The name of the level.
value: number
The numeric value of the level.
Show:

Instance Methods

Returns
String representation of the logger level.

Instance Properties

The name of the level

The numeric value of the level

Static Functions

Creates the predefined levels cache and populates it.

Gets the predefined level with the given name.

Parameters
name: string
The name of the level.
Returns
The level, or null if none found.

Gets the highest predefined level <= #value.

Parameters
value: number
Level value.
Returns
The level, or null if none found.

Static Properties

ALL indicates that all messages should be logged. + This level is initialized to 0.

CONFIG is a message level for static configuration messages. + This level is initialized to 700.

FINE is a message level providing tracing information. + This level is initialized to 500.

FINER indicates a fairly detailed tracing message. + This level is initialized to 400.

FINEST indicates a highly detailed tracing message. + This level is initialized to 300.

INFO is a message level for informational messages. + This level is initialized to 800.

OFF is a special level that can be used to turn off logging. + This level is initialized to Infinity.

SEVERE is a message level indicating a serious failure. + This level is initialized to 1000.

SHOUT is a message level for extra debugging loudness. + This level is initialized to 1200.

WARNING is a message level indicating a potential problem. + This level is initialized to 900.

A lookup map used to find the level object based on the name or value of + the level object.

\ No newline at end of file diff --git a/docs/api/javascript/class_goog_dom_DomHelper.html b/docs/api/javascript/class_goog_dom_DomHelper.html new file mode 100644 index 0000000000000..caa6f2e78c94d --- /dev/null +++ b/docs/api/javascript/class_goog_dom_DomHelper.html @@ -0,0 +1,104 @@ +goog.dom.DomHelper

Class goog.dom.DomHelper

code »

Create an instance of a DOM helper with a new document object.

Constructor

goog.dom.DomHelper ( opt_document )
Parameters
opt_document: Document=
Document object to associate with this + DOM helper.
Show:

Instance Methods

code »$ ( element )Element

Alias for getElement.

Parameters
element: (string|Element)
Element ID or a DOM node.
Returns
The element with the given ID, or the node passed in.
code »$$ ( opt_tag, opt_class, opt_el ){length: number}
Deprecated: Use DomHelper getElementsByTagNameAndClass.

Alias for getElementsByTagNameAndClass.

Parameters
opt_tag: ?string=
Element tag name.
opt_class: ?string=
Optional class name.
opt_el: Element=
Optional element to look in.
Returns
Array-like list of elements (only a length + property and numerical indices are guaranteed to exist).
code »$dom ( tagName, opt_attributes, var_args )!Element

Alias for createDom.

Parameters
tagName: string
Tag to create.
opt_attributes: (Object|string)=
If object, then a map of name-value + pairs for attributes. If a string, then this is the className of the new + element.
var_args: ...goog.dom.Appendable
Further DOM nodes or strings for + text nodes. If one of the var_args is an array, its children will be + added as childNodes instead.
Returns
Reference to a DOM node.
code »append ( parent, var_args )

Appends a node with text or other nodes.

Parameters
parent: !Node
The node to append nodes to.
var_args: ...goog.dom.Appendable
The things to append to the node. + If this is a Node it is appended as is. + If this is a string then a text node is appended. + If this is an array like object then fields 0 to length - 1 are appended.
code »appendChild ( parent, child )

Appends a child to a node.

Parameters
parent: Node
Parent.
child: Node
Child.

Determines if the given node can contain children, intended to be used for + HTML generation.

Parameters
node: Node
The node to check.
Returns
Whether the node can contain children.
code »compareNodeOrder ( node1, node2 )number

Compares the document order of two nodes, returning 0 if they are the same + node, a negative number if node1 is before node2, and a positive number if + node2 is before node1. Note that we compare the order the tags appear in the + document so in the tree text the B node is considered to be + before the I node.

Parameters
node1: Node
The first node to compare.
node2: Node
The second node to compare.
Returns
0 if the nodes are the same node, a negative number if node1 + is before node2, and a positive number if node2 is before node1.
code »contains ( parent, descendant )boolean

Whether a node contains another node.

Parameters
parent: Node
The node that should contain the other node.
descendant: Node
The node to test presence of.
Returns
Whether the parent node contains the descendent node.
code »createDom ( tagName, opt_attributes, var_args )!Element

Returns a dom node with a set of attributes. This function accepts varargs + for subsequent nodes to be added. Subsequent nodes will be added to the + first node as childNodes. + + So: + createDom('div', null, createDom('p'), createDom('p')); + would return a div with two child paragraphs + + An easy way to move all child nodes of an existing element to a new parent + element is: + createDom('div', null, oldElement.childNodes); + which will remove all child nodes from the old element and add them as + child nodes of the new DIV.

Parameters
tagName: string
Tag to create.
opt_attributes: (Object|string)=
If object, then a map of name-value + pairs for attributes. If a string, then this is the className of the new + element.
var_args: ...goog.dom.Appendable
Further DOM nodes or + strings for text nodes. If one of the var_args is an array or + NodeList, its elements will be added as childNodes instead.
Returns
Reference to a DOM node.

Creates a new element.

Parameters
name: string
Tag name.
Returns
The new element.
code »createTable ( rows, columns, opt_fillWithNbsp )!Element

Create a table.

Parameters
rows: number
The number of rows in the table. Must be >= 1.
columns: number
The number of columns in the table. Must be >= 1.
opt_fillWithNbsp: boolean=
If true, fills table entries with nsbps.
Returns
The created table.
code »createTextNode ( content )!Text

Creates a new text node.

Parameters
content: (number|string)
Content.
Returns
The new text node.

Find the deepest common ancestor of the given nodes.

Parameters
var_args: ...Node
The nodes to find a common ancestor of.
Returns
The common ancestor of the nodes, or null if there is none. + null will only be returned if two or more of the nodes are from different + documents.
code »findNode ( root, p )(Node|undefined)

Finds the first descendant node that matches the filter function. This does + a depth first search.

Parameters
root: Node
The root of the tree to search.
p: function(Node): boolean
The filter function.
Returns
The found node or undefined if none is found.
code »findNodes ( root, p )Array.<Node>

Finds all the descendant nodes that matches the filter function. This does a + depth first search.

Parameters
root: Node
The root of the tree to search.
p: function(Node): boolean
The filter function.
Returns
The found nodes or an empty array if none are found.

Flattens an element. That is, removes it and replace it with its children.

Parameters
element: Element
The element to flatten.
Returns
The original element, detached from the document + tree, sans children, or undefined if the element was already not in the + document.

Determines the active element in the given document.

Parameters
opt_doc: Document=
The document to look in.
Returns
The active element.
code »getAncestor ( element, matcher, opt_includeNode, opt_maxSearchSteps )Node

Walks up the DOM hierarchy returning the first ancestor that passes the + matcher function.

Parameters
element: Node
The DOM node to start with.
matcher: function(Node): boolean
A function that returns true if the + passed node matches the desired criteria.
opt_includeNode: boolean=
If true, the node itself is included in + the search (the first call to the matcher will pass startElement as + the node to test).
opt_maxSearchSteps: number=
Maximum number of levels to search up the + dom.
Returns
DOM node that matched the matcher, or null if there was + no match.
code »getAncestorByClass ( element, class )Element

Walks up the DOM hierarchy returning the first ancestor that has the passed + class name. If the passed element matches the specified criteria, the + element itself is returned.

Parameters
element: Node
The DOM node to start with.
class: string
The class name to match.
Returns
The first ancestor that matches the passed criteria, or + null if none match.
code »getAncestorByTagNameAndClass ( element, opt_tag, opt_class )Element

Walks up the DOM hierarchy returning the first ancestor that has the passed + tag name and/or class name. If the passed element matches the specified + criteria, the element itself is returned.

Parameters
element: Node
The DOM node to start with.
opt_tag: ?(goog.dom.TagName|string)=
The tag name to match (or + null/undefined to match only based on class name).
opt_class: ?string=
The class name to match (or null/undefined to + match only based on tag name).
Returns
The first ancestor that matches the passed criteria, or + null if no match is found.
code »getChildren ( element )!(Array|NodeList)

Returns an array containing just the element children of the given element.

Parameters
element: Element
The element whose element children we want.
Returns
An array or array-like list of just the element + children of the given element.

Gets the document object being used by the dom library.

Returns
Document object.

Calculates the height of the document.

Returns
The height of the document.

Gets the document scroll distance as a coordinate object.

Returns
Object with properties 'x' and 'y'.

Gets the document scroll element.

Returns
Scrolling element.

Gets the dom helper object for the document where the element resides.

Parameters
opt_node: Node=
If present, gets the DomHelper for this node.
Returns
The DomHelper.
code »getElement ( element )Element

Alias for getElementById. If a DOM node is passed in then we just + return that.

Parameters
element: (string|Element)
Element ID or a DOM node.
Returns
The element with the given ID, or the node passed in.
code »getElementByClass ( className, opt_el )Element

Returns the first element we find matching the provided class name.

Parameters
className: string
the name of the class to look for.
opt_el: (Element|Document)=
Optional element to look in.
Returns
The first item found with the class name provided.
code »getElementsByClass ( className, opt_el ){length: number}

Returns an array of all the elements with the provided className.

Parameters
className: string
the name of the class to look for.
opt_el: (Element|Document)=
Optional element to look in.
Returns
The items found with the class name provided.
code »getElementsByTagNameAndClass ( opt_tag, opt_class, opt_el ){length: number}

Looks up elements by both tag and class name, using browser native functions + (querySelectorAll, getElementsByTagName or + getElementsByClassName) where possible. The returned array is a live + NodeList or a static list depending on the code path taken.

Parameters
opt_tag: ?string=
Element tag name or * for all tags.
opt_class: ?string=
Optional class name.
opt_el: (Document|Element)=
Optional element to look in.
Returns
Array-like list of elements (only a length + property and numerical indices are guaranteed to exist).

Returns the first child node that is an element.

Parameters
node: Node
The node to get the first child element of.
Returns
The first child node of node that is an element.

Cross browser function for getting the document element of an iframe.

Parameters
iframe: Element
Iframe element.
Returns
The frame content document.
code »getFrameContentWindow ( frame )Window

Cross browser function for getting the window of a frame or iframe.

Parameters
frame: Element
Frame element.
Returns
The window associated with the given frame.

Returns the last child node that is an element.

Parameters
node: Node
The node to get the last child element of.
Returns
The last child node of node that is an element.

Returns the first next sibling that is an element.

Parameters
node: Node
The node to get the next sibling element of.
Returns
The next sibling of node that is an element.

Returns the next node in source order from the given node.

Parameters
node: Node
The node.
Returns
The next node in the DOM tree, or null if this was the last + node.
code »getNodeAtOffset ( parent, offset, opt_result )Node

Returns the node at a given offset in a parent node. If an object is + provided for the optional third parameter, the node and the remainder of the + offset will stored as properties of this object.

Parameters
parent: Node
The parent node.
offset: number
The offset into the parent node.
opt_result: Object=
Object to be used to store the return value. The + return value will be stored in the form {node: Node, remainder: number} + if this object is provided.
Returns
The node at the given offset.

Returns the text length of the text contained in a node, without markup. This + is equivalent to the selection length if the node was selected, or the number + of cursor movements to traverse the node. Images & BRs take one space. New + lines are ignored.

Parameters
node: Node
The node whose text content length is being calculated.
Returns
The length of node's text content.
code »getNodeTextOffset ( node, opt_offsetParent )number

Returns the text offset of a node relative to one of its ancestors. The text + length is the same as the length calculated by + goog.dom.getNodeTextLength.

Parameters
node: Node
The node whose offset is being calculated.
opt_offsetParent: Node=
Defaults to the node's owner document's body.
Returns
The text offset.
code »getOuterHtml ( element )string

Gets the outerHTML of a node, which islike innerHTML, except that it + actually contains the HTML of the node itself.

Parameters
element: Element
The element to get the HTML of.
Returns
The outerHTML of the given element.

Returns the owner document for a node.

Parameters
node: Node
The node to get the document for.
Returns
The document owning the node.

Returns an element's parent, if it's an Element.

Parameters
element: Element
The DOM element.
Returns
The parent, or null if not an Element.

Returns the first previous sibling that is an element.

Parameters
node: Node
The node to get the previous sibling element of.
Returns
The first previous sibling of node that is + an element.

Returns the previous node in source order from the given node.

Parameters
node: Node
The node.
Returns
The previous node in the DOM tree, or null if this was the + first node.

Gets an element by id, asserting that the element is found. + + This is used when an element is expected to exist, and should fail with + an assertion error if it does not (if assertions are enabled).

Parameters
id: string
Element ID.
Returns
The element with the given ID, if it exists.
code »getRequiredElementByClass ( className, opt_root )!Element

Ensures an element with the given className exists, and then returns the + first element with the provided className.

Parameters
className: string
the name of the class to look for.
opt_root: (!Element|!Document)=
Optional element or document to look + in.
Returns
The first item found with the class name provided.
Throws
goog.asserts.AssertionError
Thrown if no element is found.

Returns the text contents of the current node, without markup. New lines are + stripped and whitespace is collapsed, such that each character would be + visible. + + In browsers that support it, innerText is used. Other browsers attempt to + simulate it via node traversal. Line breaks are canonicalized in IE.

Parameters
node: Node
The node from which we are getting content.
Returns
The text content.

Gets the dimensions of the viewport.

Parameters
opt_window: Window=
Optional window element to test. Defaults to + the window of the Dom Helper.
Returns
Object with values 'width' and 'height'.
code »getWindow ( )!Window

Gets the window object associated with the document.

Returns
The window associated with the given document.

Converts an HTML string into a node or a document fragment. A single Node + is used if the htmlString only generates a single node. If the + htmlString generates multiple nodes then these are put inside a + DocumentFragment.

Parameters
htmlString: string
The HTML string to convert.
Returns
The resulting node.
code »insertChildAt ( parent, child, index )

Insert a child at a given index. If index is larger than the number of child + nodes that the parent currently has, the node is inserted as the last child + node.

Parameters
parent: Element
The element into which to insert the child.
child: Node
The element to insert.
index: number
The index at which to insert the new child node. Must + not be negative.
code »insertSiblingAfter ( newNode, refNode )

Inserts a new node after an existing reference node (i.e., as the next + sibling). If the reference node has no parent, then does nothing.

Parameters
newNode: Node
Node to insert.
refNode: Node
Reference node to insert after.
code »insertSiblingBefore ( newNode, refNode )

Inserts a new node before an existing reference node (i.e., as the previous + sibling). If the reference node has no parent, then does nothing.

Parameters
newNode: Node
Node to insert.
refNode: Node
Reference node to insert before.

Returns true if the browser is in "CSS1-compatible" (standards-compliant) + mode, false otherwise.

Returns
True if in CSS1-compatible mode.

Whether the object looks like an Element.

Parameters
obj: ?
The object being tested for Element likeness.
Returns
Whether the object looks like an Element.
code »isFocusable ( element )boolean

Returns true if the element can be focused, i.e. it has a tab index that + allows it to receive keyboard focus (tabIndex >= 0), or it is an element + that natively supports keyboard focus.

Parameters
element: Element
Element to check.
Returns
Whether the element allows keyboard focus.

Returns true if the element has a tab index that allows it to receive + keyboard focus (tabIndex >= 0), false otherwise. Note that some elements + natively support keyboard focus, even if they have no tab index.

Parameters
element: Element
Element to check.
Returns
Whether the element has a tab index that allows keyboard + focus.

Whether the object looks like a DOM node.

Parameters
obj: ?
The object being tested for node likeness.
Returns
Whether the object looks like a DOM node.

Returns true if the object is a NodeList. To qualify as a NodeList, + the object must have a numeric length property and an item function (which + has type 'string' on IE for some reason).

Parameters
val: Object
Object to test.
Returns
Whether the object is a NodeList.

Returns true if the specified value is a Window object. This includes the + global window for HTML pages, and iframe windows.

Parameters
obj: ?
Variable to test.
Returns
Whether the variable is a window.

Removes all the child nodes on a DOM node.

Parameters
node: Node
Node to remove children from.
code »removeNode ( node )Node

Removes a node from its parent.

Parameters
node: Node
The node to remove.
Returns
The node removed if removed; else, null.
code »replaceNode ( newNode, oldNode )

Replaces a node in the DOM tree. Will do nothing if oldNode has no + parent.

Parameters
newNode: Node
Node to insert.
oldNode: Node
Node to replace.
code »setDocument ( document )

Sets the document object.

Parameters
document: !Document
Document object.
code »setFocusableTabIndex ( element, enable )

Enables or disables keyboard focus support on the element via its tab index. + Only elements for which goog.dom.isFocusableTabIndex returns true + (or elements that natively support keyboard focus, like form elements) can + receive keyboard focus. See http://go/tabindex for more info.

Parameters
element: Element
Element whose tab index is to be changed.
enable: boolean
Whether to set or remove a tab index on the element + that supports keyboard focus.
code »setProperties ( element, properties )

Sets a number of properties on a node.

Parameters
element: Element
DOM node to set properties on.
properties: Object
Hash of property:value pairs.
code »setTextContent ( node, text )

Sets the text content of a node, with cross-browser support.

Parameters
node: Node
The node to change the text content of.
text: (string|number)
The value that should replace the node's content.

Instance Properties

Reference to the document object to use

\ No newline at end of file diff --git a/docs/api/javascript/class_goog_events_BrowserEvent.html b/docs/api/javascript/class_goog_events_BrowserEvent.html new file mode 100644 index 0000000000000..ed9fdc9ef5482 --- /dev/null +++ b/docs/api/javascript/class_goog_events_BrowserEvent.html @@ -0,0 +1,25 @@ +goog.events.BrowserEvent

Class goog.events.BrowserEvent

code »
goog.events.Event
+  └ goog.events.BrowserEvent

Accepts a browser event object and creates a patched, cross browser event + object. + The content of this object will not be initialized if no event object is + provided. If this is the case, init() needs to be invoked separately.

Constructor

goog.events.BrowserEvent ( opt_e, opt_currentTarget )
Parameters
opt_e: Event=
Browser event object.
opt_currentTarget: EventTarget=
Current target for event.

Enumerations

goog.events.BrowserEvent.MouseButton
Normalized button constants for the mouse.
Show:

Instance Methods

Defined in goog.events.BrowserEvent

Returns
The underlying browser event object.
code »init ( e, opt_currentTarget )

Accepts a browser event object and creates a patched, cross browser event + object.

Parameters
e: Event
Browser event object.
opt_currentTarget: EventTarget=
Current target for event.
code »isButton ( button )boolean

Tests to see which button was pressed during the event. This is really only + useful in IE and Gecko browsers. And in IE, it's only useful for + mousedown/mouseup events, because click only fires for the left mouse button. + + Safari 2 only reports the left button being clicked, and uses the value '1' + instead of 0. Opera only reports a mousedown event for the middle button, and + no mouse events for the right button. Opera has default behavior for left and + middle click that can only be overridden via a configuration setting. + + There's a nice table of this mess at http://www.unixpapa.com/js/mouse.html.

Parameters
button: goog.events.BrowserEvent.MouseButton
The button + to test for.
Returns
True if button was pressed.

Whether this has an "action"-producing mouse button. + + By definition, this includes left-click on windows/linux, and left-click + without the ctrl key on Macs.

Returns
The result.

Defined in goog.events.Event

Deprecated: Events don't need to be disposed.

For backwards compatibility (goog.events.Event used to inherit + goog.Disposable).

Instance Properties

Defined in goog.events.BrowserEvent

Whether alt was pressed at time of event.

Which mouse button was pressed.

Keycode of key press.

X-coordinate relative to the window.

Y-coordinate relative to the window.

Whether control was pressed at time of event.

Node that had the listener attached.

The browser event object.

Keycode of key press.

Whether the meta key was pressed at time of event.

X-coordinate relative to target.

Y-coordinate relative to target.

Whether the default platform modifier key was pressed at time of event. + (This is control for all platforms except Mac, where it's Meta.)

For mouseover and mouseout events, the related object for the event.

X-coordinate relative to the monitor.

Y-coordinate relative to the monitor.

Whether shift was pressed at time of event.

History state object, only set for PopState events where it's a copy of the + state object provided to pushState or replaceState.

Target that fired the event.

Defined in goog.events.Event

Whether the default action has been prevented. + This is a property to match the W3C specification at + #events-event-type-defaultPrevented. + Must be treated as read-only outside the class.

Whether to cancel the event in internal capture/bubble processing for IE.

Return value for in internal capture/bubble processing for IE.

Event type.

Static Properties

Static data for mapping mouse buttons.

\ No newline at end of file diff --git a/docs/api/javascript/class_goog_events_Event.html b/docs/api/javascript/class_goog_events_Event.html new file mode 100644 index 0000000000000..654a97da64664 --- /dev/null +++ b/docs/api/javascript/class_goog_events_Event.html @@ -0,0 +1,16 @@ +goog.events.Event

Class goog.events.Event

code »

A base class for event objects, so that they can support preventDefault and + stopPropagation.

Constructor

goog.events.Event ( type, opt_target )
Parameters
type: (string|!goog.events.EventId)
Event Type.
opt_target: Object=
Reference to the object that is the target of + this event. It has to implement the EventTarget interface + declared at http://developer.mozilla.org/en/DOM/EventTarget.
Show:

Instance Methods

Deprecated: Events don't need to be disposed.

For backwards compatibility (goog.events.Event used to inherit + goog.Disposable).

Deprecated: Events don't need to be disposed.

For backwards compatibility (goog.events.Event used to inherit + goog.Disposable).

Prevents the default action, for example a link redirecting to a url.

Stops event propagation.

Instance Properties

Object that had the listener attached.

Whether the default action has been prevented. + This is a property to match the W3C specification at + #events-event-type-defaultPrevented. + Must be treated as read-only outside the class.

Whether to cancel the event in internal capture/bubble processing for IE.

Return value for in internal capture/bubble processing for IE.

TODO(user): The type should probably be + EventTarget|goog.events.EventTarget. + + Target of the event.

Event type.

Static Functions

Prevents the default action. It is equivalent to + e.preventDefault(), but can be used as the callback argument of + goog.events.listen without declaring another function.

Parameters
e: !goog.events.Event
An event.

Stops the propagation of the event. It is equivalent to + e.stopPropagation(), but can be used as the callback argument of + goog.events.listen without declaring another function.

Parameters
e: !goog.events.Event
An event.
\ No newline at end of file diff --git a/docs/api/javascript/class_goog_events_EventId.html b/docs/api/javascript/class_goog_events_EventId.html new file mode 100644 index 0000000000000..451152687b027 --- /dev/null +++ b/docs/api/javascript/class_goog_events_EventId.html @@ -0,0 +1,10 @@ +goog.events.EventId

Class goog.events.EventId.<T>

code »

A templated class that is used when registering for events. Typical usage: + + /** @type {goog.events.EventId.} + var myEventId = new goog.events.EventId( + goog.events.getUniqueId(('someEvent')); + + // No need to cast or declare here since the compiler knows the correct + // type of 'evt' (MyEventObj). + something.listen(myEventId, function(evt) {}); +

Constructor

goog.events.EventId ( eventId )
Parameters
eventId
Show:

Instance Methods

code »toString ( )string

Instance Properties

\ No newline at end of file diff --git a/docs/api/javascript/class_goog_events_EventTarget.html b/docs/api/javascript/class_goog_events_EventTarget.html new file mode 100644 index 0000000000000..2cc42c83dab93 --- /dev/null +++ b/docs/api/javascript/class_goog_events_EventTarget.html @@ -0,0 +1,68 @@ +goog.events.EventTarget

Class goog.events.EventTarget

code »
goog.Disposable
+  └ goog.events.EventTarget
All implemented interfaces:
goog.disposable.IDisposable, goog.events.Listenable

An implementation of goog.events.Listenable with full W3C + EventTarget-like support (capture/bubble mechanism, stopping event + propagation, preventing default actions). + + You may subclass this class to turn your class into a Listenable. + + Unless propagation is stopped, an event dispatched by an + EventTarget will bubble to the parent returned by + getParentEventTarget. To set the parent, call + setParentEventTarget. Subclasses that don't support + changing the parent can override the setter to throw an error. + + Example usage: +

+   var source = new goog.events.EventTarget();
+   function handleEvent(e) {
+     alert('Type: ' + e.type + '; Target: ' + e.target);
+   }
+   source.listen('foo', handleEvent);
+   // Or: goog.events.listen(source, 'foo', handleEvent);
+   ...
+   source.dispatchEvent('foo');  // will call handleEvent
+   ...
+   source.unlisten('foo', handleEvent);
+   // Or: goog.events.unlisten(source, 'foo', handleEvent);
+ 

Constructor

goog.events.EventTarget ( )
Show:

Instance Methods

Defined in goog.events.EventTarget

code »addEventListener ( type, handler, opt_capture, opt_handlerScope )
Deprecated: Use #listen instead, when possible. Otherwise, use + goog.events.listen if you are passing Object + (instead of Function) as handler.

Adds an event listener to the event target. The same handler can only be + added once per the type. Even if you add the same handler multiple times + using the same type then it will only be called once when the event is + dispatched.

Parameters
type: string
The type of the event to listen for.
handler: (function(?): ?|{handleEvent: function(?): ?}|null)
The function + to handle the event. The handler can also be an object that implements + the handleEvent method which takes the event object as argument.
opt_capture: boolean=
In DOM-compliant browsers, this determines + whether the listener is fired during the capture or bubble phase + of the event.
opt_handlerScope: Object=
Object in whose scope to call + the listener.

Asserts that the event target instance is initialized properly.

code »dispatchEvent ( e )boolean
Parameters
e

Removes listeners from this object. Classes that extend EventTarget may + need to override this method in order to remove references to DOM Elements + and additional listeners.

code »fireListeners ( type, capture, eventObject )boolean
Parameters
type
capture
eventObject
code »getListener ( type, listener, capture, opt_listenerScope )(goog.events.ListenableKey|null)
Parameters
type
listener
capture
opt_listenerScope
code »getListeners ( type, capture )Array.<(goog.events.ListenableKey|null)>
Parameters
type
capture

Returns the parent of this event target to use for bubbling.

Returns
The parent EventTarget or null if + there is no parent.
code »hasListener ( opt_type, opt_capture )boolean
Parameters
opt_type
opt_capture
code »listen ( type, listener, opt_useCapture, opt_listenerScope )(goog.events.ListenableKey|null)
Parameters
type
listener
opt_useCapture
opt_listenerScope
code »listenOnce ( type, listener, opt_useCapture, opt_listenerScope )(goog.events.ListenableKey|null)
Parameters
type
listener
opt_useCapture
opt_listenerScope
code »removeAllListeners ( opt_type )number
Parameters
opt_type
code »removeEventListener ( type, handler, opt_capture, opt_handlerScope )
Deprecated: Use #unlisten instead, when possible. Otherwise, use + goog.events.unlisten if you are passing Object + (instead of Function) as handler.

Removes an event listener from the event target. The handler must be the + same object as the one added. If the handler has not been added then + nothing is done.

Parameters
type: string
The type of the event to listen for.
handler: (function(?): ?|{handleEvent: function(?): ?}|null)
The function + to handle the event. The handler can also be an object that implements + the handleEvent method which takes the event object as argument.
opt_capture: boolean=
In DOM-compliant browsers, this determines + whether the listener is fired during the capture or bubble phase + of the event.
opt_handlerScope: Object=
Object in whose scope to call + the listener.

Sets the parent of this event target to use for capture/bubble + mechanism.

Parameters
parent: goog.events.EventTarget
Parent listenable (null if none).

Sets the target to be used for event.target when firing + event. Mainly used for testing. For example, see + goog.testing.events.mixinListenable.

Parameters
target: !Object
The target.
code »unlisten ( type, listener, opt_useCapture, opt_listenerScope )boolean
Parameters
type
listener
opt_useCapture
opt_listenerScope
code »unlistenByKey ( key )boolean
Parameters
key

Defined in goog.Disposable

code »<T> addOnDisposeCallback ( callback, opt_scope )

Invokes a callback function when this object is disposed. Callbacks are + invoked in the order in which they were added.

Parameters
callback: function(this: T): ?
The callback function.
opt_scope: T=
An optional scope to call the callback in.
code »dispose ( )void

Disposes of the object. If the object hasn't already been disposed of, calls + #disposeInternal. Classes that extend goog.Disposable should + override #disposeInternal in order to delete references to COM + objects, DOM nodes, and other disposable objects. Reentrant.

Returns
Nothing.
Deprecated: Use #isDisposed instead.
Returns
Whether the object has been disposed of.
Returns
Whether the object has been disposed of.

Associates a disposable object with this object so that they will be disposed + together.

Parameters
disposable: goog.disposable.IDisposable
that will be disposed when + this object is disposed.

Instance Properties

Defined in goog.events.EventTarget

The object to use for event.target. Useful when mixing in an + EventTarget to another object.

Maps of event type to an array of listeners.

Parent event target, used during event bubbling. + + TODO(user): Change this to goog.events.Listenable. This + currently breaks people who expect getParentEventTarget to return + goog.events.EventTarget.

Defined in goog.Disposable

If monitoring the goog.Disposable instances is enabled, stores the creation + stack trace of the Disposable instance.

Whether the object has been disposed of.

Callbacks to invoke when this object is disposed.

Static Functions

Dispatches the given event on the ancestorsTree.

Parameters
target: !Object
The target to dispatch on.
e: (goog.events.Event|Object|string)
The event object.
opt_ancestorsTree: Array.<goog.events.Listenable>=
The ancestors + tree of the target, in reverse order from the closest ancestor + to the root event target. May be null if the target has no ancestor.
Returns
If anyone called preventDefault on the event object (or + if any of the listeners returns false) this will also return false.

Static Properties

An artificial cap on the number of ancestors you can have. This is mainly + for loop detection.

\ No newline at end of file diff --git a/docs/api/javascript/class_goog_events_Listener.html b/docs/api/javascript/class_goog_events_Listener.html new file mode 100644 index 0000000000000..7b718bc56740c --- /dev/null +++ b/docs/api/javascript/class_goog_events_Listener.html @@ -0,0 +1,6 @@ +goog.events.Listener

Class goog.events.Listener

code »
All implemented interfaces:
goog.events.ListenableKey

Simple class that stores information about a listener

Constructor

goog.events.Listener ( listener, proxy, src, type, capture, opt_handler )
Parameters
listener: !Function
Callback function.
proxy: Function
Wrapper for the listener that patches the event.
src: (EventTarget|goog.events.Listenable)
Source object for + the event.
type: string
Event type.
capture: boolean
Whether in capture or bubble phase.
opt_handler: Object=
Object in whose context to execute the callback.
Show:

Instance Methods

Marks this listener as removed. This also remove references held by + this listener object (such as listener and event source).

Instance Properties

Whether to remove the listener after it has been called.

Whether the listener is being called in the capture or bubble phase

If monitoring the goog.events.Listener instances is enabled, stores the + creation stack trace of the Disposable instance.

Optional object whose context to execute the listener in

The key of the listener.

Callback function.

A wrapper over the original listener. This is used solely to + handle native browser events (it is used to simulate the capture + phase and to patch the event object).

Whether the listener has been removed.

Object or node that callback is listening to

The event type.

Compiler Constants

\ No newline at end of file diff --git a/docs/api/javascript/class_goog_events_ListenerMap.html b/docs/api/javascript/class_goog_events_ListenerMap.html new file mode 100644 index 0000000000000..2e5abb3ed4662 --- /dev/null +++ b/docs/api/javascript/class_goog_events_ListenerMap.html @@ -0,0 +1,23 @@ +goog.events.ListenerMap

Class goog.events.ListenerMap

code »

Creates a new listener map.

Constructor

goog.events.ListenerMap ( src )
Parameters
src: (EventTarget|goog.events.Listenable)
The src object.
Show:

Instance Methods

code »add ( type, listener, callOnce, opt_useCapture, opt_listenerScope )goog.events.ListenableKey

Adds an event listener. A listener can only be added once to an + object and if it is added again the key for the listener is + returned. + + Note that a one-off listener will not change an existing listener, + if any. On the other hand a normal listener will change existing + one-off listener to become a normal listener.

Parameters
type: (string|!goog.events.EventId)
The listener event type.
listener: !Function
This listener callback method.
callOnce: boolean
Whether the listener is a one-off + listener.
opt_useCapture: boolean=
The capture mode of the listener.
opt_listenerScope: Object=
Object in whose scope to call the + listener.
Returns
Unique key for the listener.
code »getListener ( type, listener, capture, opt_listenerScope )goog.events.ListenableKey

Gets the goog.events.ListenableKey for the event or null if no such + listener is in use.

Parameters
type: (string|!goog.events.EventId)
The type of the listener + to retrieve.
listener: !Function
The listener function to get.
capture: boolean
Whether the listener is a capturing listener.
opt_listenerScope: Object=
Object in whose scope to call the + listener.
Returns
the found listener or null if not found.
Returns
Total number of registered listeners.

Gets all listeners that match the given type and capture mode. The + returned array is a copy (but the listener objects are not).

Parameters
type: (string|!goog.events.EventId)
The type of the listeners + to retrieve.
capture: boolean
The capture mode of the listeners to retrieve.
Returns
An array of matching + listeners.
Returns
The count of event types in this map that actually + have registered listeners.
code »hasListener ( opt_type, opt_capture )boolean

Whether there is a matching listener. If either the type or capture + parameters are unspecified, the function will match on the + remaining criteria.

Parameters
opt_type: (string|!goog.events.EventId)=
The type of the listener.
opt_capture: boolean=
The capture mode of the listener.
Returns
Whether there is an active listener matching + the requested type and/or capture phase.
code »remove ( type, listener, opt_useCapture, opt_listenerScope )boolean

Removes a matching listener.

Parameters
type: (string|!goog.events.EventId)
The listener event type.
listener: !Function
This listener callback method.
opt_useCapture: boolean=
The capture mode of the listener.
opt_listenerScope: Object=
Object in whose scope to call the + listener.
Returns
Whether any listener was removed.
code »removeAll ( opt_type )number

Removes all listeners from this map. If opt_type is provided, only + listeners that match the given type are removed.

Parameters
opt_type: (string|!goog.events.EventId)=
Type of event to remove.
Returns
Number of listeners removed.
code »removeByKey ( listener )boolean

Removes the given listener object.

Parameters
listener: goog.events.ListenableKey
The listener to remove.
Returns
Whether the listener is removed.

Instance Properties

Maps of event type to an array of listeners.

The count of types in this map that have registered listeners.

Static Functions

code »goog.events.ListenerMap.findListenerIndex_ ( listenerArray, listener, opt_useCapture, opt_listenerScope )number

Finds the index of a matching goog.events.Listener in the given + listenerArray.

Parameters
listenerArray: !Array
Array of listener.
listener: !Function
The listener function.
opt_useCapture: boolean=
The capture flag for the listener.
opt_listenerScope: Object=
The listener scope.
Returns
The index of the matching listener within the + listenerArray.
\ No newline at end of file diff --git a/docs/api/javascript/class_goog_iter_GroupByIterator_.html b/docs/api/javascript/class_goog_iter_GroupByIterator_.html index 6331c61fcbd56..c2e0c02287c20 100644 --- a/docs/api/javascript/class_goog_iter_GroupByIterator_.html +++ b/docs/api/javascript/class_goog_iter_GroupByIterator_.html @@ -9,4 +9,4 @@ 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 + 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/docs/api/javascript/class_goog_iter_Iterator.html b/docs/api/javascript/class_goog_iter_Iterator.html index 9a08d8ff837e7..c1ed2cdc307ce 100644 --- a/docs/api/javascript/class_goog_iter_Iterator.html +++ b/docs/api/javascript/class_goog_iter_Iterator.html @@ -8,4 +8,4 @@ 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 + goog.iter#StopIteration when the iteration passes the end.
Returns
Any object or value.
\ No newline at end of file diff --git a/docs/api/javascript/class_goog_json_Serializer.html b/docs/api/javascript/class_goog_json_Serializer.html index cb17974567047..9b83d58328ee3 100644 --- a/docs/api/javascript/class_goog_json_Serializer.html +++ b/docs/api/javascript/class_goog_json_Serializer.html @@ -1,4 +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. +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 + adjusts the regular expression accordingly.
\ No newline at end of file diff --git a/docs/api/javascript/class_goog_labs_testing_AllOfMatcher.html b/docs/api/javascript/class_goog_labs_testing_AllOfMatcher.html index a8abeeb35580d..b407e608a27ae 100644 --- a/docs/api/javascript/class_goog_labs_testing_AllOfMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_AllOfMatcher.html @@ -1,2 +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 + 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/docs/api/javascript/class_goog_labs_testing_AnyOfMatcher.html b/docs/api/javascript/class_goog_labs_testing_AnyOfMatcher.html index 69104a3e87acd..dfa33315f7223 100644 --- a/docs/api/javascript/class_goog_labs_testing_AnyOfMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_AnyOfMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_CloseToMatcher.html b/docs/api/javascript/class_goog_labs_testing_CloseToMatcher.html index 6ba10dd700025..790d379926623 100644 --- a/docs/api/javascript/class_goog_labs_testing_CloseToMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_CloseToMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_ContainsStringMatcher.html b/docs/api/javascript/class_goog_labs_testing_ContainsStringMatcher.html index 0cff10fd5bca7..772335e2e1df5 100644 --- a/docs/api/javascript/class_goog_labs_testing_ContainsStringMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_ContainsStringMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_EndsWithMatcher.html b/docs/api/javascript/class_goog_labs_testing_EndsWithMatcher.html index 3a8150c400a77..b6e434f6d7b82 100644 --- a/docs/api/javascript/class_goog_labs_testing_EndsWithMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_EndsWithMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_EqualToIgnoringWhitespaceMatcher.html b/docs/api/javascript/class_goog_labs_testing_EqualToIgnoringWhitespaceMatcher.html index de9baf2299bfc..f82d5983168e3 100644 --- a/docs/api/javascript/class_goog_labs_testing_EqualToIgnoringWhitespaceMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_EqualToIgnoringWhitespaceMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_EqualToMatcher.html b/docs/api/javascript/class_goog_labs_testing_EqualToMatcher.html index cab42687cfff9..81c5dcbdf611c 100644 --- a/docs/api/javascript/class_goog_labs_testing_EqualToMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_EqualToMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_EqualsMatcher.html b/docs/api/javascript/class_goog_labs_testing_EqualsMatcher.html index bec6a9e1866e7..ab302cc419e97 100644 --- a/docs/api/javascript/class_goog_labs_testing_EqualsMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_EqualsMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_GreaterThanEqualToMatcher.html b/docs/api/javascript/class_goog_labs_testing_GreaterThanEqualToMatcher.html index dc0eef558076e..75cfdab953da7 100644 --- a/docs/api/javascript/class_goog_labs_testing_GreaterThanEqualToMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_GreaterThanEqualToMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_GreaterThanMatcher.html b/docs/api/javascript/class_goog_labs_testing_GreaterThanMatcher.html index d6833fc8ceb05..841df16fabf9f 100644 --- a/docs/api/javascript/class_goog_labs_testing_GreaterThanMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_GreaterThanMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_HasPropertyMatcher.html b/docs/api/javascript/class_goog_labs_testing_HasPropertyMatcher.html index 20cbe1b194ec9..457b6c5b3651a 100644 --- a/docs/api/javascript/class_goog_labs_testing_HasPropertyMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_HasPropertyMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_InstanceOfMatcher.html b/docs/api/javascript/class_goog_labs_testing_InstanceOfMatcher.html index 28672ce494617..255bd2e2f737c 100644 --- a/docs/api/javascript/class_goog_labs_testing_InstanceOfMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_InstanceOfMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_IsNotMatcher.html b/docs/api/javascript/class_goog_labs_testing_IsNotMatcher.html index 3900ba621391e..a36c7ceb8145f 100644 --- a/docs/api/javascript/class_goog_labs_testing_IsNotMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_IsNotMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_IsNullMatcher.html b/docs/api/javascript/class_goog_labs_testing_IsNullMatcher.html index 2f49dbb692f59..2873c4fc56dca 100644 --- a/docs/api/javascript/class_goog_labs_testing_IsNullMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_IsNullMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_IsNullOrUndefinedMatcher.html b/docs/api/javascript/class_goog_labs_testing_IsNullOrUndefinedMatcher.html index 6dfc0164b9c44..40eff3573d0ce 100644 --- a/docs/api/javascript/class_goog_labs_testing_IsNullOrUndefinedMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_IsNullOrUndefinedMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_IsUndefinedMatcher.html b/docs/api/javascript/class_goog_labs_testing_IsUndefinedMatcher.html index 195756d210a23..e5414711e5d88 100644 --- a/docs/api/javascript/class_goog_labs_testing_IsUndefinedMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_IsUndefinedMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_LessThanEqualToMatcher.html b/docs/api/javascript/class_goog_labs_testing_LessThanEqualToMatcher.html index c2b056d1e153d..ffd26c372779b 100644 --- a/docs/api/javascript/class_goog_labs_testing_LessThanEqualToMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_LessThanEqualToMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_LessThanMatcher.html b/docs/api/javascript/class_goog_labs_testing_LessThanMatcher.html index d6ef5aa532ed4..3dc64a1e5f5c7 100644 --- a/docs/api/javascript/class_goog_labs_testing_LessThanMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_LessThanMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_MatcherError.html b/docs/api/javascript/class_goog_labs_testing_MatcherError.html index d59d8cd09a416..8edf8d8d8b508 100644 --- a/docs/api/javascript/class_goog_labs_testing_MatcherError.html +++ b/docs/api/javascript/class_goog_labs_testing_MatcherError.html @@ -1,3 +1,3 @@ goog.labs.testing.MatcherError

Class goog.labs.testing.MatcherError

code »
Errorgoog.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 + └ 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/docs/api/javascript/class_goog_labs_testing_ObjectEqualsMatcher.html b/docs/api/javascript/class_goog_labs_testing_ObjectEqualsMatcher.html index c1866469f6346..12d8f280ad10e 100644 --- a/docs/api/javascript/class_goog_labs_testing_ObjectEqualsMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_ObjectEqualsMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_RegexMatcher.html b/docs/api/javascript/class_goog_labs_testing_RegexMatcher.html index a2c868ff9df6e..db2df2ee4193a 100644 --- a/docs/api/javascript/class_goog_labs_testing_RegexMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_RegexMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_StartsWithMatcher.html b/docs/api/javascript/class_goog_labs_testing_StartsWithMatcher.html index d365ba056bdc6..df9f7381e6f82 100644 --- a/docs/api/javascript/class_goog_labs_testing_StartsWithMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_StartsWithMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_labs_testing_StringContainsInOrderMatcher.html b/docs/api/javascript/class_goog_labs_testing_StringContainsInOrderMatcher.html index 8b3943844f30a..02b0b872a6a82 100644 --- a/docs/api/javascript/class_goog_labs_testing_StringContainsInOrderMatcher.html +++ b/docs/api/javascript/class_goog_labs_testing_StringContainsInOrderMatcher.html @@ -1 +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 +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/docs/api/javascript/class_goog_math_Box.html b/docs/api/javascript/class_goog_math_Box.html new file mode 100644 index 0000000000000..84531c7dd9379 --- /dev/null +++ b/docs/api/javascript/class_goog_math_Box.html @@ -0,0 +1,23 @@ +goog.math.Box

Class goog.math.Box

code »

Class for representing a box. A box is specified as a top, right, bottom, + and left. A box is useful for representing margins and padding. + + This class assumes 'screen coordinates': larger Y coordinates are further + from the top of the screen.

Constructor

goog.math.Box ( top, right, bottom, left )
Parameters
top: number
Top.
right: number
Right.
bottom: number
Bottom.
left: number
Left.
Show:

Instance Methods

Rounds the fields to the next larger integer values.

Returns
This box with ceil'd fields.

Creates a copy of the box with the same dimensions.

Returns
A clone of this Box.
code »contains ( other )boolean

Returns whether the box contains a coordinate or another box.

Parameters
other: (goog.math.Coordinate|goog.math.Box)
A Coordinate or a Box.
Returns
Whether the box contains the coordinate or other box.
code »expand ( top, opt_right, opt_bottom, opt_left )!goog.math.Box

Expands box with the given margins.

Parameters
top: (number|goog.math.Box)
Top margin or box with all margins.
opt_right: number=
Right margin.
opt_bottom: number=
Bottom margin.
opt_left: number=
Left margin.
Returns
A reference to this Box.

Expand this box to include another box. + NOTE(user): This is used in code that needs to be very fast, please don't + add functionality to this function at the expense of speed (variable + arguments, accepting multiple argument types, etc).

Parameters
box: goog.math.Box
The box to include in this one.

Rounds the fields to the next smaller integer values.

Returns
This box with floored fields.
Returns
height The height of this Box.
Returns
width The width of this Box.

Rounds the fields to nearest integer values.

Returns
This box with rounded fields.
code »scale ( sx, opt_sy )!goog.math.Box

Scales this coordinate by the given scale factors. The x and y dimension + values are scaled by sx and opt_sy respectively. + If opt_sy is not given, then sx is used for both x and y.

Parameters
sx: number
The scale factor to use for the x dimension.
opt_sy: number=
The scale factor to use for the y dimension.
Returns
This box after scaling.

Returns a nice string representing the box.

Returns
In the form (50t, 73r, 24b, 13l).
code »translate ( tx, opt_ty )!goog.math.Box

Translates this box by the given offsets. If a goog.math.Coordinate + is given, then the left and right values are translated by the coordinate's + x value and the top and bottom values are translated by the coordinate's y + value. Otherwise, tx and opt_ty are used to translate the x + and y dimension values.

Parameters
tx: (number|goog.math.Coordinate)
The value to translate the x + dimension values by or the the coordinate to translate this box by.
opt_ty: number=
The value to translate y dimension values by.
Returns
This box after translating.

Instance Properties

Static Functions

Creates a Box by bounding a collection of goog.math.Coordinate objects

Parameters
var_args: ...goog.math.Coordinate
Coordinates to be included inside + the box.
Returns
A Box containing all the specified Coordinates.

Returns whether a box contains a coordinate or another box.

Parameters
box: goog.math.Box
A Box.
other: (goog.math.Coordinate|goog.math.Box)
A Coordinate or a Box.
Returns
Whether the box contains the coordinate or other box.

Returns the distance between a coordinate and the nearest corner/side of a + box. Returns zero if the coordinate is inside the box.

Parameters
box: goog.math.Box
A Box.
coord: goog.math.Coordinate
A Coordinate.
Returns
The distance between coord and the nearest + corner/side of box, or zero if coord is inside + box.

Compares boxes for equality.

Parameters
a: goog.math.Box
A Box.
b: goog.math.Box
A Box.
Returns
True iff the boxes are equal, or if both are null.

Returns whether two boxes intersect.

Parameters
a: goog.math.Box
A Box.
b: goog.math.Box
A second Box.
Returns
Whether the boxes intersect.

Returns whether two boxes would intersect with additional padding.

Parameters
a: goog.math.Box
A Box.
b: goog.math.Box
A second Box.
padding: number
The additional padding.
Returns
Whether the boxes intersect.

Returns the relative x position of a coordinate compared to a box. Returns + zero if the coordinate is inside the box.

Parameters
box: goog.math.Box
A Box.
coord: goog.math.Coordinate
A Coordinate.
Returns
The x position of coord relative to the nearest + side of box, or zero if coord is inside box.

Returns the relative y position of a coordinate compared to a box. Returns + zero if the coordinate is inside the box.

Parameters
box: goog.math.Box
A Box.
coord: goog.math.Coordinate
A Coordinate.
Returns
The y position of coord relative to the nearest + side of box, or zero if coord is inside box.
\ No newline at end of file diff --git a/docs/api/javascript/class_goog_math_Coordinate.html b/docs/api/javascript/class_goog_math_Coordinate.html new file mode 100644 index 0000000000000..c1e4989638e73 --- /dev/null +++ b/docs/api/javascript/class_goog_math_Coordinate.html @@ -0,0 +1,22 @@ +goog.math.Coordinate

Class goog.math.Coordinate

code »

Class for representing coordinates and positions.

Constructor

goog.math.Coordinate ( opt_x, opt_y )
Parameters
opt_x: number=
Left, defaults to 0.
opt_y: number=
Top, defaults to 0.
Show:

Instance Methods

Rounds the x and y fields to the next larger integer values.

Returns
This coordinate with ceil'd fields.

Returns a new copy of the coordinate.

Returns
A clone of this coordinate.

Rounds the x and y fields to the next smaller integer values.

Returns
This coordinate with floored fields.
code »rotateDegrees ( degrees, opt_center )

Rotates this coordinate clockwise about the origin (or, optionally, the given + center) by the given angle, in degrees.

Parameters
degrees: number
The angle by which to rotate this coordinate + clockwise about the given center, in degrees.
opt_center: !goog.math.Coordinate=
The center of rotation. Defaults + to (0, 0) if not given.
code »rotateRadians ( radians, opt_center )

Rotates this coordinate clockwise about the origin (or, optionally, the given + center) by the given angle, in radians.

Parameters
radians: number
The angle by which to rotate this coordinate + clockwise about the given center, in radians.
opt_center: !goog.math.Coordinate=
The center of rotation. Defaults + to (0, 0) if not given.

Rounds the x and y fields to the nearest integer values.

Returns
This coordinate with rounded fields.

Scales this coordinate by the given scale factors. The x and y values are + scaled by sx and opt_sy respectively. If opt_sy + is not given, then sx is used for both x and y.

Parameters
sx: number
The scale factor to use for the x dimension.
opt_sy: number=
The scale factor to use for the y dimension.
Returns
This coordinate after scaling.

Returns a nice string representing the coordinate.

Returns
In the form (50, 73).

Translates this box by the given offsets. If a goog.math.Coordinate + is given, then the x and y values are translated by the coordinate's x and y. + Otherwise, x and y are translated by tx and opt_ty + respectively.

Parameters
tx: (number|goog.math.Coordinate)
The value to translate x by or the + the coordinate to translate this coordinate by.
opt_ty: number=
The value to translate y by.
Returns
This coordinate after translating.

Instance Properties

X-value

Y-value

Static Functions

Returns the angle from the origin to a coordinate.

Parameters
a: !goog.math.Coordinate
A Coordinate.
Returns
The angle, in degrees, clockwise from the positive X + axis to a.

Returns the difference between two coordinates as a new + goog.math.Coordinate.

Parameters
a: !goog.math.Coordinate
A Coordinate.
b: !goog.math.Coordinate
A Coordinate.
Returns
A Coordinate representing the difference + between a and b.

Returns the distance between two coordinates.

Parameters
a: !goog.math.Coordinate
A Coordinate.
b: !goog.math.Coordinate
A Coordinate.
Returns
The distance between a and b.

Compares coordinates for equality.

Parameters
a: goog.math.Coordinate
A Coordinate.
b: goog.math.Coordinate
A Coordinate.
Returns
True iff the coordinates are equal, or if both are null.

Returns the magnitude of a coordinate.

Parameters
a: !goog.math.Coordinate
A Coordinate.
Returns
The distance between the origin and a.

Returns the squared distance between two coordinates. Squared distances can + be used for comparisons when the actual value is not required. + + Performance note: eliminating the square root is an optimization often used + in lower-level languages, but the speed difference is not nearly as + pronounced in JavaScript (only a few percent.)

Parameters
a: !goog.math.Coordinate
A Coordinate.
b: !goog.math.Coordinate
A Coordinate.
Returns
The squared distance between a and b.

Returns the sum of two coordinates as a new goog.math.Coordinate.

Parameters
a: !goog.math.Coordinate
A Coordinate.
b: !goog.math.Coordinate
A Coordinate.
Returns
A Coordinate representing the sum of the two + coordinates.
\ No newline at end of file diff --git a/docs/api/javascript/class_goog_math_Rect.html b/docs/api/javascript/class_goog_math_Rect.html new file mode 100644 index 0000000000000..3b077ebbe0151 --- /dev/null +++ b/docs/api/javascript/class_goog_math_Rect.html @@ -0,0 +1,34 @@ +goog.math.Rect

Class goog.math.Rect

code »

Class for representing rectangular regions.

Constructor

goog.math.Rect ( x, y, w, h )
Parameters
x: number
Left.
y: number
Top.
w: number
Width.
h: number
Height.
Show:

Instance Methods

Expand this rectangle to also include the area of the given rectangle.

Parameters
rect: goog.math.Rect
The other rectangle.

Rounds the fields to the next larger integer values.

Returns
This rectangle with ceil'd fields.
Returns
A new copy of this Rectangle.
code »contains ( another )boolean

Tests whether this rectangle entirely contains another rectangle or + coordinate.

Parameters
another: (goog.math.Rect|goog.math.Coordinate)
The rectangle or + coordinate to test for containment.
Returns
Whether this rectangle contains given rectangle or + coordinate.
code »difference ( rect )!Array

Computes the difference regions between this rectangle and rect. The + return value is an array of 0 to 4 rectangles defining the remaining regions + of this rectangle after the other has been subtracted.

Parameters
rect: goog.math.Rect
A Rectangle.
Returns
An array with 0 to 4 rectangles which + together define the difference area of rectangle a minus rectangle b.
code »distance ( point )number
Parameters
point: !goog.math.Coordinate
A coordinate.
Returns
The distance between the point and the closest point + inside the rectangle. Returns 0 if the point is inside the rectangle.

Rounds the fields to the next smaller integer values.

Returns
This rectangle with floored fields.
Returns
A new coordinate for the bottom-right corner + of the rectangle.
Returns
A new coordinate for the center of the + rectangle.
Returns
The size of this rectangle.
Returns
A new coordinate for the top-left corner of + the rectangle.

Computes the intersection of this rectangle and the rectangle parameter. If + there is no intersection, returns false and leaves this rectangle as is.

Parameters
rect: goog.math.Rect
A Rectangle.
Returns
True iff this rectangle intersects with the parameter.

Returns whether a rectangle intersects this rectangle.

Parameters
rect: goog.math.Rect
A rectangle.
Returns
Whether rect intersects this rectangle.

Rounds the fields to nearest integer values.

Returns
This rectangle with rounded fields.
code »scale ( sx, opt_sy )!goog.math.Rect

Scales this rectangle by the given scale factors. The left and width values + are scaled by sx and the top and height values are scaled by + opt_sy. If opt_sy is not given, then all fields are scaled + by sx.

Parameters
sx: number
The scale factor to use for the x dimension.
opt_sy: number=
The scale factor to use for the y dimension.
Returns
This rectangle after scaling.
Parameters
point: !goog.math.Coordinate
A coordinate.
Returns
The squared distance between the point and the closest + point inside the rectangle. Returns 0 if the point is inside the + rectangle.

Returns a new Box object with the same position and dimensions as this + rectangle.

Returns
A new Box representation of this Rectangle.

Returns a nice string representing size and dimensions of rectangle.

Returns
In the form (50, 73 - 75w x 25h).
code »translate ( tx, opt_ty )!goog.math.Rect

Translates this rectangle by the given offsets. If a + goog.math.Coordinate is given, then the left and top values are + translated by the coordinate's x and y values. Otherwise, top and left are + translated by tx and opt_ty respectively.

Parameters
tx: (number|goog.math.Coordinate)
The value to translate left by or the + the coordinate to translate this rect by.
opt_ty: number=
The value to translate top by.
Returns
This rectangle after translating.

Instance Properties

Static Functions

Returns a new rectangle which completely contains both input rectangles.

Parameters
a: goog.math.Rect
A rectangle.
b: goog.math.Rect
A rectangle.
Returns
A new bounding rect, or null if either rect is + null.

Creates a new Rect object with the same position and dimensions as a given + Box. Note that this is only the inverse of toBox if left/top are defined.

Parameters
box: goog.math.Box
A box.
Returns
A new Rect initialized with the box's position + and size.

Computes the difference regions between two rectangles. The return value is + an array of 0 to 4 rectangles defining the remaining regions of the first + rectangle after the second has been subtracted.

Parameters
a: goog.math.Rect
A Rectangle.
b: goog.math.Rect
A Rectangle.
Returns
An array with 0 to 4 rectangles which + together define the difference area of rectangle a minus rectangle b.

Compares rectangles for equality.

Parameters
a: goog.math.Rect
A Rectangle.
b: goog.math.Rect
A Rectangle.
Returns
True iff the rectangles have the same left, top, width, + and height, or if both are null.

Returns the intersection of two rectangles. Two rectangles intersect if they + touch at all, for example, two zero width and height rectangles would + intersect if they had the same top and left.

Parameters
a: goog.math.Rect
A Rectangle.
b: goog.math.Rect
A Rectangle.
Returns
A new intersection rect (even if width and height + are 0), or null if there is no intersection.

Returns whether two rectangles intersect. Two rectangles intersect if they + touch at all, for example, two zero width and height rectangles would + intersect if they had the same top and left.

Parameters
a: goog.math.Rect
A Rectangle.
b: goog.math.Rect
A Rectangle.
Returns
Whether a and b intersect.
\ No newline at end of file diff --git a/docs/api/javascript/class_goog_math_Size.html b/docs/api/javascript/class_goog_math_Size.html new file mode 100644 index 0000000000000..efb7ff6aee44b --- /dev/null +++ b/docs/api/javascript/class_goog_math_Size.html @@ -0,0 +1,10 @@ +goog.math.Size

Class goog.math.Size

code »

Class for representing sizes consisting of a width and height. Undefined + width and height support is deprecated and results in compiler warning.

Constructor

goog.math.Size ( width, height )
Parameters
width: number
Width.
height: number
Height.
Show:

Instance Methods

Returns
The area of the size (width * height).
Returns
The ratio of the size's width to its height.

Clamps the width and height parameters upward to integer values.

Returns
This size with ceil'd components.
Returns
A new copy of the Size.
code »fitsInside ( target )boolean
Parameters
target: !goog.math.Size
The target size.
Returns
True if this Size is the same size or smaller than the + target size in both dimensions.

Clamps the width and height parameters downward to integer values.

Returns
This size with floored components.
Returns
The longer of the two dimensions in the size.
Returns
The shorter of the two dimensions in the size.
Returns
True if the size has zero area, false if both dimensions + are non-zero numbers.
Returns
The perimeter of the size (width + height) * 2.

Rounds the width and height parameters to integer values.

Returns
This size with rounded components.
code »scale ( sx, opt_sy )!goog.math.Size

Scales this size by the given scale factors. The width and height are scaled + by sx and opt_sy respectively. If opt_sy is not + given, then sx is used for both the width and height.

Parameters
sx: number
The scale factor to use for the width.
opt_sy: number=
The scale factor to use for the height.
Returns
This Size object after scaling.

Uniformly scales the size to fit inside the dimensions of a given size. The + original aspect ratio will be preserved. + + This function assumes that both Sizes contain strictly positive dimensions.

Parameters
target: !goog.math.Size
The target size.
Returns
This Size object, after optional scaling.

Returns a nice string representing size.

Returns
In the form (50 x 73).

Instance Properties

Static Functions

Compares sizes for equality.

Parameters
a: goog.math.Size
A Size.
b: goog.math.Size
A Size.
Returns
True iff the sizes have equal widths and equal + heights, or if both are null.
\ No newline at end of file diff --git a/docs/api/javascript/class_goog_net_DefaultXmlHttpFactory.html b/docs/api/javascript/class_goog_net_DefaultXmlHttpFactory.html index 926ca60f70604..054fd935d1e1d 100644 --- a/docs/api/javascript/class_goog_net_DefaultXmlHttpFactory.html +++ b/docs/api/javascript/class_goog_net_DefaultXmlHttpFactory.html @@ -1,4 +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 + 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/docs/api/javascript/class_goog_net_WrapperXmlHttpFactory.html b/docs/api/javascript/class_goog_net_WrapperXmlHttpFactory.html index aee1ef2e393a6..927086d689ed0 100644 --- a/docs/api/javascript/class_goog_net_WrapperXmlHttpFactory.html +++ b/docs/api/javascript/class_goog_net_WrapperXmlHttpFactory.html @@ -4,4 +4,4 @@ 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 + 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/docs/api/javascript/class_goog_net_XmlHttpFactory.html b/docs/api/javascript/class_goog_net_XmlHttpFactory.html index fb9ff8d08c40b..849e5eec4897f 100644 --- a/docs/api/javascript/class_goog_net_XmlHttpFactory.html +++ b/docs/api/javascript/class_goog_net_XmlHttpFactory.html @@ -1,4 +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 + factory should be used.

Instance Properties

Cache of options - we only actually call internalGetOptions once.

\ No newline at end of file diff --git a/docs/api/javascript/class_goog_structs_Map.html b/docs/api/javascript/class_goog_structs_Map.html index 161f995c9994d..68fa850f4d91c 100644 --- a/docs/api/javascript/class_goog_structs_Map.html +++ b/docs/api/javascript/class_goog_structs_Map.html @@ -25,4 +25,4 @@ 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 + '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/docs/api/javascript/class_goog_structs_Set.html b/docs/api/javascript/class_goog_structs_Set.html new file mode 100644 index 0000000000000..306ff303be1ff --- /dev/null +++ b/docs/api/javascript/class_goog_structs_Set.html @@ -0,0 +1,28 @@ +goog.structs.Set

Class goog.structs.Set.<T>

code »
All implemented interfaces:
goog.structs.Collection.<(T|null)>

A set that can contain both primitives and objects. Adding and removing + elements is O(1). Primitives are treated as identical if they have the same + type and convert to the same string. Objects are treated as identical only + if they are references to the same object. WARNING: A goog.structs.Set can + contain both 1 and (new Number(1)), because they are not the same. WARNING: + Adding (new Number(1)) twice will yield two distinct elements, because they + are two different objects. WARNING: Any object that is added to a + goog.structs.Set will be modified! Because goog.getUid() is used to + identify objects, every object in the set will be mutated.

Constructor

goog.structs.Set ( opt_values )
Parameters
opt_values: (Array.<T>|Object)=
Initial values to start with.
Show:

Instance Methods

Returns an iterator that iterates over the elements in this set.

Parameters
opt_keys: boolean=
This argument is ignored.
Returns
An iterator over the elements in this set.
code »add ( element )

Add a primitive or an object to the set.

Parameters
element: T
The primitive or object to add.

Adds all the values in the given collection to this set.

Parameters
col: (Array.<T>|goog.structs.Collection.<T>|Object)
A collection + containing the elements to add.

Removes all elements from this set.

Creates a shallow clone of this set.

Returns
A new set containing all the same elements as + this set.
code »contains ( element )boolean

Tests whether this set contains the given element.

Parameters
element: T
The primitive or object to test for.
Returns
True if this set contains the given element.

Tests whether this set contains all the values in a given collection. + Repeated elements in the collection are ignored, e.g. (new + goog.structs.Set([1, 2])).containsAll([1, 1]) is True.

Parameters
col: (goog.structs.Collection.<T>|Object)
A collection-like object.
Returns
True if the set contains all elements.

Finds all values that are present in this set and not in the given + collection.

Parameters
col: (Array.<T>|goog.structs.Collection.<T>|Object)
A collection.
Returns
A new set containing all the values + (primitives or objects) present in this set but not in the given + collection.

Tests whether the given collection consists of the same elements as this set, + regardless of order, without repetition. Primitives are treated as equal if + they have the same type and convert to the same string; objects are treated + as equal if they are references to the same object. This operation is O(n).

Parameters
col: (goog.structs.Collection.<T>|Object)
A collection.
Returns
True if the given collection consists of the same elements + as this set, regardless of order, without repetition.
Returns
The number of elements in the set.
code »getValues ( )!Array.<T>

Returns an array containing all the elements in this set.

Returns
An array containing all the elements in this set.

Finds all values that are present in both this set and the given collection.

Parameters
col: (Array.<S>|Object)
A collection.
Returns
A new set containing all the values + (primitives or objects) present in both this set and the given + collection.

Tests whether this set is empty.

Returns
True if there are no elements in this set.

Tests whether the given collection contains all the elements in this set. + Primitives are treated as equal if they have the same type and convert to the + same string; objects are treated as equal if they are references to the same + object. This operation is O(n).

Parameters
col: (goog.structs.Collection.<T>|Object)
A collection.
Returns
True if this set is a subset of the given collection.
code »remove ( element )boolean

Removes the given element from this set.

Parameters
element: T
The primitive or object to remove.
Returns
Whether the element was found and removed.

Removes all values in the given collection from this set.

Parameters
col: (Array.<T>|goog.structs.Collection.<T>|Object)
A collection + containing the elements to remove.

Instance Properties

Class for Hash Map datastructure.

Static Functions

Obtains a unique key for an element of the set. Primitives will yield the + same key if they have the same type and convert to the same string. Object + references will yield the same key only if they refer to the same object.

Parameters
val: *
Object or primitive value to get a key for.
Returns
A unique key for this value/object.
\ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_AsyncTestCase.html b/docs/api/javascript/class_goog_testing_AsyncTestCase.html new file mode 100644 index 0000000000000..22a3b14900c2c --- /dev/null +++ b/docs/api/javascript/class_goog_testing_AsyncTestCase.html @@ -0,0 +1,81 @@ +goog.testing.AsyncTestCase

Class goog.testing.AsyncTestCase

code »
goog.testing.TestCase
+  └ goog.testing.AsyncTestCase

A test case that is capable of running tests the contain asynchronous logic.

Constructor

goog.testing.AsyncTestCase ( opt_name )
Parameters
opt_name: string=
A descriptive name for the test case.

Classes

goog.testing.AsyncTestCase.ControlBreakingException
An exception class used solely for control flow.
Show:

Type Definitions

code »goog.testing.AsyncTestCase.TopStackFuncResult_ : {controlBreakingExceptionThrown: boolean, message: string}
Represents result of top stack function call.

Instance Methods

Defined in goog.testing.AsyncTestCase

Calls the given function, redirecting any exceptions to doAsyncError.

Parameters
func: Function
The function to call.
Returns
Returns a + TopStackFuncResult_.

Continue with the next step in the test cycle.

Starts the tests.

code »dbgLog_ ( message )

Logs the given debug message to the console (when enabled).

Parameters
message: string
The message to log.

Handles an exception thrown by a test.

Parameters
opt_e: *=
The exception object associated with the failure + or a string.
Throws
throws a ControlBreakingException.

Calls the tearDown function, catching any errors, and then moves on to + the next step in the testing cycle.

Step 3: Call test.execute().

Step 1: Move to the next test.

Step 5: Call doSuccess()

Sets up the test page and then waits untill the test case has been marked + as ready before executing the tests.

Step 2: Call setUp().

Step 4: Call tearDown().

Wraps doAsyncError() for when we are sure that the test runner has no user + code above it in the stack.

Parameters
opt_e: (string|Error)=
The exception object associated with the + failure or a string.

Enables verbose logging of what is happening inside of the AsyncTestCase.

Ends the current test step and queues the next test step to run.

Finalizes the test case, called when the tests have finished executing.

The current step name.

Returns
Step name.

Replaces the asserts.js assert_() and fail() functions with a wrappers to + catch the exceptions.

Sets a window.onerror handler for catching exceptions that happen in async + callbacks. Note that as of Safari 3.1, Safari does not support this.

code »pump_ ( opt_doFirst )

Calls the next callback when the isReady_ flag is true.

Parameters
opt_doFirst: Function=
A function to call before pumping.
Throws
a ControlBreakingException if there were any failing steps.

Sets up the test page and then waits until the test case has been marked + as ready before executing the tests.

code »setNextStep_ ( func, name )

Sets the next function to call in our sequence of async callbacks.

Parameters
func: Function
The function that executes the next step.
name: string
A description of the next step.

Signals once to continue with the test. If this is the last signal that the + test was waiting on, call continueTesting.

Enables the timeout timer. This timer fires unless continueTesting is + called.

Disables the timeout timer.

Unhooks window.onerror and _assert.

code »waitForAsync ( opt_name )

Informs the testcase not to continue to the next step in the test cycle + until continueTesting is called.

Parameters
opt_name: string=
A description of what we are waiting for.
code »waitForSignals ( times, opt_name )

Informs the testcase not to continue to the next step in the test cycle + until signal is called the specified number of times. Within a test, this + function behaves additively if called multiple times; the number of signals + to wait for will be the sum of all expected number of signals this function + was called with.

Parameters
times: number
The number of signals to receive before + continuing testing.
opt_name: string=
A description of what we are waiting for.

Defined in goog.testing.TestCase

code »add ( test )

Adds a new test to the test case.

Parameters
test: goog.testing.TestCase.Test
The test to add.
code »addNewTest ( name, ref, opt_scope )

Creates and adds a new test. + + Convenience function to make syntax less awkward when not using automatic + test discovery.

Parameters
name: string
The test name.
ref: !Function
Reference to the test function.
opt_scope: !Object=
Optional scope that the test function should be + called in.

Adds any functions defined in the global scope that correspond to + lifecycle events for the test case. Overrides setUp, tearDown, setUpPage, + tearDownPage and runTests if they are defined.

Adds any functions defined in the global scope that are prefixed with "test" + to the test case.

Clears a timeout created by this.timeout().

Parameters
id: number
A timeout id.

Counts the number of files that were loaded for dependencies that are + required to run the test.

Returns
The number of files loaded.

Creates a goog.testing.TestCase.Test from an auto-discovered + function.

Parameters
name: string
The name of the function.
ref: function(): void
The auto-discovered function.
Returns
The newly created test.
code »doError ( test, opt_e )

Handles a test that failed.

Parameters
test: goog.testing.TestCase.Test
The test that failed.
opt_e: *=
The exception object associated with the + failure or a string.

Handles a test that passed.

Parameters
test: goog.testing.TestCase.Test
The test that passed.

Executes each of the tests.

Returns the number of tests actually run in the test case, i.e. subtracting + any which are skipped.

Returns
The number of un-ignored tests.
Returns
The function name prefix used to auto-discover tests.
Returns
Time since the last batch of tests was started.

Returns the number of tests contained in the test case.

Returns
The number of tests.
code »getGlobals ( opt_prefix )!Array

Gets list of objects that potentially contain test cases. For IE 8 and below, + this is the global "this" (for properties set directly on the global this or + window) and the RuntimeObject (for global variables and functions). For all + other browsers, the array simply contains the global this.

Parameters
opt_prefix: string=
An optional prefix. If specified, only get things + under this prefix. Note that the prefix is only honored in IE, since it + supports the RuntimeObject: + http://msdn.microsoft.com/en-us/library/ff521039%28VS.85%29.aspx + TODO: Remove this option.
Returns
A list of objects that should be inspected.
Returns
The name of the test.

Returns the number of script files that were loaded in order to run the test.

Returns
The number of script files.
code »getReport ( opt_verbose )string

Returns a string detailing the results from the test.

Parameters
opt_verbose: boolean=
If true results will include data about all + tests, not just what failed.
Returns
The results from the test.

Returns the amount of time it took for the test to run.

Returns
The run time, in milliseconds.

Returns the test results object: a map from test names to a list of test + failures (if any exist).

Returns
Tests results object.

Gets the tests.

Returns
The test array.

Returns the current time.

Returns
HH:MM:SS.
Returns
Whether the test case is running inside the multi test + runner.
Returns
Whether the test was a success.
code »log ( val )

Logs an object to the console, if available.

Parameters
val: *
The value to log. Will be ToString'd.
Parameters
name: string
Failed test name.
opt_e: *=
The exception object associated with the + failure or a string.
Returns
Error object.

Checks to see if the test should be marked as failed before it is run. + + If there was an error in setUpPage, we treat that as a failure for all tests + and mark them all as having failed.

Parameters
testCase: goog.testing.TestCase.Test
The current test case.
Returns
Whether the test was marked as failed.

Returns the current test and increments the pointer.

Returns
The current test case.
Returns
The current time in milliseconds, don't use goog.now as some + tests override it.

Reorders the tests depending on the order field.

Parameters
tests: Array.<goog.testing.TestCase.Test>
An array of tests to + reorder.
code »pad_ ( number )string

Pads a number to make it have a leading zero if it's less than 10.

Parameters
number: number
The number to pad.
Returns
The resulting string.

Resets the test case pointer, so that next returns the first test.

code »saveMessage ( message )

Saves a message to the result set.

Parameters
message: string
The message to save.
code »setBatchTime ( batchTime )
Parameters
batchTime: number
Time since the last batch of tests was started.

Sets the callback function that should be executed when the tests have + completed.

Parameters
fn: Function
The callback function.
code »setTests ( tests )

Sets the tests.

Parameters
tests: !Array.<goog.testing.TestCase.Test>
A new test array.

Gets called before every goog.testing.TestCase.Test is been executed. Can be + overridden to add set up functionality to each test.

Gets called before any tests are executed. Can be overridden to set up the + environment for the whole test case.

Can be overridden in test classes to indicate whether the tests in a case + should be run in that particular situation. For example, this could be used + to stop tests running in a particular browser, where browser support for + the class under test was absent.

Returns
Whether any of the tests in the case should be run.

Gets called after every goog.testing.TestCase.Test has been executed. Can be + overriden to add tear down functionality to each test.

Gets called after all tests have been executed. Can be overridden to tear + down the entire test case.

code »timeout ( fn, time )number

Calls a function after a delay, using the protected timeout.

Parameters
fn: Function
The function to call.
time: number
Delay in milliseconds.
Returns
The timeout id.

Trims a path to be only that after google3.

Parameters
path: string
The path to trim.
Returns
The resulting string.

Instance Properties

Defined in goog.testing.AsyncTestCase

Marks if the cleanUp() function has been called for the currently running + test.

The stage of the test we are currently on.

The name of the stage of the test we are currently on.

Turn on extra logging to help debug failing async. tests.

Number of signals to wait for before continuing testing when waitForSignals + is used.

A flag to prevent recursive exception handling.

Flag used to determine if we can move to the next step in the testing loop.

The stage of the test we should run next.

The name of the stage of the test we should run next.

The number of times we have thrown a ControlBreakingException so that we + know not to complain in our window.onerror handler. In Webkit, window.onerror + is not supported, and so this counter will keep going up but we won't care + about it.

A reference to the original window.onerror function.

Number of signals received.

Flag that tells us if there is a function in the call stack that will make + a call to pump_().

How long to wait for a single step of a test to complete in milliseconds. + A step starts when a call to waitForAsync() is made.

How long to wait after a failed test before moving onto the next one. + The purpose of this is to allow any pending async callbacks from the failing + test to finish up and not cause the next test to fail.

The handle to the current setTimeout timer.

Defined in goog.testing.TestCase

Time since the last batch of tests was started, if batchTime exceeds + #maxRunTime a timeout will be used to stop the tests blocking the + browser and a new batch will be started.

Pointer to the current test.

Exception object that was detected before a test runs.

A name for the test case.

Optional callback that will be executed when the test has finalized.

The order to run the auto-discovered tests in.

Object used to encapsulate the test results.

Whether the test case is running.

Timestamp for when the test was started.

Whether the test case has ever tried to execute.

Set of test names and/or indices to execute, or null if all tests should + be executed. + + Indices are included to allow automation tools to run a subset of the + tests without knowing the exact contents of the test file. + + Indices should only be used with SORTED ordering. + + Example valid values: +

    +
  • [testName] +
  • [testName1, testName2] +
  • [2] - will run the 3rd test in the order specified +
  • [1,3,5] +
  • [testName1, testName2, 3, 5] - will work +

    Array of test functions that can be executed.

    Static Functions

    Preferred way of creating an AsyncTestCase. Creates one and initializes it + with the G_testRunner.

    Parameters
    opt_name: string=
    A descriptive name for the test case.
    Returns
    The created AsyncTestCase.

    Static Properties

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_AsyncTestCase_ControlBreakingException.html b/docs/api/javascript/class_goog_testing_AsyncTestCase_ControlBreakingException.html new file mode 100644 index 0000000000000..1336ae2689c18 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_AsyncTestCase_ControlBreakingException.html @@ -0,0 +1 @@ +goog.testing.AsyncTestCase.ControlBreakingException

    Class goog.testing.AsyncTestCase.ControlBreakingException

    code »

    An exception class used solely for control flow.

    Constructor

    goog.testing.AsyncTestCase.ControlBreakingException ( opt_message )
    Parameters
    opt_message: string=
    Error message.
    Show:

    Instance Methods

    code »toString ( )string

    Instance Properties

    Marks this object as a ControlBreakingException

    The exception message.

    Static Properties

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_FunctionCall.html b/docs/api/javascript/class_goog_testing_FunctionCall.html new file mode 100644 index 0000000000000..1b6b6e8254f1d --- /dev/null +++ b/docs/api/javascript/class_goog_testing_FunctionCall.html @@ -0,0 +1,2 @@ +goog.testing.FunctionCall

    Class goog.testing.FunctionCall

    code »

    Struct for a single function call.

    Constructor

    goog.testing.FunctionCall ( func, thisContext, args, ret, error )
    Parameters
    func: !Function
    The called function.
    thisContext: !Object
    this context of called function.
    args: !Arguments
    Arguments of the called function.
    ret: *
    Return value of the function or undefined in case of error.
    error: *
    The error thrown by the function or null if none.
    Show:

    Instance Methods

    code »getArgument ( index )*

    Returns the nth argument of the called function.

    Parameters
    index: number
    0-based index of the argument.
    Returns
    The argument value or undefined if there is no such argument.
    Returns
    Arguments of the called function.
    code »getError ( )*
    Returns
    The error thrown by the function or null if none.
    Returns
    The called function.
    Returns
    Return value of the function or undefined in case of error.
    Returns
    this context of called function. It is the same as + the created object if the function is a constructor.

    Instance Properties

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_JsUnitException.html b/docs/api/javascript/class_goog_testing_JsUnitException.html new file mode 100644 index 0000000000000..2b0f8ae5acde7 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_JsUnitException.html @@ -0,0 +1,2 @@ +goog.testing.JsUnitException

    Class goog.testing.JsUnitException

    code »
    Error
    +  └ goog.testing.JsUnitException

    Constructor

    goog.testing.JsUnitException ( comment, opt_message )
    Parameters
    comment: string
    A summary for the exception.
    opt_message: ?string=
    A description of the exception.
    Show:

    Instance Methods

    Defined in goog.testing.JsUnitException

    code »toString ( )string

    Instance Properties

    Defined in goog.testing.JsUnitException

    code »comment : (null|string)

    Static Properties

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_LooseExpectationCollection.html b/docs/api/javascript/class_goog_testing_LooseExpectationCollection.html new file mode 100644 index 0000000000000..cf6bd5247927b --- /dev/null +++ b/docs/api/javascript/class_goog_testing_LooseExpectationCollection.html @@ -0,0 +1,4 @@ +goog.testing.LooseExpectationCollection

    Class goog.testing.LooseExpectationCollection

    code »

    This class is an ordered collection of expectations for one method. Since + the loose mock does most of its verification at the time of $verify, this + class is necessary to manage the return/throw behavior when the mock is + being called.

    Constructor

    goog.testing.LooseExpectationCollection ( )
    Show:

    Instance Methods

    code »addExpectation ( expectation )

    Adds an expectation to this collection.

    Parameters
    expectation: goog.testing.MockExpectation
    The expectation to add.

    Gets the list of expectations in this collection.

    Returns
    The array of expectations.

    Instance Properties

    The list of expectations. All of these should have the same name.

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_LooseMock.html b/docs/api/javascript/class_goog_testing_LooseMock.html new file mode 100644 index 0000000000000..c08bb544fc8bd --- /dev/null +++ b/docs/api/javascript/class_goog_testing_LooseMock.html @@ -0,0 +1,25 @@ +goog.testing.LooseMock

    Class goog.testing.LooseMock

    code »
    goog.testing.Mock
    +  └ goog.testing.LooseMock
    All implemented interfaces:
    goog.testing.MockInterface

    This is a mock that does not care about the order of method calls. As a + result, it won't throw exceptions until verify() is called. The only + exception is that if a method is called that has no expectations, then an + exception will be thrown.

    Constructor

    goog.testing.LooseMock ( objectToMock, opt_ignoreUnexpectedCalls, opt_mockStaticMethods, opt_createProxy )
    Parameters
    objectToMock: (Object|Function)
    The object that should be mocked, or + the constructor of an object to mock.
    opt_ignoreUnexpectedCalls: boolean=
    Whether to ignore unexpected + calls.
    opt_mockStaticMethods: boolean=
    An optional argument denoting that + a mock should be constructed from the static functions of a class.
    opt_createProxy: boolean=
    An optional argument denoting that + a proxy for the target mock should be created.
    Show:

    Instance Methods

    Defined in goog.testing.LooseMock

    code »$recordCall ( name, args )*
    Parameters
    name
    args

    A setter for the ignoreUnexpectedCalls field.

    Parameters
    ignoreUnexpectedCalls: boolean
    Whether to ignore unexpected calls.
    Returns
    This mock object.

    Defined in goog.testing.Mock

    Allows the expectation to be called any number of times.

    Returns
    This mock object.

    Render the provided argument array to a string to help + clients with debugging tests.

    Parameters
    args: ?Array
    The arguments passed to the mock.
    Returns
    Human-readable string.

    Allows the expectation to be called any number of times, as long as it's + called once.

    Returns
    This mock object.

    Allows the expectation to be called 0 or 1 times.

    Returns
    This mock object.
    code »$do ( expectation, args )*

    If this expectation defines a function to be called, + it will be called and its result will be returned. + Otherwise, if the expectation expects to throw, it will throw. + Otherwise, this method will return defined value.

    Parameters
    expectation: goog.testing.MockExpectation
    The expectation.
    args: Array
    The arguments to the method.
    Returns
    The return value expected by the mock.

    Specifies a function to call for currently pending expectation. + Note, that using this method overrides declarations made + using $returns() and $throws() methods.

    Parameters
    func: Function
    The function to call.
    Returns
    This mock object.

    Initializes the functions on the mock object.

    Parameters
    objectToMock: Object
    The object being mocked.
    code »$maybeThrow ( expectation )

    If the expectation expects to throw, this method will throw.

    Parameters
    expectation: goog.testing.MockExpectation
    The expectation.
    code »$mockMethod ( name )*

    The function that replaces all methods on the mock object.

    Parameters
    name: string
    The name of the method being mocked.
    Returns
    In record mode, returns the mock object. In replay mode, returns + whatever the creator of the mock set as the return value.

    Disallows the expectation from being called.

    Returns
    This mock object.

    Allows the expectation to be called exactly once.

    Returns
    This mock object.

    Throws an exception and records that an exception was thrown.

    Parameters
    ex: Object
    Exception.
    Throws
    Object
    #ex.

    Registers a verfifier function to use when verifying method argument lists.

    Parameters
    methodName: string
    The name of the method for which the verifierFn + should be used.
    fn: Function
    Argument list verifier function. Should take 2 argument + arrays as arguments, and return true if they are considered equivalent.
    Returns
    This mock object.

    Specifies a return value for the currently pending expectation.

    Parameters
    val: *
    The return value.
    Returns
    This mock object.
    code »$throwCallException ( name, args, opt_expectation )

    Throw an exception based on an incorrect method call.

    Parameters
    name: string
    Name of method called.
    args: ?Array
    Arguments passed to the mock.
    opt_expectation: goog.testing.MockExpectation=
    Expected next call, + if any.
    code »$throwException ( comment, opt_message )

    Throws an exception and records that an exception was thrown.

    Parameters
    comment: string
    A short comment about the exception.
    opt_message: ?string=
    A longer message about the exception.
    Throws
    Object
    JsUnitException object.

    Specifies a value for the currently pending expectation to throw.

    Parameters
    val: *
    The value to throw.
    Returns
    This mock object.

    Specifies the number of times the expectation should be called.

    Parameters
    times: number
    The number of times this method will be called.
    Returns
    This mock object.
    code »$verifyCall ( expectation, name, args )boolean

    Verifies that a method call matches an expectation.

    Parameters
    expectation: goog.testing.MockExpectation
    The expectation to check.
    name: string
    The name of the called method.
    args: ?Array
    The arguments passed to the mock.
    Returns
    Whether the call matches the expectation.

    Instance Properties

    Defined in goog.testing.LooseMock

    The calls that have been made; we cache them to verify at the end. Each + element is an array where the first element is the name, and the second + element is the arguments.

    A map of method names to a LooseExpectationCollection for that method.

    Whether to ignore unexpected calls.

    Defined in goog.testing.Mock

    Map of argument name to optional argument list verifier function.

    The expectation currently being created. All methods that modify the + current expectation return the Mock object for easy chaining, so this is + where we keep track of the expectation that's currently being modified.

    A proxy for the mock. This can be used for dependency injection in lieu of + the mock if the test requires a strict instanceof check.

    Whether or not we are in recording mode.

    First exception thrown by this mock; used in $verify.

    Static Properties

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_Mock.html b/docs/api/javascript/class_goog_testing_Mock.html new file mode 100644 index 0000000000000..6cfe20de9e347 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_Mock.html @@ -0,0 +1,29 @@ +goog.testing.Mock

    Class goog.testing.Mock

    code »
    All implemented interfaces:
    goog.testing.MockInterface

    The base class for a mock object.

    Constructor

    goog.testing.Mock ( objectToMock, opt_mockStaticMethods, opt_createProxy )
    Parameters
    objectToMock: (Object|Function)
    The object that should be mocked, or + the constructor of an object to mock.
    opt_mockStaticMethods: boolean=
    An optional argument denoting that + a mock should be constructed from the static functions of a class.
    opt_createProxy: boolean=
    An optional argument denoting that + a proxy for the target mock should be created.
    Show:

    Instance Methods

    Allows the expectation to be called any number of times.

    Returns
    This mock object.

    Render the provided argument array to a string to help + clients with debugging tests.

    Parameters
    args: ?Array
    The arguments passed to the mock.
    Returns
    Human-readable string.

    Allows the expectation to be called any number of times, as long as it's + called once.

    Returns
    This mock object.

    Allows the expectation to be called 0 or 1 times.

    Returns
    This mock object.
    code »$do ( expectation, args )*

    If this expectation defines a function to be called, + it will be called and its result will be returned. + Otherwise, if the expectation expects to throw, it will throw. + Otherwise, this method will return defined value.

    Parameters
    expectation: goog.testing.MockExpectation
    The expectation.
    args: Array
    The arguments to the method.
    Returns
    The return value expected by the mock.

    Specifies a function to call for currently pending expectation. + Note, that using this method overrides declarations made + using $returns() and $throws() methods.

    Parameters
    func: Function
    The function to call.
    Returns
    This mock object.

    Initializes the functions on the mock object.

    Parameters
    objectToMock: Object
    The object being mocked.
    code »$maybeThrow ( expectation )

    If the expectation expects to throw, this method will throw.

    Parameters
    expectation: goog.testing.MockExpectation
    The expectation.
    code »$mockMethod ( name )*

    The function that replaces all methods on the mock object.

    Parameters
    name: string
    The name of the method being mocked.
    Returns
    In record mode, returns the mock object. In replay mode, returns + whatever the creator of the mock set as the return value.

    Disallows the expectation from being called.

    Returns
    This mock object.

    Allows the expectation to be called exactly once.

    Returns
    This mock object.

    Throws an exception and records that an exception was thrown.

    Parameters
    ex: Object
    Exception.
    Throws
    Object
    #ex.
    code »$recordCall ( name, args )*

    Records an actual method call, intended to be overridden by a + subclass. The subclass must find the pending expectation and return the + correct value.

    Parameters
    name: string
    The name of the method being called.
    args: Array
    The arguments to the method.
    Returns
    The return expected by the mock.

    Records the currently pending expectation, intended to be overridden by a + subclass.

    Registers a verfifier function to use when verifying method argument lists.

    Parameters
    methodName: string
    The name of the method for which the verifierFn + should be used.
    fn: Function
    Argument list verifier function. Should take 2 argument + arrays as arguments, and return true if they are considered equivalent.
    Returns
    This mock object.

    Switches from recording to replay mode.

    Resets the state of this mock object. This clears all pending expectations + without verifying, and puts the mock in recording mode.

    Specifies a return value for the currently pending expectation.

    Parameters
    val: *
    The return value.
    Returns
    This mock object.
    code »$throwCallException ( name, args, opt_expectation )

    Throw an exception based on an incorrect method call.

    Parameters
    name: string
    Name of method called.
    args: ?Array
    Arguments passed to the mock.
    opt_expectation: goog.testing.MockExpectation=
    Expected next call, + if any.
    code »$throwException ( comment, opt_message )

    Throws an exception and records that an exception was thrown.

    Parameters
    comment: string
    A short comment about the exception.
    opt_message: ?string=
    A longer message about the exception.
    Throws
    Object
    JsUnitException object.

    Specifies a value for the currently pending expectation to throw.

    Parameters
    val: *
    The value to throw.
    Returns
    This mock object.

    Specifies the number of times the expectation should be called.

    Parameters
    times: number
    The number of times this method will be called.
    Returns
    This mock object.

    Verify that all of the expectations were met. Should be overridden by + subclasses.

    code »$verifyCall ( expectation, name, args )boolean

    Verifies that a method call matches an expectation.

    Parameters
    expectation: goog.testing.MockExpectation
    The expectation to check.
    name: string
    The name of the called method.
    args: ?Array
    The arguments passed to the mock.
    Returns
    Whether the call matches the expectation.

    Instance Properties

    Map of argument name to optional argument list verifier function.

    The expectation currently being created. All methods that modify the + current expectation return the Mock object for easy chaining, so this is + where we keep track of the expectation that's currently being modified.

    A proxy for the mock. This can be used for dependency injection in lieu of + the mock if the test requires a strict instanceof check.

    Whether or not we are in recording mode.

    First exception thrown by this mock; used in $verify.

    Static Properties

    Option that may be passed when constructing function, method, and + constructor mocks. Indicates that the expected calls should be accepted in + any order.

    This array contains the name of the functions that are part of the base + Object prototype. + Basically a copy of goog.object.PROTOTYPE_FIELDS_.

    Option that may be passed when constructing function, method, and + constructor mocks. Indicates that the expected calls should be accepted in + the recorded order only.

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_MockClock.html b/docs/api/javascript/class_goog_testing_MockClock.html new file mode 100644 index 0000000000000..894cd5571a925 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_MockClock.html @@ -0,0 +1,66 @@ +goog.testing.MockClock

    Class goog.testing.MockClock

    code »
    goog.Disposable
    +  └ goog.testing.MockClock
    All implemented interfaces:
    goog.disposable.IDisposable

    Class for unit testing code that uses setTimeout and clearTimeout. + + NOTE: If you are using MockClock to test code that makes use of + goog.fx.Animation, then you must either: + + 1. Install and dispose of the MockClock in setUpPage() and tearDownPage() + respectively (rather than setUp()/tearDown()). + + or + + 2. Ensure that every test clears the animation queue by calling + mockClock.tick(x) at the end of each test function (where `x` is large + enough to complete all animations). + + Otherwise, if any animation is left pending at the time that + MockClock.dispose() is called, that will permanently prevent any future + animations from playing on the page.

    Constructor

    goog.testing.MockClock ( opt_autoInstall )
    Parameters
    opt_autoInstall: boolean=
    Install the MockClock at construction time.
    Show:

    Instance Methods

    Defined in goog.testing.MockClock

    Clears a requestAnimationFrame. + Mock implementation for cancelRequestAnimationFrame.

    Parameters
    timeoutKey: number
    The requestAnimationFrame key to clear.
    code »clearInterval_ ( timeoutKey )

    Clears an interval. + Mock implementation for clearInterval.

    Parameters
    timeoutKey: number
    The interval key to clear.
    code »clearTimeout_ ( timeoutKey )

    Clears a timeout. + Mock implementation for clearTimeout.

    Parameters
    timeoutKey: number
    The timeout key to clear.

    Signals that the mock clock has been reset, allowing objects that + maintain their own internal state to reset.

    Returns
    The MockClock's current time in milliseconds.
    Returns
    delay The amount of time between when a timeout is + scheduled to fire and when it actually fires, in milliseconds. May + be negative.
    Returns
    The number of timeouts that have been scheduled.

    Installs the MockClock by overriding the global object's implementation of + setTimeout, setInterval, clearTimeout and clearInterval.

    code »isTimeoutSet ( timeoutKey )boolean
    Parameters
    timeoutKey: number
    The timeout key.
    Returns
    Whether the timer has been set and not cleared, + independent of the timeout's expiration. In other words, the timeout + could have passed or could be scheduled for the future. Either way, + this function returns true or false depending only on whether the + provided timeoutKey represents a timeout that has been set and not + cleared.

    Installs the mocks for requestAnimationFrame and cancelRequestAnimationFrame.

    Schedules a function to be called when an animation frame is triggered. + Mock implementation for requestAnimationFrame.

    Parameters
    funcToCall: Function
    The function to call.
    Returns
    The number of timeouts created.

    Resets the MockClock, removing all timeouts that are scheduled and resets + the fake timer count.

    Runs any function that is scheduled before a certain time. Timeouts can + be made to fire early or late if timeoutDelay_ is non-0.

    Parameters
    endTime: number
    The latest time in the range, in milliseconds.
    code »scheduleFunction_ ( timeoutKey, funcToCall, millis, recurring )

    Schedules a function to be run at a certain time.

    Parameters
    timeoutKey: number
    The timeout key.
    funcToCall: Function
    The function to call.
    millis: number
    The number of milliseconds to call it in.
    recurring: boolean
    Whether to function call should recur.
    code »setImmediate_ ( funcToCall )number

    Schedules a function to be called immediately after the current JS + execution. + Mock implementation for setImmediate.

    Parameters
    funcToCall: Function
    The function to call.
    Returns
    The number of timeouts created.
    code »setInterval_ ( funcToCall, millis )number

    Schedules a function to be called every millis milliseconds. + Mock implementation for setInterval.

    Parameters
    funcToCall: Function
    The function to call.
    millis: number
    The number of milliseconds between calls.
    Returns
    The number of timeouts created.

    Sets the amount of time between when a timeout is scheduled to fire and when + it actually fires.

    Parameters
    delay: number
    The delay in milliseconds. May be negative.
    code »setTimeout_ ( funcToCall, millis )number

    Schedules a function to be called after millis milliseconds. + Mock implementation for setTimeout.

    Parameters
    funcToCall: Function
    The function to call.
    millis: number
    The number of milliseconds to call it after.
    Returns
    The number of timeouts created.
    code »tick ( opt_millis )number

    Increments the MockClock's time by a given number of milliseconds, running + any functions that are now overdue.

    Parameters
    opt_millis: number=
    Number of milliseconds to increment the counter. + If not specified, clock ticks 1 millisecond.
    Returns
    Current mock time in milliseconds.

    Removes the MockClock's hooks into the global object's functions and revert + to their original values.

    Defined in goog.Disposable

    code »<T> addOnDisposeCallback ( callback, opt_scope )

    Invokes a callback function when this object is disposed. Callbacks are + invoked in the order in which they were added.

    Parameters
    callback: function(this: T): ?
    The callback function.
    opt_scope: T=
    An optional scope to call the callback in.
    code »dispose ( )void

    Disposes of the object. If the object hasn't already been disposed of, calls + #disposeInternal. Classes that extend goog.Disposable should + override #disposeInternal in order to delete references to COM + objects, DOM nodes, and other disposable objects. Reentrant.

    Returns
    Nothing.
    Deprecated: Use #isDisposed instead.
    Returns
    Whether the object has been disposed of.
    Returns
    Whether the object has been disposed of.

    Associates a disposable object with this object so that they will be disposed + together.

    Parameters
    disposable: goog.disposable.IDisposable
    that will be disposed when + this object is disposed.

    Instance Properties

    Defined in goog.testing.MockClock

    Map of deleted keys. These keys represents keys that were deleted in a + clearInterval, timeoutid -> object.

    The current simulated time in milliseconds.

    Reverse-order queue of timers to fire. + + The last item of the queue is popped off. Insertion happens from the + right. For example, the expiration times for each element of the queue + might be in the order 300, 200, 200.

    PropertyReplacer instance which overwrites and resets setTimeout, + setInterval, etc. or null if the MockClock is not installed.

    Additional delay between the time a timeout was set to fire, and the time + it actually fires. Useful for testing workarounds for this Firefox 2 bug: + https://bugzilla.mozilla.org/show_bug.cgi?id=291386 + May be negative.

    Count of the number of timeouts made.

    Defined in goog.Disposable

    If monitoring the goog.Disposable instances is enabled, stores the creation + stack trace of the Disposable instance.

    Whether the object has been disposed of.

    Callbacks to invoke when this object is disposed.

    Static Functions

    Inserts a timer descriptor into a descending-order queue. + + Later-inserted duplicates appear at lower indices. For example, the + asterisk in (5,4,*,3,2,1) would be the insertion point for 3.

    Parameters
    timeout: Object
    The timeout to insert, with numerical runAtMillis + property.
    queue: Array.<Object>
    The queue to insert into, with each element + having a numerical runAtMillis property.

    Static Properties

    Maximum 32-bit signed integer. + + Timeouts over this time return immediately in many browsers, due to integer + overflow. Such known browsers include Firefox, Chrome, and Safari, but not + IE.

    Default wait timeout for mocking requestAnimationFrame (in milliseconds).

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_MockControl.html b/docs/api/javascript/class_goog_testing_MockControl.html new file mode 100644 index 0000000000000..661a96c45bd99 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_MockControl.html @@ -0,0 +1,22 @@ +goog.testing.MockControl

    Class goog.testing.MockControl

    code »

    Controls a set of mocks. Controlled mocks are replayed, verified, and + cleaned-up at the same time.

    Constructor

    goog.testing.MockControl ( )
    Show:

    Instance Methods

    Calls replay on each controlled mock.

    Calls reset on each controlled mock.

    Calls tearDown on each controlled mock, if necesssary.

    Calls verify on each controlled mock.

    Takes control of this mock.

    Parameters
    mock: goog.testing.MockInterface
    Mock to be controlled.
    Returns
    The same mock passed in, + for convenience.
    code »createConstructorMock ( scope, constructorName, opt_strictness )!goog.testing.MockInterface

    Creates a controlled MethodMock for a constructor. Passes its arguments + through to the MethodMock constructor. See + goog.testing.createConstructorMock for details.

    Parameters
    scope: Object
    The scope of the constructor to be mocked out.
    constructorName: string
    The name of the function we're going to mock.
    opt_strictness: number=
    One of goog.testing.Mock.LOOSE or + goog.testing.Mock.STRICT. The default is STRICT.
    Returns
    The mocked method.
    code »createFunctionMock ( opt_functionName, opt_strictness )goog.testing.MockInterface

    Creates a controlled FunctionMock. Passes its arguments through to the + FunctionMock constructor.

    Parameters
    opt_functionName: string=
    The optional name of the function to mock + set to '[anonymous mocked function]' if not passed in.
    opt_strictness: number=
    One of goog.testing.Mock.LOOSE or + goog.testing.Mock.STRICT. The default is STRICT.
    Returns
    The mocked function.
    code »createGlobalFunctionMock ( functionName, opt_strictness )goog.testing.MockInterface

    Creates a controlled GlobalFunctionMock. Passes its arguments through to the + GlobalFunctionMock constructor.

    Parameters
    functionName: string
    The name of the function we're going to mock.
    opt_strictness: number=
    One of goog.testing.Mock.LOOSE or + goog.testing.Mock.STRICT. The default is STRICT.
    Returns
    The mocked function.
    code »createLooseMock ( objectToMock, opt_ignoreUnexpectedCalls, opt_mockStaticMethods, opt_createProxy )!goog.testing.LooseMock

    Creates a controlled LooseMock. Passes its arguments through to the + LooseMock constructor.

    Parameters
    objectToMock: (Object|Function)
    The object that should be mocked, or + the constructor of an object to mock.
    opt_ignoreUnexpectedCalls: boolean=
    Whether to ignore unexpected + calls.
    opt_mockStaticMethods: boolean=
    An optional argument denoting that + a mock should be constructed from the static functions of a class.
    opt_createProxy: boolean=
    An optional argument denoting that + a proxy for the target mock should be created.
    Returns
    The mock object.
    code »createMethodMock ( scope, functionName, opt_strictness )!goog.testing.MockInterface

    Creates a controlled MethodMock. Passes its arguments through to the + MethodMock constructor.

    Parameters
    scope: Object
    The scope of the method to be mocked out.
    functionName: string
    The name of the function we're going to mock.
    opt_strictness: number=
    One of goog.testing.Mock.LOOSE or + goog.testing.Mock.STRICT. The default is STRICT.
    Returns
    The mocked method.
    code »createStrictMock ( objectToMock, opt_mockStaticMethods, opt_createProxy )!goog.testing.StrictMock

    Creates a controlled StrictMock. Passes its arguments through to the + StrictMock constructor.

    Parameters
    objectToMock: (Object|Function)
    The object that should be mocked, or + the constructor of an object to mock.
    opt_mockStaticMethods: boolean=
    An optional argument denoting that + a mock should be constructed from the static functions of a class.
    opt_createProxy: boolean=
    An optional argument denoting that + a proxy for the target mock should be created.
    Returns
    The mock object.

    Instance Properties

    The list of mocks being controlled.

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_MockExpectation.html b/docs/api/javascript/class_goog_testing_MockExpectation.html new file mode 100644 index 0000000000000..261918026d807 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_MockExpectation.html @@ -0,0 +1,3 @@ +goog.testing.MockExpectation

    Class goog.testing.MockExpectation

    code »

    This is a class that represents an expectation.

    Constructor

    goog.testing.MockExpectation ( name )
    Parameters
    name: string
    The name of the method for this expectation.
    Show:

    Instance Methods

    Allow expectation failures to include messages.

    Parameters
    message: string
    The failure message.

    Get the error messages seen so far.

    Returns
    Error messages separated by \n.

    Get how many error messages have been seen so far.

    Returns
    Count of error messages.

    Instance Properties

    The number of times this method is called by real code.

    The arguments that are expected to be passed to this function

    An array of error messages for expectations not met.

    The value that will be thrown when the method is called

    The maximum number of times this method should be called.

    The minimum number of times this method should be called.

    The name of the method that is expected to be called.

    The value that this method should return.

    The function which will be executed when this method is called. + Method arguments will be passed to this function, and return value + of this function will be returned by the method.

    The number of times this method is called during the verification phase.

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_ObjectPropertyString.html b/docs/api/javascript/class_goog_testing_ObjectPropertyString.html new file mode 100644 index 0000000000000..4195cc7e764d0 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_ObjectPropertyString.html @@ -0,0 +1,3 @@ +goog.testing.ObjectPropertyString

    Class goog.testing.ObjectPropertyString

    code »

    Object to pass a property name as a string literal and its containing object + when the JSCompiler is rewriting these names. This should only be used in + test code.

    Constructor

    goog.testing.ObjectPropertyString ( object, propertyString )
    Parameters
    object: Object
    The containing object.
    propertyString: (Object|string)
    Property name as a string literal.
    Show:

    Instance Methods

    Returns
    The object.
    Returns
    The property string.

    Instance Properties

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_PropertyReplacer.html b/docs/api/javascript/class_goog_testing_PropertyReplacer.html new file mode 100644 index 0000000000000..14dd9134cab3e --- /dev/null +++ b/docs/api/javascript/class_goog_testing_PropertyReplacer.html @@ -0,0 +1,46 @@ +goog.testing.PropertyReplacer

    Class goog.testing.PropertyReplacer

    code »

    Helper class for stubbing out variables and object properties for unit tests. + This class can change the value of some variables before running the test + cases, and to reset them in the tearDown phase. + See googletest.StubOutForTesting as an analogy in Python: + http://protobuf.googlecode.com/svn/trunk/python/stubout.py + + Example usage: +

    var stubs = new goog.testing.PropertyReplacer();
    +
    + function setUp() {
    +   // Mock functions used in all test cases.
    +   stubs.set(Math, 'random', function() {
    +     return 4;  // Chosen by fair dice roll. Guaranteed to be random.
    +   });
    + }
    +
    + function tearDown() {
    +   stubs.reset();
    + }
    +
    + function testThreeDice() {
    +   // Mock a constant used only in this test case.
    +   stubs.set(goog.global, 'DICE_COUNT', 3);
    +   assertEquals(12, rollAllDice());
    + }
    + + Constraints on altered objects: +
      +
    • DOM subclasses aren't supported. +
    • The value of the objects' constructor property must either be equal to + the real constructor or kept untouched. +

    Constructor

    goog.testing.PropertyReplacer ( )
    Show:

    Instance Methods

    code »remove ( obj, key )

    Deletes the key from the object while saving its original value.

    Parameters
    obj: (Object|Function)
    The JavaScript or native object or function to + alter. See the constraints in the class description.
    key: string
    The key to delete.
    code »replace ( obj, key, value )

    Changes an existing value in an object to another one of the same type while + saving its original state. The advantage of replace over #set + is that replace protects against typos and erroneously passing tests + after some members have been renamed during a refactoring.

    Parameters
    obj: (Object|Function)
    The JavaScript or native object or function to + alter. See the constraints in the class description.
    key: string
    The key to change the value for. It has to be present + either in obj or in its prototype chain.
    value: *
    The new value to set. It has to have the same type as the + original value. The types are compared with goog.typeOf.
    Throws
    Error
    In case of missing key or type mismatch.

    Resets all changes made by goog.testing.PropertyReplacer.prototype.set.

    code »set ( obj, key, value )

    Adds or changes a value in an object while saving its original state.

    Parameters
    obj: (Object|Function)
    The JavaScript or native object or function to + alter. See the constraints in the class description.
    key: string
    The key to change the value for.
    value: *
    The new value to set.
    code »setPath ( path, value )

    Builds an object structure for the provided namespace path. Doesn't + overwrite those prefixes of the path that are already objects or functions.

    Parameters
    path: string
    The path to create or alter, e.g. 'goog.ui.Menu'.
    value: *
    The value to set.

    Instance Properties

    Stores the values changed by the set() method in chronological order. + Its items are objects with 3 fields: 'object', 'key', 'value'. The + original value for the given key in the given object is stored under the + 'value' key.

    Static Functions

    Deletes a key from an object. Sets it to undefined or empty string if the + delete failed.

    Parameters
    obj: (Object|Function)
    The object or function to delete a key from.
    key: string
    The key to delete.

    Tells if the given key exists in the object. Ignores inherited fields.

    Parameters
    obj: (Object|Function)
    The JavaScript or native object or function + whose key is to be checked.
    key: string
    The key to check.
    Returns
    Whether the object has the key as own key.

    Static Properties

    Indicates that a key didn't exist before having been set by the set() method.

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_StrictMock.html b/docs/api/javascript/class_goog_testing_StrictMock.html new file mode 100644 index 0000000000000..aae28140333ee --- /dev/null +++ b/docs/api/javascript/class_goog_testing_StrictMock.html @@ -0,0 +1,23 @@ +goog.testing.StrictMock

    Class goog.testing.StrictMock

    code »
    goog.testing.Mock
    +  └ goog.testing.StrictMock
    All implemented interfaces:
    goog.testing.MockInterface

    This is a mock that verifies that methods are called in the order that they + are specified during the recording phase. Since it verifies order, it + follows 'fail fast' semantics. If it detects a deviation from the + expectations, it will throw an exception and not wait for verify to be + called.

    Constructor

    goog.testing.StrictMock ( objectToMock, opt_mockStaticMethods, opt_createProxy )
    Parameters
    objectToMock: (Object|Function)
    The object that should be mocked, or + the constructor of an object to mock.
    opt_mockStaticMethods: boolean=
    An optional argument denoting that + a mock should be constructed from the static functions of a class.
    opt_createProxy: boolean=
    An optional argument denoting that + a proxy for the target mock should be created.
    Show:

    Instance Methods

    Defined in goog.testing.StrictMock

    code »$recordCall ( name, args )*
    Parameters
    name
    args

    Defined in goog.testing.Mock

    Allows the expectation to be called any number of times.

    Returns
    This mock object.

    Render the provided argument array to a string to help + clients with debugging tests.

    Parameters
    args: ?Array
    The arguments passed to the mock.
    Returns
    Human-readable string.

    Allows the expectation to be called any number of times, as long as it's + called once.

    Returns
    This mock object.

    Allows the expectation to be called 0 or 1 times.

    Returns
    This mock object.
    code »$do ( expectation, args )*

    If this expectation defines a function to be called, + it will be called and its result will be returned. + Otherwise, if the expectation expects to throw, it will throw. + Otherwise, this method will return defined value.

    Parameters
    expectation: goog.testing.MockExpectation
    The expectation.
    args: Array
    The arguments to the method.
    Returns
    The return value expected by the mock.

    Specifies a function to call for currently pending expectation. + Note, that using this method overrides declarations made + using $returns() and $throws() methods.

    Parameters
    func: Function
    The function to call.
    Returns
    This mock object.

    Initializes the functions on the mock object.

    Parameters
    objectToMock: Object
    The object being mocked.
    code »$maybeThrow ( expectation )

    If the expectation expects to throw, this method will throw.

    Parameters
    expectation: goog.testing.MockExpectation
    The expectation.
    code »$mockMethod ( name )*

    The function that replaces all methods on the mock object.

    Parameters
    name: string
    The name of the method being mocked.
    Returns
    In record mode, returns the mock object. In replay mode, returns + whatever the creator of the mock set as the return value.

    Disallows the expectation from being called.

    Returns
    This mock object.

    Allows the expectation to be called exactly once.

    Returns
    This mock object.

    Throws an exception and records that an exception was thrown.

    Parameters
    ex: Object
    Exception.
    Throws
    Object
    #ex.

    Registers a verfifier function to use when verifying method argument lists.

    Parameters
    methodName: string
    The name of the method for which the verifierFn + should be used.
    fn: Function
    Argument list verifier function. Should take 2 argument + arrays as arguments, and return true if they are considered equivalent.
    Returns
    This mock object.

    Switches from recording to replay mode.

    Specifies a return value for the currently pending expectation.

    Parameters
    val: *
    The return value.
    Returns
    This mock object.
    code »$throwCallException ( name, args, opt_expectation )

    Throw an exception based on an incorrect method call.

    Parameters
    name: string
    Name of method called.
    args: ?Array
    Arguments passed to the mock.
    opt_expectation: goog.testing.MockExpectation=
    Expected next call, + if any.
    code »$throwException ( comment, opt_message )

    Throws an exception and records that an exception was thrown.

    Parameters
    comment: string
    A short comment about the exception.
    opt_message: ?string=
    A longer message about the exception.
    Throws
    Object
    JsUnitException object.

    Specifies a value for the currently pending expectation to throw.

    Parameters
    val: *
    The value to throw.
    Returns
    This mock object.

    Specifies the number of times the expectation should be called.

    Parameters
    times: number
    The number of times this method will be called.
    Returns
    This mock object.
    code »$verifyCall ( expectation, name, args )boolean

    Verifies that a method call matches an expectation.

    Parameters
    expectation: goog.testing.MockExpectation
    The expectation to check.
    name: string
    The name of the called method.
    args: ?Array
    The arguments passed to the mock.
    Returns
    Whether the call matches the expectation.

    Instance Properties

    Defined in goog.testing.StrictMock

    Defined in goog.testing.Mock

    Map of argument name to optional argument list verifier function.

    The expectation currently being created. All methods that modify the + current expectation return the Mock object for easy chaining, so this is + where we keep track of the expectation that's currently being modified.

    A proxy for the mock. This can be used for dependency injection in lieu of + the mock if the test requires a strict instanceof check.

    Whether or not we are in recording mode.

    First exception thrown by this mock; used in $verify.

    Static Properties

    \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_TestCase.html b/docs/api/javascript/class_goog_testing_TestCase.html new file mode 100644 index 0000000000000..cd35ab84e374f --- /dev/null +++ b/docs/api/javascript/class_goog_testing_TestCase.html @@ -0,0 +1,85 @@ +goog.testing.TestCase

    Class goog.testing.TestCase

    code »

    A class representing a JsUnit test case. A TestCase is made up of a number + of test functions which can be run. Individual test cases can override the + following functions to set up their test environment: + - runTests - completely override the test's runner + - setUpPage - called before any of the test functions are run + - tearDownPage - called after all tests are finished + - setUp - called before each of the test functions + - tearDown - called after each of the test functions + - shouldRunTests - called before a test run, all tests are skipped if it + returns false. Can be used to disable tests on browsers + where they aren't expected to pass. + + Use #autoDiscoverLifecycle and #autoDiscoverTests

    Constructor

    goog.testing.TestCase ( opt_name )
    Parameters
    opt_name: string=
    The name of the test case, defaults to + 'Untitled Test Case'.

    Classes

    goog.testing.TestCase.Error
    A class representing an error thrown by the test
    goog.testing.TestCase.Result
    A class for representing test results.
    goog.testing.TestCase.Test
    A class representing a single test function.
    goog.testing.TestCase.protectedDate_
    No Description.

    Enumerations

    goog.testing.TestCase.Order
    The order to run the auto-discovered tests.
    Show:

    Instance Methods

    code »add ( test )

    Adds a new test to the test case.

    Parameters
    test: goog.testing.TestCase.Test
    The test to add.
    code »addNewTest ( name, ref, opt_scope )

    Creates and adds a new test. + + Convenience function to make syntax less awkward when not using automatic + test discovery.

    Parameters
    name: string
    The test name.
    ref: !Function
    Reference to the test function.
    opt_scope: !Object=
    Optional scope that the test function should be + called in.

    Adds any functions defined in the global scope that correspond to + lifecycle events for the test case. Overrides setUp, tearDown, setUpPage, + tearDownPage and runTests if they are defined.

    Adds any functions defined in the global scope that are prefixed with "test" + to the test case.

    Clears a timeout created by this.timeout().

    Parameters
    id: number
    A timeout id.

    Counts the number of files that were loaded for dependencies that are + required to run the test.

    Returns
    The number of files loaded.

    Creates a goog.testing.TestCase.Test from an auto-discovered + function.

    Parameters
    name: string
    The name of the function.
    ref: function(): void
    The auto-discovered function.
    Returns
    The newly created test.

    Cycles through the tests, breaking out using a setTimeout if the execution + time has execeeded #maxRunTime.

    code »doError ( test, opt_e )

    Handles a test that failed.

    Parameters
    test: goog.testing.TestCase.Test
    The test that failed.
    opt_e: *=
    The exception object associated with the + failure or a string.

    Handles a test that passed.

    Parameters
    test: goog.testing.TestCase.Test
    The test that passed.

    Executes each of the tests.

    Finalizes the test case, called when the tests have finished executing.

    Returns the number of tests actually run in the test case, i.e. subtracting + any which are skipped.

    Returns
    The number of un-ignored tests.
    Returns
    The function name prefix used to auto-discover tests.
    Returns
    Time since the last batch of tests was started.

    Returns the number of tests contained in the test case.

    Returns
    The number of tests.
    code »getGlobals ( opt_prefix )!Array

    Gets list of objects that potentially contain test cases. For IE 8 and below, + this is the global "this" (for properties set directly on the global this or + window) and the RuntimeObject (for global variables and functions). For all + other browsers, the array simply contains the global this.

    Parameters
    opt_prefix: string=
    An optional prefix. If specified, only get things + under this prefix. Note that the prefix is only honored in IE, since it + supports the RuntimeObject: + http://msdn.microsoft.com/en-us/library/ff521039%28VS.85%29.aspx + TODO: Remove this option.
    Returns
    A list of objects that should be inspected.
    Returns
    The name of the test.

    Returns the number of script files that were loaded in order to run the test.

    Returns
    The number of script files.
    code »getReport ( opt_verbose )string

    Returns a string detailing the results from the test.

    Parameters
    opt_verbose: boolean=
    If true results will include data about all + tests, not just what failed.
    Returns
    The results from the test.

    Returns the amount of time it took for the test to run.

    Returns
    The run time, in milliseconds.

    Returns the test results object: a map from test names to a list of test + failures (if any exist).

    Returns
    Tests results object.

    Gets the tests.

    Returns
    The test array.

    Returns the current time.

    Returns
    HH:MM:SS.
    Returns
    Whether the test case is running inside the multi test + runner.
    Returns
    Whether the test was a success.
    code »log ( val )

    Logs an object to the console, if available.

    Parameters
    val: *
    The value to log. Will be ToString'd.
    Parameters
    name: string
    Failed test name.
    opt_e: *=
    The exception object associated with the + failure or a string.
    Returns
    Error object.

    Checks to see if the test should be marked as failed before it is run. + + If there was an error in setUpPage, we treat that as a failure for all tests + and mark them all as having failed.

    Parameters
    testCase: goog.testing.TestCase.Test
    The current test case.
    Returns
    Whether the test was marked as failed.

    Returns the current test and increments the pointer.

    Returns
    The current test case.
    Returns
    The current time in milliseconds, don't use goog.now as some + tests override it.

    Reorders the tests depending on the order field.

    Parameters
    tests: Array.<goog.testing.TestCase.Test>
    An array of tests to + reorder.
    code »pad_ ( number )string

    Pads a number to make it have a leading zero if it's less than 10.

    Parameters
    number: number
    The number to pad.
    Returns
    The resulting string.

    Resets the test case pointer, so that next returns the first test.

    Executes each of the tests. + Overridable by the individual test case. This allows test cases to defer + when the test is actually started. If overridden, finalize must be called + by the test to indicate it has finished.

    code »saveMessage ( message )

    Saves a message to the result set.

    Parameters
    message: string
    The message to save.
    code »setBatchTime ( batchTime )
    Parameters
    batchTime: number
    Time since the last batch of tests was started.

    Sets the callback function that should be executed when the tests have + completed.

    Parameters
    fn: Function
    The callback function.
    code »setTests ( tests )

    Sets the tests.

    Parameters
    tests: !Array.<goog.testing.TestCase.Test>
    A new test array.

    Gets called before every goog.testing.TestCase.Test is been executed. Can be + overridden to add set up functionality to each test.

    Gets called before any tests are executed. Can be overridden to set up the + environment for the whole test case.

    Can be overridden in test classes to indicate whether the tests in a case + should be run in that particular situation. For example, this could be used + to stop tests running in a particular browser, where browser support for + the class under test was absent.

    Returns
    Whether any of the tests in the case should be run.

    Gets called after every goog.testing.TestCase.Test has been executed. Can be + overriden to add tear down functionality to each test.

    Gets called after all tests have been executed. Can be overridden to tear + down the entire test case.

    code »timeout ( fn, time )number

    Calls a function after a delay, using the protected timeout.

    Parameters
    fn: Function
    The function to call.
    time: number
    Delay in milliseconds.
    Returns
    The timeout id.

    Trims a path to be only that after google3.

    Parameters
    path: string
    The path to trim.
    Returns
    The resulting string.

    Instance Properties

    Time since the last batch of tests was started, if batchTime exceeds + #maxRunTime a timeout will be used to stop the tests blocking the + browser and a new batch will be started.

    Pointer to the current test.

    Exception object that was detected before a test runs.

    A name for the test case.

    Optional callback that will be executed when the test has finalized.

    The order to run the auto-discovered tests in.

    Object used to encapsulate the test results.

    Whether the test case is running.

    Timestamp for when the test was started.

    Whether the test case has ever tried to execute.

    Set of test names and/or indices to execute, or null if all tests should + be executed. + + Indices are included to allow automation tools to run a subset of the + tests without knowing the exact contents of the test file. + + Indices should only be used with SORTED ordering. + + Example valid values: +

      +
    • [testName] +
    • [testName1, testName2] +
    • [2] - will run the 3rd test in the order specified +
    • [1,3,5] +
    • [testName1, testName2, 3, 5] - will work +

      Array of test functions that can be executed.

      Static Functions

      Gets list of objects that potentially contain test cases. For IE 8 and below, + this is the global "this" (for properties set directly on the global this or + window) and the RuntimeObject (for global variables and functions). For all + other browsers, the array simply contains the global this.

      Parameters
      opt_prefix: string=
      An optional prefix. If specified, only get things + under this prefix. Note that the prefix is only honored in IE, since it + supports the RuntimeObject: + http://msdn.microsoft.com/en-us/library/ff521039%28VS.85%29.aspx + TODO: Remove this option.
      Returns
      A list of objects that should be inspected.

      Initializes the given test case with the global test runner 'G_testRunner'.

      Parameters
      testCase: goog.testing.TestCase
      The test case to install.

      Save a reference to window.clearTimeout, so any code that overrides + the default behavior (e.g. MockClock) doesn't affect our runner.

      Save a reference to window.setTimeout, so any code that overrides the + default behavior (the MockClock, for example) doesn't affect our runner.

      Static Properties

      Avoid a dependency on goog.userAgent and keep our own reference of whether + the browser is IE.

      TODO(user) replace this with prototype.currentTest. + Name of the current test that is running, or null if none is running.

      The maximum amount of time that the test can run before we force it to be + async. This prevents the test runner from blocking the browser and + potentially hurting the Selenium test harness.

      Saved string referencing goog.global.setTimeout's string serialization. IE + sometimes fails to uphold equality for setTimeout, but the string version + stays the same.

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_TestCase_Error.html b/docs/api/javascript/class_goog_testing_TestCase_Error.html new file mode 100644 index 0000000000000..dbe77b29fb4e3 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_TestCase_Error.html @@ -0,0 +1 @@ +goog.testing.TestCase.Error

      Class goog.testing.TestCase.Error

      code »

      A class representing an error thrown by the test

      Constructor

      goog.testing.TestCase.Error ( source, message, opt_stack )
      Parameters
      source: string
      The name of the test which threw the error.
      message: string
      The error message.
      opt_stack: string=
      A string showing the execution stack.
      Show:

      Instance Methods

      Returns a string representing the error object.

      Returns
      A string representation of the error.

      Instance Properties

      Reference to the test function.

      The name of the test which threw the error.

      Scope that the test function should be called in.

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_TestCase_Result.html b/docs/api/javascript/class_goog_testing_TestCase_Result.html new file mode 100644 index 0000000000000..094cf67a31eea --- /dev/null +++ b/docs/api/javascript/class_goog_testing_TestCase_Result.html @@ -0,0 +1,5 @@ +goog.testing.TestCase.Result

      Class goog.testing.TestCase.Result

      code »

      A class for representing test results. A bag of public properties.

      Constructor

      goog.testing.TestCase.Result ( testCase )
      Parameters
      testCase: goog.testing.TestCase
      The test case that owns this result.
      Show:

      Instance Methods

      Returns
      A summary of the tests, including total number of tests that + passed, failed, and the time taken.
      Returns
      Whether the test was successful.

      Instance Properties

      Whether the tests have completed.

      Errors encountered while running the test.

      Messages to show the user after running the test.

      The number of files loaded to run this test.

      Test results for each test that was run. The test name is always added + as the key in the map, and the array of strings is an optional list + of failure messages. If the array is empty, the test passed. Otherwise, + the test failed.

      Total number of tests that were actually run.

      The amount of time the tests took to run.

      Number of successful tests.

      The test case that owns this result.

      Whether this test case was suppressed by shouldRunTests() returning false.

      Total number of tests that should have been run.

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_TestCase_Test.html b/docs/api/javascript/class_goog_testing_TestCase_Test.html new file mode 100644 index 0000000000000..16aac26f1bd28 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_TestCase_Test.html @@ -0,0 +1,2 @@ +goog.testing.TestCase.Test

      Class goog.testing.TestCase.Test

      code »

      A class representing a single test function.

      Constructor

      goog.testing.TestCase.Test ( name, ref, opt_scope )
      Parameters
      name: string
      The test name.
      ref: Function
      Reference to the test function.
      opt_scope: Object=
      Optional scope that the test function should be + called in.
      Show:

      Instance Methods

      Executes the test function.

      Instance Properties

      The name of the test.

      Reference to the test function.

      Scope that the test function should be called in.

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_TestCase_protectedDate_.html b/docs/api/javascript/class_goog_testing_TestCase_protectedDate_.html new file mode 100644 index 0000000000000..3087ec288c2a8 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_TestCase_protectedDate_.html @@ -0,0 +1,3 @@ +goog.testing.TestCase.protectedDate_

      Class goog.testing.TestCase.protectedDate_

      code »

      Save a reference to window.Date, so any code that overrides + the default behavior doesn't affect our runner.

      Constructor

      goog.testing.TestCase.protectedDate_ ( )
      Show:

      Instance Methods

      code »setDate ( dayValue )

      Sets the day of the month for a specified date according to local time.

      Parameters
      dayValue
      code »setFullYear ( yearValue, opt_monthValue, opt_dayValue )

      Sets the full year for a specified date according to local time.

      Parameters
      yearValue
      opt_monthValue
      opt_dayValue
      code »setHours ( hoursValue, opt_minutesValue, opt_secondsValue, opt_msValue )

      Sets the hours for a specified date according to local time.

      Parameters
      hoursValue
      opt_minutesValue
      opt_secondsValue
      opt_msValue
      code »setMilliseconds ( millisecondsValue )

      Sets the milliseconds for a specified date according to local time.

      Parameters
      millisecondsValue
      code »setMinutes ( minutesValue, opt_secondsValue, opt_msValue )

      Sets the minutes for a specified date according to local time.

      Parameters
      minutesValue
      opt_secondsValue
      opt_msValue
      code »setMonth ( monthValue, opt_dayValue )

      Set the month for a specified date according to local time.

      Parameters
      monthValue
      opt_dayValue
      code »setSeconds ( secondsValue, opt_msValue )

      Sets the seconds for a specified date according to local time.

      Parameters
      secondsValue
      opt_msValue
      code »setTime ( timeValue )

      Sets the Date object to the time represented by a number of milliseconds + since January 1, 1970, 00:00:00 UTC.

      Parameters
      timeValue
      code »setUTCDate ( dayValue )

      Sets the day of the month for a specified date according to universal time.

      Parameters
      dayValue
      code »setUTCFullYear ( yearValue, opt_monthValue, opt_dayValue )

      Sets the full year for a specified date according to universal time.

      Parameters
      yearValue
      opt_monthValue
      opt_dayValue
      code »setUTCHours ( hoursValue, opt_minutesValue, opt_secondsValue, opt_msValue )

      Sets the hour for a specified date according to universal time.

      Parameters
      hoursValue
      opt_minutesValue
      opt_secondsValue
      opt_msValue
      code »setUTCMilliseconds ( millisecondsValue )

      Sets the milliseconds for a specified date according to universal time.

      Parameters
      millisecondsValue
      code »setUTCMinutes ( minutesValue, opt_secondsValue, opt_msValue )

      Sets the minutes for a specified date according to universal time.

      Parameters
      minutesValue
      opt_secondsValue
      opt_msValue
      code »setUTCMonth ( monthValue, opt_dayValue )

      Sets the month for a specified date according to universal time.

      Parameters
      monthValue
      opt_dayValue
      code »setUTCSeconds ( secondsValue, opt_msValue )

      Sets the seconds for a specified date according to universal time.

      Parameters
      secondsValue
      opt_msValue
      code »setYear ( yearValue )

      Sets the year for a specified date according to local time.

      Parameters
      yearValue
      code »toJSON ( opt_ignoredKey )string
      Parameters
      opt_ignoredKey
      code »toLocaleDateString ( opt_locales, opt_options )string
      Parameters
      opt_locales
      opt_options
      code »toLocaleFormat ( formatString )string
      Parameters
      formatString
      code »toLocaleTimeString ( opt_locales, opt_options )string
      Parameters
      opt_locales
      opt_options
      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_TestRunner.html b/docs/api/javascript/class_goog_testing_TestRunner.html new file mode 100644 index 0000000000000..c3cde335720b7 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_TestRunner.html @@ -0,0 +1,17 @@ +goog.testing.TestRunner

      Class goog.testing.TestRunner

      code »

      Construct a test runner. + + NOTE(user): This is currently pretty weird, I'm essentially trying to + create a wrapper that the Selenium test can hook into to query the state of + the running test case, while making goog.testing.TestCase general.

      Constructor

      goog.testing.TestRunner ( )
      Show:

      Instance Methods

      Executes a test case and prints the results to the window.

      Returns the number of script files that were loaded in order to run the test.

      Returns
      The number of script files.
      code »getReport ( opt_verbose )string

      Returns a report of the test case that ran. + Used by Selenium Hooks.

      Parameters
      opt_verbose: boolean=
      If true results will include data about all + tests, not just what failed.
      Returns
      A report summary of the test.

      Returns the amount of time it took for the test to run. + Used by Selenium Hooks.

      Returns
      The run time, in milliseconds.
      Returns
      A map of test names to a list of + test failures (if any) to provide formatted data for the test runner.

      Returns true if the test case runner has errors that were caught outside of + the test case.

      Returns
      Whether there were JS errors.
      code »initialize ( testCase )

      Initializes the test runner.

      Parameters
      testCase: goog.testing.TestCase
      The test case to initialize with.

      Returns true if the test runner is finished. + Used by Selenium Hooks.

      Returns
      Whether the test runner is active.

      Returns true if the test runner is initialized. + Used by Selenium Hooks.

      Returns
      Whether the test runner is active.
      Returns
      Whether the test runner should fail on an empty + test case.

      Returns true if the test case didn't fail. + Used by Selenium Hooks.

      Returns
      Whether the current test returned successfully.

      Logs a message to the current test case.

      Parameters
      s: string
      The text to output to the log.

      Logs an error that occurred. Used in the case of environment setting up + an onerror handler.

      Parameters
      msg: string
      Error message.

      Log failure in current running test.

      Parameters
      ex: Error
      Exception.

      Writes the results to the document when the test case completes.

      Sets a function to use as a filter for errors.

      Parameters
      fn: function(string)
      Filter function.
      code »setStrict ( strict )

      By default, the test runner is strict, and fails if it runs an empty + test case.

      Parameters
      strict: boolean
      Whether the test runner should fail on an empty + test case.

      Writes a nicely formatted log out to the document.

      Parameters
      log: string
      The string to write.

      Instance Properties

      Function to use when filtering errors.

      Errors that occurred in the window.

      Whether the test runner has been initialized yet.

      Element created in the document to add test results to.

      Whether an empty test case counts as an error.

      Reference to the active test case.

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_events_Event.html b/docs/api/javascript/class_goog_testing_events_Event.html new file mode 100644 index 0000000000000..4c0df8e09fd49 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_events_Event.html @@ -0,0 +1,6 @@ +goog.testing.events.Event

      Class goog.testing.events.Event

      code »
      Event
      +  └ goog.testing.events.Event

      goog.events.BrowserEvent expects an Event so we provide one for JSCompiler. + + This clones a lot of the functionality of goog.events.Event. This used to + use a mixin, but the mixin results in confusing the two types when compiled.

      Constructor

      goog.testing.events.Event ( type, opt_target )
      Parameters
      type: string
      Event Type.
      opt_target: Object=
      Reference to the object that is the target of + this event.
      Show:

      Instance Methods

      Defined in goog.testing.events.Event

      Defined in Event

      code »initEvent ( eventTypeArg, canBubbleArg, cancelableArg )undefined
      Parameters
      eventTypeArg
      canBubbleArg
      cancelableArg

      Instance Properties

      Defined in goog.testing.events.Event

      Whether to cancel the event in internal capture/bubble processing for IE.

      Return value for in internal capture/bubble processing for IE.

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_mockmatchers_ArgumentMatcher.html b/docs/api/javascript/class_goog_testing_mockmatchers_ArgumentMatcher.html new file mode 100644 index 0000000000000..ffc68fdb9cade --- /dev/null +++ b/docs/api/javascript/class_goog_testing_mockmatchers_ArgumentMatcher.html @@ -0,0 +1,9 @@ +goog.testing.mockmatchers.ArgumentMatcher

      Class goog.testing.mockmatchers.ArgumentMatcher

      code »

      A simple interface for executing argument matching. A match in this case is + testing to see if a supplied object fits a given criteria. True is returned + if the given criteria is met.

      Constructor

      goog.testing.mockmatchers.ArgumentMatcher ( opt_matchFn, opt_matchName )
      Parameters
      opt_matchFn: Function=
      A function that evaluates a given argument + and returns true if it meets a given criteria.
      opt_matchName: ?string=
      The name expressing intent as part of + an error message for when a match fails.
      Show:

      Instance Methods

      code »matches ( toVerify, opt_expectation )boolean

      A function that takes a match argument and an optional MockExpectation + which (if provided) will get error information and returns whether or + not it matches.

      Parameters
      toVerify: *
      The argument that should be verified.
      opt_expectation: ?goog.testing.MockExpectation=
      The expectation + for this match.
      Returns
      Whether or not a given argument passes verification.

      Instance Properties

      A function that evaluates a given argument and returns true if it meets a + given criteria.

      A string indicating the match intent (e.g. isBoolean or isString).

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_mockmatchers_IgnoreArgument.html b/docs/api/javascript/class_goog_testing_mockmatchers_IgnoreArgument.html new file mode 100644 index 0000000000000..4d325c4afccab --- /dev/null +++ b/docs/api/javascript/class_goog_testing_mockmatchers_IgnoreArgument.html @@ -0,0 +1,8 @@ +goog.testing.mockmatchers.IgnoreArgument

      Class goog.testing.mockmatchers.IgnoreArgument

      code »
      goog.testing.mockmatchers.ArgumentMatcher
      +  └ goog.testing.mockmatchers.IgnoreArgument

      A matcher that always returns true. It is useful when the user does not care + for some arguments. + For example: mockFunction('username', 'password', IgnoreArgument);

      Constructor

      goog.testing.mockmatchers.IgnoreArgument ( )
      Show:

      Instance Methods

      code »matches ( toVerify, opt_expectation )boolean

      A function that takes a match argument and an optional MockExpectation + which (if provided) will get error information and returns whether or + not it matches.

      Parameters
      toVerify: *
      The argument that should be verified.
      opt_expectation: ?goog.testing.MockExpectation=
      The expectation + for this match.
      Returns
      Whether or not a given argument passes verification.

      Instance Properties

      A function that evaluates a given argument and returns true if it meets a + given criteria.

      A string indicating the match intent (e.g. isBoolean or isString).

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_mockmatchers_InstanceOf.html b/docs/api/javascript/class_goog_testing_mockmatchers_InstanceOf.html new file mode 100644 index 0000000000000..a5f073b098819 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_mockmatchers_InstanceOf.html @@ -0,0 +1,6 @@ +goog.testing.mockmatchers.InstanceOf

      Class goog.testing.mockmatchers.InstanceOf

      code »
      goog.testing.mockmatchers.ArgumentMatcher
      +  └ goog.testing.mockmatchers.InstanceOf

      A matcher that verifies that an argument is an instance of a given class.

      Constructor

      goog.testing.mockmatchers.InstanceOf ( ctor )
      Parameters
      ctor: Function
      The class that will be used for verification.
      Show:

      Instance Methods

      code »matches ( toVerify, opt_expectation )boolean

      A function that takes a match argument and an optional MockExpectation + which (if provided) will get error information and returns whether or + not it matches.

      Parameters
      toVerify: *
      The argument that should be verified.
      opt_expectation: ?goog.testing.MockExpectation=
      The expectation + for this match.
      Returns
      Whether or not a given argument passes verification.

      Instance Properties

      A function that evaluates a given argument and returns true if it meets a + given criteria.

      A string indicating the match intent (e.g. isBoolean or isString).

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_mockmatchers_ObjectEquals.html b/docs/api/javascript/class_goog_testing_mockmatchers_ObjectEquals.html new file mode 100644 index 0000000000000..967af0423ec7b --- /dev/null +++ b/docs/api/javascript/class_goog_testing_mockmatchers_ObjectEquals.html @@ -0,0 +1,5 @@ +goog.testing.mockmatchers.ObjectEquals

      Class goog.testing.mockmatchers.ObjectEquals

      code »
      goog.testing.mockmatchers.ArgumentMatcher
      +  └ goog.testing.mockmatchers.ObjectEquals

      A matcher that verifies that the argument is an object that equals the given + expected object, using a deep comparison.

      Constructor

      goog.testing.mockmatchers.ObjectEquals ( expectedObject )
      Parameters
      expectedObject: Object
      An object to match against when + verifying the argument.
      Show:

      Instance Methods

      Defined in goog.testing.mockmatchers.ObjectEquals

      code »matches ( toVerify, opt_expectation )boolean
      Parameters
      toVerify
      opt_expectation

      Instance Properties

      Defined in goog.testing.mockmatchers.ArgumentMatcher

      A function that evaluates a given argument and returns true if it meets a + given criteria.

      A string indicating the match intent (e.g. isBoolean or isString).

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_mockmatchers_RegexpMatch.html b/docs/api/javascript/class_goog_testing_mockmatchers_RegexpMatch.html new file mode 100644 index 0000000000000..641c947579f45 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_mockmatchers_RegexpMatch.html @@ -0,0 +1,6 @@ +goog.testing.mockmatchers.RegexpMatch

      Class goog.testing.mockmatchers.RegexpMatch

      code »
      goog.testing.mockmatchers.ArgumentMatcher
      +  └ goog.testing.mockmatchers.RegexpMatch

      A matcher that verifies that an argument matches a given RegExp.

      Constructor

      goog.testing.mockmatchers.RegexpMatch ( regexp )
      Parameters
      regexp: RegExp
      The regular expression that the argument must match.
      Show:

      Instance Methods

      code »matches ( toVerify, opt_expectation )boolean

      A function that takes a match argument and an optional MockExpectation + which (if provided) will get error information and returns whether or + not it matches.

      Parameters
      toVerify: *
      The argument that should be verified.
      opt_expectation: ?goog.testing.MockExpectation=
      The expectation + for this match.
      Returns
      Whether or not a given argument passes verification.

      Instance Properties

      A function that evaluates a given argument and returns true if it meets a + given criteria.

      A string indicating the match intent (e.g. isBoolean or isString).

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_mockmatchers_SaveArgument.html b/docs/api/javascript/class_goog_testing_mockmatchers_SaveArgument.html new file mode 100644 index 0000000000000..54da2714679b6 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_mockmatchers_SaveArgument.html @@ -0,0 +1,8 @@ +goog.testing.mockmatchers.SaveArgument

      Class goog.testing.mockmatchers.SaveArgument

      code »
      goog.testing.mockmatchers.ArgumentMatcher
      +  └ goog.testing.mockmatchers.SaveArgument

      A matcher that saves the argument that it is verifying so that your unit test + can perform extra tests with this argument later. For example, if the + argument is a callback method, the unit test can then later call this + callback to test the asynchronous portion of the call.

      Constructor

      goog.testing.mockmatchers.SaveArgument ( opt_matcher, opt_matchName )
      Parameters
      opt_matcher: (goog.testing.mockmatchers.ArgumentMatcher|Function)=
      Argument matcher or matching function that will be used to validate the + argument. By default, argument will always be valid.
      opt_matchName: ?string=
      The name expressing intent as part of + an error message for when a match fails.
      Show:

      Instance Methods

      Defined in goog.testing.mockmatchers.SaveArgument

      code »matches ( toVerify, opt_expectation )boolean
      Parameters
      toVerify
      opt_expectation

      Instance Properties

      Defined in goog.testing.mockmatchers.SaveArgument

      Saved argument that was verified.

      Delegate match requests to this matcher.

      Defined in goog.testing.mockmatchers.ArgumentMatcher

      A function that evaluates a given argument and returns true if it meets a + given criteria.

      A string indicating the match intent (e.g. isBoolean or isString).

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_mockmatchers_TypeOf.html b/docs/api/javascript/class_goog_testing_mockmatchers_TypeOf.html new file mode 100644 index 0000000000000..8835d33ee43f9 --- /dev/null +++ b/docs/api/javascript/class_goog_testing_mockmatchers_TypeOf.html @@ -0,0 +1,6 @@ +goog.testing.mockmatchers.TypeOf

      Class goog.testing.mockmatchers.TypeOf

      code »
      goog.testing.mockmatchers.ArgumentMatcher
      +  └ goog.testing.mockmatchers.TypeOf

      A matcher that verifies that an argument is of a given type (e.g. "object").

      Constructor

      goog.testing.mockmatchers.TypeOf ( type )
      Parameters
      type: string
      The type that a given argument must have.
      Show:

      Instance Methods

      code »matches ( toVerify, opt_expectation )boolean

      A function that takes a match argument and an optional MockExpectation + which (if provided) will get error information and returns whether or + not it matches.

      Parameters
      toVerify: *
      The argument that should be verified.
      opt_expectation: ?goog.testing.MockExpectation=
      The expectation + for this match.
      Returns
      Whether or not a given argument passes verification.

      Instance Properties

      A function that evaluates a given argument and returns true if it meets a + given criteria.

      A string indicating the match intent (e.g. isBoolean or isString).

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_goog_testing_stacktrace_Frame.html b/docs/api/javascript/class_goog_testing_stacktrace_Frame.html new file mode 100644 index 0000000000000..460cb267c81fb --- /dev/null +++ b/docs/api/javascript/class_goog_testing_stacktrace_Frame.html @@ -0,0 +1,6 @@ +goog.testing.stacktrace.Frame

      Class goog.testing.stacktrace.Frame

      code »

      Class representing one stack frame.

      Constructor

      goog.testing.stacktrace.Frame ( context, name, alias, args, path )
      Parameters
      context: string
      Context object, empty in case of global functions or + if the browser doesn't provide this information.
      name: string
      Function name, empty in case of anonymous functions.
      alias: string
      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() {};.
      args: string
      Arguments of the function in parentheses if available.
      path: string
      File path or URL including line number and optionally + column number separated by colons.
      Show:

      Instance Methods

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

      Brings one frame of the stack trace into a common format across browsers.

      Returns
      Pretty printed stack frame.

      Instance Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_AbstractBuilder.html b/docs/api/javascript/class_webdriver_AbstractBuilder.html index a8dc544aeaa99..1b1363e74bf88 100644 --- a/docs/api/javascript/class_webdriver_AbstractBuilder.html +++ b/docs/api/javascript/class_webdriver_AbstractBuilder.html @@ -5,10 +5,12 @@
      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 +

      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 + to use.

      Sets the logging preferences for the created session. Preferences may be + changed by repeated calls, or by calling #withCapabilities.

      Parameters
      prefs: !(webdriver.logging.Preferences|Object.<string, string>)
      The + desired logging preferences.
      Returns
      This Builder instance for chain calling.

      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 @@ -18,4 +20,4 @@ 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 + using #usingServer(url). \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_ActionSequence.html b/docs/api/javascript/class_webdriver_ActionSequence.html index 86ec373ff4bd7..084051b9693c2 100644 --- a/docs/api/javascript/class_webdriver_ActionSequence.html +++ b/docs/api/javascript/class_webdriver_ActionSequence.html @@ -84,4 +84,4 @@ 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 + 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/docs/api/javascript/class_webdriver_Alert.html b/docs/api/javascript/class_webdriver_Alert.html index 4778843dbc2d9..581819e679b6f 100644 --- a/docs/api/javascript/class_webdriver_Alert.html +++ b/docs/api/javascript/class_webdriver_Alert.html @@ -1,85 +1,12 @@ -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 +webdriver.Alert

      Class webdriver.Alert

      code »

      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 is attached to.

      text: string
      The message text displayed with this alert.
      Show:

      Instance Methods

      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 + 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 + when this command has completed.

      Instance Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_AlertPromise.html b/docs/api/javascript/class_webdriver_AlertPromise.html new file mode 100644 index 0000000000000..d3793cb3ded15 --- /dev/null +++ b/docs/api/javascript/class_webdriver_AlertPromise.html @@ -0,0 +1,20 @@ +webdriver.AlertPromise

      Class webdriver.AlertPromise

      code »
      webdriver.Alert
      +  └ webdriver.AlertPromise
      All implemented interfaces:
      webdriver.promise.Thenable.<webdriver.Alert>

      AlertPromise is a promise that will be fulfilled with an Alert. This promise + serves as a forward proxy on an Alert, allowing calls to be scheduled + directly on this instance before the underlying Alert has been fulfilled. In + other words, the following two statements are equivalent: +

      
      +     driver.switchTo().alert().dismiss();
      +     driver.switchTo().alert().then(function(alert) {
      +       return alert.dismiss();
      +     });
      + 

      Constructor

      webdriver.AlertPromise ( driver, alert )
      Parameters
      driver: !webdriver.WebDriver
      The driver controlling the browser this + alert is attached to.
      alert: !webdriver.promise.Thenable
      A thenable + that will be fulfilled with the promised alert.
      Show:

      Instance Methods

      Defined in webdriver.AlertPromise

      code »isPending ( )boolean
      code »then ( )webdriver.promise.Promise
      code »thenCatch ( )webdriver.promise.Promise
      code »thenFinally ( )webdriver.promise.Promise

      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.

      Instance Properties

      Defined in webdriver.Alert

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_Builder.html b/docs/api/javascript/class_webdriver_Builder.html index f650658502444..a67f28c4f54f0 100644 --- a/docs/api/javascript/class_webdriver_Builder.html +++ b/docs/api/javascript/class_webdriver_Builder.html @@ -3,7 +3,9 @@ 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 + to use.

      Sets the logging preferences for the created session. Preferences may be + changed by repeated calls, or by calling #withCapabilities.

      Parameters
      prefs: !(webdriver.logging.Preferences|Object.<string, string>)
      The + desired logging preferences.
      Returns
      This Builder instance for chain calling.

      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 @@ -19,4 +21,4 @@ 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 + be set. \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_Capabilities.html b/docs/api/javascript/class_webdriver_Capabilities.html index 12d3834d9807b..ee5d1f143d034 100644 --- a/docs/api/javascript/class_webdriver_Capabilities.html +++ b/docs/api/javascript/class_webdriver_Capabilities.html @@ -1,9 +1,15 @@ -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 +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 + 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.

      Sets the default action to take with an unexpected alert before returning + an error.

      Parameters
      behavior: string
      The desired behavior; should be "accept", "dismiss", + or "ignore". Defaults to "dismiss".
      Returns
      A self reference.

      Sets whether native events should be used.

      Parameters
      enabled: boolean
      Whether to enable native events.
      Returns
      A self reference.

      Sets the logging preferences. Preferences may be specified as a + webdriver.logging.Preferences instance, or a as a map of log-type to + log-level.

      Parameters
      prefs: !(webdriver.logging.Preferences|Object.<string, string>)
      The + logging preferences.
      Returns
      A self reference.

      Sets the proxy configuration for this instance.

      Parameters
      proxy: webdriver.ProxyConfig
      The desired proxy configuration.
      Returns
      A self reference.

      Sets how elements should be scrolled into view for interaction.

      Parameters
      behavior: number
      The desired scroll behavior: either 0 to align with + the top of the viewport or 1 to align with the bottom.
      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/docs/api/javascript/class_webdriver_Command.html b/docs/api/javascript/class_webdriver_Command.html index 77ec1daf7b2ba..2b7442bc4d8f0 100644 --- a/docs/api/javascript/class_webdriver_Command.html +++ b/docs/api/javascript/class_webdriver_Command.html @@ -1 +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 +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/docs/api/javascript/class_webdriver_EventEmitter.html b/docs/api/javascript/class_webdriver_EventEmitter.html index 0289852279a2a..411f1921049c9 100644 --- a/docs/api/javascript/class_webdriver_EventEmitter.html +++ b/docs/api/javascript/class_webdriver_EventEmitter.html @@ -4,4 +4,4 @@ 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 + 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/docs/api/javascript/class_webdriver_FirefoxDomExecutor.html b/docs/api/javascript/class_webdriver_FirefoxDomExecutor.html index 2e72f35605344..6057523d80233 100644 --- a/docs/api/javascript/class_webdriver_FirefoxDomExecutor.html +++ b/docs/api/javascript/class_webdriver_FirefoxDomExecutor.html @@ -1,2 +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 + FirefoxDomExecutor. \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_Locator.html b/docs/api/javascript/class_webdriver_Locator.html index c6876e32f58bc..0b349d8aee6ed 100644 --- a/docs/api/javascript/class_webdriver_Locator.html +++ b/docs/api/javascript/class_webdriver_Locator.html @@ -1,2 +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 + 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/docs/api/javascript/class_webdriver_Session.html b/docs/api/javascript/class_webdriver_Session.html index 5aa83a40ddcbe..220d7a570743e 100644 --- a/docs/api/javascript/class_webdriver_Session.html +++ b/docs/api/javascript/class_webdriver_Session.html @@ -1,3 +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 + session ID.
      Returns
      The JSON representation of this Session.

      Instance Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_UnhandledAlertError.html b/docs/api/javascript/class_webdriver_UnhandledAlertError.html index 6162b910cdf5a..f3f06da71eb0c 100644 --- a/docs/api/javascript/class_webdriver_UnhandledAlertError.html +++ b/docs/api/javascript/class_webdriver_UnhandledAlertError.html @@ -1,6 +1,7 @@ -webdriver.UnhandledAlertError

      Class webdriver.UnhandledAlertError

      code »
      Error
      +webdriver.UnhandledAlertError

      Class webdriver.UnhandledAlertError

      code »
      Errorbot.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. + current page.

      Constructor

      webdriver.UnhandledAlertError ( message, text, alert )
      Parameters
      message: string
      The error message.
      text: string
      The text displayed with the unhandled alert.
      alert: !webdriver.Alert
      The alert handle.
      Show:

      Instance Methods

      Defined in webdriver.UnhandledAlertError

      Deprecated: Use #getAlertText. This method will be removed in + 2.45.0.
      Returns
      The open alert.
      Returns
      The text displayed with the unhandled 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 + to another will fail instanceof checks in the second component.

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_WebDriver.html b/docs/api/javascript/class_webdriver_WebDriver.html index d49e341886632..8d793ce942813 100644 --- a/docs/api/javascript/class_webdriver_WebDriver.html +++ b/docs/api/javascript/class_webdriver_WebDriver.html @@ -1,4 +1,4 @@ -webdriver.WebDriver

      Class webdriver.WebDriver

      code »

      Creates a new WebDriver client, which provides control over a browser. +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 @@ -17,7 +17,7 @@

      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 + 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:

      
      @@ -26,11 +26,11 @@
              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 +
      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 + 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 @@ -79,7 +79,7 @@ 'var callback = arguments[arguments.length - 1];' + 'mailClient.getComposeWindowWidget().onload(callback);'); driver.switchTo().frame('composeWidget'); - driver.findElement(By.id('to')).sendKEys('dog@example.com'); + driver.findElement(By.id('to')).sendKeys('dog@example.com'); Example #3: Injecting a XMLHttpRequest and waiting for the result. In this @@ -94,7 +94,7 @@ xhr.open("GET", "/resource/data.json", true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { - callback(xhr.resposneText); + callback(xhr.responseText); } } xhr.send(''); @@ -102,7 +102,7 @@ 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 + 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 @@ -132,14 +132,14 @@

    • 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 + 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 + 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 @@ -182,39 +182,39 @@ 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 + 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 + 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 + 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 + 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. + 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 + 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 + 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 + 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 @@ -222,38 +222,44 @@
      2. Visible portion of the current frame
      3. 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 + 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 +

      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 + wait condition has been satisfied.

      Instance Properties

      Static Functions

      code »webdriver.WebDriver.acquireSession_ ( executor, command, description, opt_flow )!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 + details.
      description: string
      A descriptive debug label for this action.
      opt_flow: webdriver.promise.ControlFlow=
      The control flow all driver + commands should execute under. Defaults to the + currently active control flow.
      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.
      opt_flow: webdriver.promise.ControlFlow=
      The control flow all driver + commands should execute under. Defaults to the + currently active control flow.
      Returns
      A new client for the specified session.
      code »webdriver.WebDriver.createSession ( executor, desiredCapabilities, opt_flow )!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 + capabilities for the new session.

      opt_flow: webdriver.promise.ControlFlow=
      The control flow all driver + commands should execute under, including the initial session creation. + Defaults to the currently active + control flow.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 + 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. + 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 is a WebElement, the return value will be the element's + server ID
      4. if the object provides a "toJSON" function, the return value of this function will be returned
      5. otherwise, the value of each key will be recursively converted according to the rules above.
      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 + input value's JSON representation. \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_WebDriver_Logs.html b/docs/api/javascript/class_webdriver_WebDriver_Logs.html index a4976c6d71116..8c5295bda3b45 100644 --- a/docs/api/javascript/class_webdriver_WebDriver_Logs.html +++ b/docs/api/javascript/class_webdriver_WebDriver_Logs.html @@ -1,4 +1,4 @@ -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. +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 @@ -6,5 +6,5 @@ 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 + 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/docs/api/javascript/class_webdriver_WebDriver_Navigation.html b/docs/api/javascript/class_webdriver_WebDriver_Navigation.html index d2ac0dbaedd33..864fb17629597 100644 --- a/docs/api/javascript/class_webdriver_WebDriver_Navigation.html +++ b/docs/api/javascript/class_webdriver_WebDriver_Navigation.html @@ -1,5 +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 +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/docs/api/javascript/class_webdriver_WebDriver_Options.html b/docs/api/javascript/class_webdriver_WebDriver_Options.html index 3e4e2f12badd6..f3025663723eb 100644 --- a/docs/api/javascript/class_webdriver_WebDriver_Options.html +++ b/docs/api/javascript/class_webdriver_WebDriver_Options.html @@ -1,17 +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 +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 + 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 + 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. + 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 + 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/docs/api/javascript/class_webdriver_WebDriver_TargetLocator.html b/docs/api/javascript/class_webdriver_WebDriver_TargetLocator.html index b63420e12a413..65817d5587062 100644 --- a/docs/api/javascript/class_webdriver_WebDriver_TargetLocator.html +++ b/docs/api/javascript/class_webdriver_WebDriver_TargetLocator.html @@ -1,10 +1,10 @@ -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 +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 + available.

      Returns
      The active element.

      Schedules a command to change focus to the active alert dialog. This command + will return a bot.ErrorCode.NO_SUCH_ALERT error if an alert 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 + 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 @@ -17,11 +17,11 @@

      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 + 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 + when the driver has changed focus to the specified window.

      Instance Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_WebDriver_Timeouts.html b/docs/api/javascript/class_webdriver_WebDriver_Timeouts.html index 918a6bc798388..2f074f05777c4 100644 --- a/docs/api/javascript/class_webdriver_WebDriver_Timeouts.html +++ b/docs/api/javascript/class_webdriver_WebDriver_Timeouts.html @@ -1,4 +1,4 @@ -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 +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 @@ -13,9 +13,9 @@ 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 + 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 + 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 + when the script timeout has been set.

      Instance Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_WebDriver_Window.html b/docs/api/javascript/class_webdriver_WebDriver_Window.html index 16c11836f3b9e..b06f8cc7faa35 100644 --- a/docs/api/javascript/class_webdriver_WebDriver_Window.html +++ b/docs/api/javascript/class_webdriver_WebDriver_Window.html @@ -1,11 +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 +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 + {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 + {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 + 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/docs/api/javascript/class_webdriver_WebElement.html b/docs/api/javascript/class_webdriver_WebElement.html index 4f34f4126d720..f0435375eed75 100644 --- a/docs/api/javascript/class_webdriver_WebElement.html +++ b/docs/api/javascript/class_webdriver_WebElement.html @@ -1,6 +1,4 @@ -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 +webdriver.WebElement

      Class webdriver.WebElement

      code »

      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:

      
      @@ -21,13 +19,12 @@
            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 + element.

      id: !(webdriver.promise.Promise.<webdriver.WebElement.Id>|webdriver.WebElement.Id)
      The server-assigned opaque ID for the + underlying DOM element.
      Show:

      Type Definitions

      Wire protocol definition of a WebElement ID.

      Instance Methods

      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 + 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 @@ -61,10 +58,10 @@

      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 + 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 + 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 @@ -88,7 +85,7 @@

    • "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 + 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 @@ -97,27 +94,29 @@ 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 + resolved with the requested CSS value.
      Returns
      The parent driver for this instance.
      Returns
      A promise + that resolves to this element's JSON representation as defined by the + WebDriver wire protocol.

      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 + {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 + {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 + 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 + 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 + 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 + 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 @@ -151,81 +150,9 @@ 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 + 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 + when the form has been submitted.

      Instance Properties

      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/docs/api/javascript/class_webdriver_WebElementPromise.html b/docs/api/javascript/class_webdriver_WebElementPromise.html new file mode 100644 index 0000000000000..6c6f9aa31c8fd --- /dev/null +++ b/docs/api/javascript/class_webdriver_WebElementPromise.html @@ -0,0 +1,147 @@ +webdriver.WebElementPromise

      Class webdriver.WebElementPromise

      code »
      webdriver.WebElement
      +  └ webdriver.WebElementPromise
      All implemented interfaces:
      webdriver.promise.Thenable.<webdriver.WebElement>

      WebElementPromise is a promise that will be fulfilled with a WebElement. + This serves as a forward proxy on WebElement, allowing calls to be + scheduled without directly on this instance before the underlying + WebElement has been fulfilled. In other words, the following two statements + are equivalent: +

      
      +     driver.findElement({id: 'my-button'}).click();
      +     driver.findElement({id: 'my-button'}).then(function(el) {
      +       return el.click();
      +     });
      + 

      Constructor

      webdriver.WebElementPromise ( driver, el )
      Parameters
      driver: !webdriver.WebDriver
      The parent WebDriver instance for this + element.
      el: !webdriver.promise.Promise
      A promise + that will resolve to the promised element.
      Show:

      Instance Methods

      Defined in webdriver.WebElementPromise

      code »isPending ( )boolean

      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.
      Returns
      A promise + that resolves to this element's JSON representation as defined by the + WebDriver wire protocol.

      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.

      Instance Properties

      Defined in webdriver.WebElement

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_http_CorsClient.html b/docs/api/javascript/class_webdriver_http_CorsClient.html index 7a7b1f118af24..cbffd877677dd 100644 --- a/docs/api/javascript/class_webdriver_http_CorsClient.html +++ b/docs/api/javascript/class_webdriver_http_CorsClient.html @@ -30,4 +30,4 @@ 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 +

      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/docs/api/javascript/class_webdriver_http_Executor.html b/docs/api/javascript/class_webdriver_http_Executor.html index 1e656a36c529e..6082a43df5d5c 100644 --- a/docs/api/javascript/class_webdriver_http_Executor.html +++ b/docs/api/javascript/class_webdriver_http_Executor.html @@ -5,4 +5,4 @@ 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 + 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/docs/api/javascript/class_webdriver_http_Request.html b/docs/api/javascript/class_webdriver_http_Request.html index 2c4efb5e9bba6..d5619977966ec 100644 --- a/docs/api/javascript/class_webdriver_http_Request.html +++ b/docs/api/javascript/class_webdriver_http_Request.html @@ -1,4 +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 + 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/docs/api/javascript/class_webdriver_http_Response.html b/docs/api/javascript/class_webdriver_http_Response.html index c39d270d72653..6c4b1d483a700 100644 --- a/docs/api/javascript/class_webdriver_http_Response.html +++ b/docs/api/javascript/class_webdriver_http_Response.html @@ -1,3 +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 + XDomainRequest response object.
      Parameters
      xhr: !(XDomainRequest|XMLHttpRequest)
      The request to parse.
      Returns
      The parsed response.
      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_http_XhrClient.html b/docs/api/javascript/class_webdriver_http_XhrClient.html index d53dfaa096929..1ed338f5a30d4 100644 --- a/docs/api/javascript/class_webdriver_http_XhrClient.html +++ b/docs/api/javascript/class_webdriver_http_XhrClient.html @@ -1 +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 +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/docs/api/javascript/class_webdriver_logging_Entry.html b/docs/api/javascript/class_webdriver_logging_Entry.html index c6f0822e0d666..dc38ad599f43b 100644 --- a/docs/api/javascript/class_webdriver_logging_Entry.html +++ b/docs/api/javascript/class_webdriver_logging_Entry.html @@ -1,4 +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 +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 + 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/docs/api/javascript/class_webdriver_logging_Preferences.html b/docs/api/javascript/class_webdriver_logging_Preferences.html new file mode 100644 index 0000000000000..cc633e8b9617e --- /dev/null +++ b/docs/api/javascript/class_webdriver_logging_Preferences.html @@ -0,0 +1,2 @@ +webdriver.logging.Preferences

      Class webdriver.logging.Preferences

      code »

      Describes the log preferences for a WebDriver session.

      Constructor

      webdriver.logging.Preferences ( )
      Show:

      Instance Methods

      code »setLevel ( type, level )

      Sets the desired logging level for a particular log type.

      Parameters
      type: (string|webdriver.logging.Type)
      The log type.
      level: !webdriver.logging.Level
      The desired log level.

      Converts this instance to its JSON representation.

      Returns
      The JSON representation of this set of + preferences.

      Instance Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_promise_CanceledTaskError_.html b/docs/api/javascript/class_webdriver_promise_CanceledTaskError_.html index 5c5061396cdc2..95c978bb2b50f 100644 --- a/docs/api/javascript/class_webdriver_promise_CanceledTaskError_.html +++ b/docs/api/javascript/class_webdriver_promise_CanceledTaskError_.html @@ -1,4 +1,4 @@ -webdriver.promise.CanceledTaskError_

      Class webdriver.promise.CanceledTaskError_

      code »
      Error
      +webdriver.promise.CanceledTaskError_

      Class webdriver.promise.CanceledTaskError_

      code »
      Errorgoog.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 + 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/docs/api/javascript/class_webdriver_promise_ControlFlow.html b/docs/api/javascript/class_webdriver_promise_ControlFlow.html index b76cc7e840c01..872a5ab005e87 100644 --- a/docs/api/javascript/class_webdriver_promise_ControlFlow.html +++ b/docs/api/javascript/class_webdriver_promise_ControlFlow.html @@ -1,4 +1,4 @@ -webdriver.promise.ControlFlow

      Class webdriver.promise.ControlFlow

      code »
      webdriver.EventEmitter
      +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 @@ -23,44 +23,46 @@ 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 + 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 + 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 + abort; usually either an Error or string value.

      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 + 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 + 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 + 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. If + the task function is a generator, the task will be executed using + webdriver.promise.consume.

      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 + 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 + 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 + 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 + 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 + 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, @@ -80,12 +82,12 @@ 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 + 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. + 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 @@ -96,11 +98,11 @@

      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 + 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 + 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 @@ -113,5 +115,5 @@ 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 + 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/docs/api/javascript/class_webdriver_promise_Deferred.html b/docs/api/javascript/class_webdriver_promise_Deferred.html index 97444694edf8e..430ae0c86187b 100644 --- a/docs/api/javascript/class_webdriver_promise_Deferred.html +++ b/docs/api/javascript/class_webdriver_promise_Deferred.html @@ -1,5 +1,5 @@ -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 +webdriver.promise.Deferred

      Class webdriver.promise.Deferred.<T>

      code »
      webdriver.promise.Promise.<(T|null)>
      +  └ webdriver.promise.Deferred
      All implemented interfaces:
      webdriver.promise.Thenable.<(T|null)>

      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 @@ -14,73 +14,14 @@ 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 + 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 + 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 + 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 + 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 )
      Parameters
      reason
      code »isPending ( )boolean
      code »then ( opt_callback, opt_errback )
      Parameters
      opt_callback
      opt_errback
      code »thenCatch ( errback )
      Parameters
      errback
      code »thenFinally ( callback )
      Parameters
      callback

      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 + fulfilled or rejected state, at which point the promise is considered + resolved.

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_promise_Frame_.html b/docs/api/javascript/class_webdriver_promise_Frame_.html index a13555e573ee9..19134a691caa9 100644 --- a/docs/api/javascript/class_webdriver_promise_Frame_.html +++ b/docs/api/javascript/class_webdriver_promise_Frame_.html @@ -1,14 +1,14 @@ -webdriver.promise.Frame_

      Class webdriver.promise.Frame_

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

      Class webdriver.promise.Frame_

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

      An execution frame within a webdriver.promise.ControlFlow. Each + └ webdriver.promise.Frame_

      All implemented interfaces:
      webdriver.promise.Thenable.<(T|null)>

      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 + 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: @@ -27,71 +27,14 @@ // 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 + 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 + 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 + 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 )
      Parameters
      reason
      code »isPending ( )boolean
      code »then ( opt_callback, opt_errback )
      Parameters
      opt_callback
      opt_errback
      code »thenCatch ( errback )
      Parameters
      errback
      code »thenFinally ( callback )
      Parameters
      callback

      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 @@ -104,15 +47,13 @@ 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 +

      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 + 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 + fulfilled or rejected state, at which point the promise is considered + resolved.

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_promise_Node_.html b/docs/api/javascript/class_webdriver_promise_Node_.html index f3df4ae674023..666e39a0f52af 100644 --- a/docs/api/javascript/class_webdriver_promise_Node_.html +++ b/docs/api/javascript/class_webdriver_promise_Node_.html @@ -1,73 +1,14 @@ -webdriver.promise.Node_

      Class webdriver.promise.Node_

      code »
      webdriver.promise.Promise.<(T|null)>
      +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 + └ webdriver.promise.Node_

      All implemented interfaces:
      webdriver.promise.Thenable.<(T|null)>

      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 + 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 + 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 + 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 )
      Parameters
      reason
      code »isPending ( )boolean
      code »then ( opt_callback, opt_errback )
      Parameters
      opt_callback
      opt_errback
      code »thenCatch ( errback )
      Parameters
      errback
      code »thenFinally ( callback )
      Parameters
      callback

      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 + fulfilled or rejected state, at which point the promise is considered + resolved.

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_promise_Promise.html b/docs/api/javascript/class_webdriver_promise_Promise.html index ed14e51b3588d..691829b7feb75 100644 --- a/docs/api/javascript/class_webdriver_promise_Promise.html +++ b/docs/api/javascript/class_webdriver_promise_Promise.html @@ -1,64 +1,5 @@ -webdriver.promise.Promise

      Class webdriver.promise.Promise.<T>

      code »

      Represents the eventual value of a completed operation. Each promise may be +webdriver.promise.Promise

      Class webdriver.promise.Promise.<T>

      code »
      All implemented interfaces:
      webdriver.promise.Thenable.<(T|null)>

      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 + fulfilled or rejected state, at which point the promise is considered + resolved.

      Constructor

      webdriver.promise.Promise ( )
      Show:

      Instance Methods

      code »cancel ( reason )
      Parameters
      reason
      code »isPending ( )boolean
      code »then ( opt_callback, opt_errback )
      Parameters
      opt_callback
      opt_errback
      code »thenCatch ( errback )
      Parameters
      errback
      code »thenFinally ( callback )
      Parameters
      callback
      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_promise_Task_.html b/docs/api/javascript/class_webdriver_promise_Task_.html index 3400fedb85bef..f226db6a328d3 100644 --- a/docs/api/javascript/class_webdriver_promise_Task_.html +++ b/docs/api/javascript/class_webdriver_promise_Task_.html @@ -1,77 +1,18 @@ -webdriver.promise.Task_

      Class webdriver.promise.Task_

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

      Class webdriver.promise.Task_

      code »
      webdriver.promise.Promise.<(T|null)>
         └ webdriver.promise.Deferredwebdriver.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 + └ webdriver.promise.Task_
      All implemented interfaces:
      webdriver.promise.Thenable.<(T|null)>

      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 + 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 + 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 + 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 + 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 )
      Parameters
      reason
      code »isPending ( )boolean
      code »then ( opt_callback, opt_errback )
      Parameters
      opt_callback
      opt_errback
      code »thenCatch ( errback )
      Parameters
      errback
      code »thenFinally ( callback )
      Parameters
      callback

      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 + fulfilled or rejected state, at which point the promise is considered + resolved.

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_stacktrace_Frame.html b/docs/api/javascript/class_webdriver_stacktrace_Frame.html index 68edecc93af94..7ca7c92d025c4 100644 --- a/docs/api/javascript/class_webdriver_stacktrace_Frame.html +++ b/docs/api/javascript/class_webdriver_stacktrace_Frame.html @@ -5,4 +5,4 @@ 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 + 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/docs/api/javascript/class_webdriver_stacktrace_Snapshot.html b/docs/api/javascript/class_webdriver_stacktrace_Snapshot.html index 0484ea1b8f121..479f5d719ae18 100644 --- a/docs/api/javascript/class_webdriver_stacktrace_Snapshot.html +++ b/docs/api/javascript/class_webdriver_stacktrace_Snapshot.html @@ -2,4 +2,4 @@ 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 + computes the context correctly. \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_testing_Assertion.html b/docs/api/javascript/class_webdriver_testing_Assertion.html index 8aee79ed24e20..0a27496909d22 100644 --- a/docs/api/javascript/class_webdriver_testing_Assertion.html +++ b/docs/api/javascript/class_webdriver_testing_Assertion.html @@ -29,4 +29,4 @@ 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 + webdriver.testing.assert(x).not.equalTo(y); \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_testing_Assertion_DelegatingMatcher_.html b/docs/api/javascript/class_webdriver_testing_Assertion_DelegatingMatcher_.html index 22a3d65299bac..1b3117692dac8 100644 --- a/docs/api/javascript/class_webdriver_testing_Assertion_DelegatingMatcher_.html +++ b/docs/api/javascript/class_webdriver_testing_Assertion_DelegatingMatcher_.html @@ -1,3 +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 + 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/docs/api/javascript/class_webdriver_testing_ContainsMatcher.html b/docs/api/javascript/class_webdriver_testing_ContainsMatcher.html index d56b8a3109862..3de5f5f8145c1 100644 --- a/docs/api/javascript/class_webdriver_testing_ContainsMatcher.html +++ b/docs/api/javascript/class_webdriver_testing_ContainsMatcher.html @@ -1 +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 +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/docs/api/javascript/class_webdriver_testing_NegatedAssertion.html b/docs/api/javascript/class_webdriver_testing_NegatedAssertion.html index 6a7d0736735db..cf528bd8c12f0 100644 --- a/docs/api/javascript/class_webdriver_testing_NegatedAssertion.html +++ b/docs/api/javascript/class_webdriver_testing_NegatedAssertion.html @@ -23,4 +23,4 @@ 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 + webdriver.testing.assert(x).not.equalTo(y);

      Static Properties

      \ No newline at end of file diff --git a/docs/api/javascript/class_webdriver_testing_TestCase.html b/docs/api/javascript/class_webdriver_testing_TestCase.html new file mode 100644 index 0000000000000..071792f9357f9 --- /dev/null +++ b/docs/api/javascript/class_webdriver_testing_TestCase.html @@ -0,0 +1,76 @@ +webdriver.testing.TestCase

      Class webdriver.testing.TestCase

      code »
      goog.testing.TestCase
      +  └ webdriver.testing.TestCase

      Constructs a test case that synchronizes each test case with the singleton + webdriver.promise.ControlFlow.

      Constructor

      webdriver.testing.TestCase ( client, opt_name )
      Parameters
      client: !webdriver.testing.Client
      The test client to use for + reporting test results.
      opt_name: string=
      The name of the test case, defaults to + 'Untitled Test Case'.
      Show:

      Instance Methods

      Defined in webdriver.testing.TestCase

      Executes the next test inside its own webdriver.Application.

      code »logError ( name, opt_e )goog.testing.TestCase.Error
      Parameters
      name
      opt_e

      Executes a single test, scheduling each phase with the global application. + Each phase will wait for the application to go idle before moving on to the + next test phase. This function models the follow basic test flow: + + try { + this.setUp.call(test.scope); + test.ref.call(test.scope); + } catch (ex) { + onError(ex); + } finally { + try { + this.tearDown.call(test.scope); + } catch (e) { + onError(e); + } + }

      Parameters
      test: !goog.testing.TestCase.Test
      The test to run.
      onError: function(*)
      The function to call each time an error is + detected.
      Returns
      A promise that will be resolved when the + test has finished running.

      Defined in goog.testing.TestCase

      code »add ( test )

      Adds a new test to the test case.

      Parameters
      test: goog.testing.TestCase.Test
      The test to add.
      code »addNewTest ( name, ref, opt_scope )

      Creates and adds a new test. + + Convenience function to make syntax less awkward when not using automatic + test discovery.

      Parameters
      name: string
      The test name.
      ref: !Function
      Reference to the test function.
      opt_scope: !Object=
      Optional scope that the test function should be + called in.

      Adds any functions defined in the global scope that correspond to + lifecycle events for the test case. Overrides setUp, tearDown, setUpPage, + tearDownPage and runTests if they are defined.

      Adds any functions defined in the global scope that are prefixed with "test" + to the test case.

      Clears a timeout created by this.timeout().

      Parameters
      id: number
      A timeout id.

      Counts the number of files that were loaded for dependencies that are + required to run the test.

      Returns
      The number of files loaded.

      Creates a goog.testing.TestCase.Test from an auto-discovered + function.

      Parameters
      name: string
      The name of the function.
      ref: function(): void
      The auto-discovered function.
      Returns
      The newly created test.
      code »doError ( test, opt_e )

      Handles a test that failed.

      Parameters
      test: goog.testing.TestCase.Test
      The test that failed.
      opt_e: *=
      The exception object associated with the + failure or a string.

      Handles a test that passed.

      Parameters
      test: goog.testing.TestCase.Test
      The test that passed.

      Executes each of the tests.

      Finalizes the test case, called when the tests have finished executing.

      Returns the number of tests actually run in the test case, i.e. subtracting + any which are skipped.

      Returns
      The number of un-ignored tests.
      Returns
      The function name prefix used to auto-discover tests.
      Returns
      Time since the last batch of tests was started.

      Returns the number of tests contained in the test case.

      Returns
      The number of tests.
      code »getGlobals ( opt_prefix )!Array

      Gets list of objects that potentially contain test cases. For IE 8 and below, + this is the global "this" (for properties set directly on the global this or + window) and the RuntimeObject (for global variables and functions). For all + other browsers, the array simply contains the global this.

      Parameters
      opt_prefix: string=
      An optional prefix. If specified, only get things + under this prefix. Note that the prefix is only honored in IE, since it + supports the RuntimeObject: + http://msdn.microsoft.com/en-us/library/ff521039%28VS.85%29.aspx + TODO: Remove this option.
      Returns
      A list of objects that should be inspected.
      Returns
      The name of the test.

      Returns the number of script files that were loaded in order to run the test.

      Returns
      The number of script files.
      code »getReport ( opt_verbose )string

      Returns a string detailing the results from the test.

      Parameters
      opt_verbose: boolean=
      If true results will include data about all + tests, not just what failed.
      Returns
      The results from the test.

      Returns the amount of time it took for the test to run.

      Returns
      The run time, in milliseconds.

      Returns the test results object: a map from test names to a list of test + failures (if any exist).

      Returns
      Tests results object.

      Gets the tests.

      Returns
      The test array.

      Returns the current time.

      Returns
      HH:MM:SS.
      Returns
      Whether the test case is running inside the multi test + runner.
      Returns
      Whether the test was a success.
      code »log ( val )

      Logs an object to the console, if available.

      Parameters
      val: *
      The value to log. Will be ToString'd.

      Checks to see if the test should be marked as failed before it is run. + + If there was an error in setUpPage, we treat that as a failure for all tests + and mark them all as having failed.

      Parameters
      testCase: goog.testing.TestCase.Test
      The current test case.
      Returns
      Whether the test was marked as failed.

      Returns the current test and increments the pointer.

      Returns
      The current test case.
      Returns
      The current time in milliseconds, don't use goog.now as some + tests override it.

      Reorders the tests depending on the order field.

      Parameters
      tests: Array.<goog.testing.TestCase.Test>
      An array of tests to + reorder.
      code »pad_ ( number )string

      Pads a number to make it have a leading zero if it's less than 10.

      Parameters
      number: number
      The number to pad.
      Returns
      The resulting string.

      Resets the test case pointer, so that next returns the first test.

      Executes each of the tests. + Overridable by the individual test case. This allows test cases to defer + when the test is actually started. If overridden, finalize must be called + by the test to indicate it has finished.

      code »saveMessage ( message )

      Saves a message to the result set.

      Parameters
      message: string
      The message to save.
      code »setBatchTime ( batchTime )
      Parameters
      batchTime: number
      Time since the last batch of tests was started.

      Sets the callback function that should be executed when the tests have + completed.

      Parameters
      fn: Function
      The callback function.
      code »setTests ( tests )

      Sets the tests.

      Parameters
      tests: !Array.<goog.testing.TestCase.Test>
      A new test array.

      Gets called before every goog.testing.TestCase.Test is been executed. Can be + overridden to add set up functionality to each test.

      Gets called before any tests are executed. Can be overridden to set up the + environment for the whole test case.

      Can be overridden in test classes to indicate whether the tests in a case + should be run in that particular situation. For example, this could be used + to stop tests running in a particular browser, where browser support for + the class under test was absent.

      Returns
      Whether any of the tests in the case should be run.

      Gets called after every goog.testing.TestCase.Test has been executed. Can be + overriden to add tear down functionality to each test.

      Gets called after all tests have been executed. Can be overridden to tear + down the entire test case.

      code »timeout ( fn, time )number

      Calls a function after a delay, using the protected timeout.

      Parameters
      fn: Function
      The function to call.
      time: number
      Delay in milliseconds.
      Returns
      The timeout id.

      Trims a path to be only that after google3.

      Parameters
      path: string
      The path to trim.
      Returns
      The resulting string.

      Instance Properties

      Defined in webdriver.testing.TestCase

      code »client_ : !webdriver.testing.Client

      Defined in goog.testing.TestCase

      Time since the last batch of tests was started, if batchTime exceeds + #maxRunTime a timeout will be used to stop the tests blocking the + browser and a new batch will be started.

      Pointer to the current test.

      Exception object that was detected before a test runs.

      A name for the test case.

      Optional callback that will be executed when the test has finalized.

      The order to run the auto-discovered tests in.

      Object used to encapsulate the test results.

      Whether the test case is running.

      Timestamp for when the test was started.

      Whether the test case has ever tried to execute.

      Set of test names and/or indices to execute, or null if all tests should + be executed. + + Indices are included to allow automation tools to run a subset of the + tests without knowing the exact contents of the test file. + + Indices should only be used with SORTED ordering. + + Example valid values: +

        +
      • [testName] +
      • [testName1, testName2] +
      • [2] - will run the 3rd test in the order specified +
      • [1,3,5] +
      • [testName1, testName2, 3, 5] - will work +

        Array of test functions that can be executed.

        Static Properties

        \ No newline at end of file diff --git a/docs/api/javascript/dossier.js b/docs/api/javascript/dossier.js index b2ebb526ef5bf..ba88c19fc495c 100644 --- a/docs/api/javascript/dossier.js +++ b/docs/api/javascript/dossier.js @@ -2,7 +2,7 @@ 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(;c")&&(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={}; @@ -42,7 +42,7 @@ function ac(a){if(da(a)||!a||a.U)return!1;var b=a.src;if(Mb(b))return Sb(b.C,a); function cc(a,b){var c=a.K,d=a.ga||a.src;a.ea&&ac(a);return c.call(d,b)} function Zb(a,b){if(a.U)return!0;if(!Db){var c;if(!(c=b))a:{c=["window","event"];for(var d=m,e;e=c.shift();)if(null!=d[e])d=d[e];else{c=null;break a}c=d}e=c;c=new Q(e,this);d=!0;if(!(0>e.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}; +" "+d:d},ic=ec?function(a,b){a.classList.remove(b)}:function(a,b){S(a,b)&&(a.className=wa(fc(a),function(a){return a!=b}).join(" "))},jc=ec?function(a,b){A(b,function(b){ic(a,b)})}:function(a,b){a.className=wa(fc(a),function(a){return!(0<=va(b,a))}).join(" ")};function T(a,b,c,d){this.top=a;this.right=b;this.bottom=c;this.left=d}T.prototype.X=function(){return new T(this.top,this.right,this.bottom,this.left)};T.prototype.contains=function(a){return this&&a?a instanceof T?a.left>=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} @@ -97,14 +97,14 @@ h.A=function(a){if(-1==a)Td(this,-1);else for(var b=0;b=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 @@ -127,7 +127,7 @@ 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 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");if((b=ub(Bb,{types:b,I:ie,ya:!!c}))&&b.childNodes.length)return ob(d),a.appendChild(b),b;sc(a,!1);return 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 + http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes

        Values and Descriptions

        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/enum_bot_Error_State.html b/docs/api/javascript/enum_bot_Error_State.html index 49054c1dcb1fd..7b80a02e7de00 100644 --- a/docs/api/javascript/enum_bot_Error_State.html +++ b/docs/api/javascript/enum_bot_Error_State.html @@ -1 +1 @@ -bot.Error.State \ No newline at end of file +bot.Error.State \ No newline at end of file diff --git a/docs/api/javascript/enum_goog_Disposable_MonitoringMode.html b/docs/api/javascript/enum_goog_Disposable_MonitoringMode.html new file mode 100644 index 0000000000000..14cbf0487c6df --- /dev/null +++ b/docs/api/javascript/enum_goog_Disposable_MonitoringMode.html @@ -0,0 +1,6 @@ +goog.Disposable.MonitoringMode

        Enum goog.Disposable.MonitoringMode

        code »
        Type: number

        Values and Descriptions

        INTERACTIVE
        INTERACTIVE mode can be switched on and off on the fly without producing + errors. It also doesn't warn if the disposable objects don't call the + goog.Disposable base constructor.
        OFF
        No monitoring.
        PERMANENT
        Creating and disposing the goog.Disposable instances is monitored. All + disposable objects need to call the goog.Disposable base + constructor. The PERMANENT mode must be switched on before creating any + goog.Disposable instances.
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/enum_goog_dom_BrowserFeature.html b/docs/api/javascript/enum_goog_dom_BrowserFeature.html new file mode 100644 index 0000000000000..9aa63db72f6ee --- /dev/null +++ b/docs/api/javascript/enum_goog_dom_BrowserFeature.html @@ -0,0 +1,8 @@ +goog.dom.BrowserFeature

        Enum goog.dom.BrowserFeature

        code »
        Type: boolean

        Enum of browser capabilities.

        Values and Descriptions

        CAN_ADD_NAME_OR_TYPE_ATTRIBUTES
        Whether attributes 'name' and 'type' can be added to an element after it's + created. False in Internet Explorer prior to version 9.
        CAN_USE_CHILDREN_ATTRIBUTE
        Whether we can use element.children to access an element's Element + children. Available since Gecko 1.9.1, IE 9. (IE<9 also includes comment + nodes in the collection.)
        CAN_USE_INNER_TEXT
        Opera, Safari 3, and Internet Explorer 9 all support innerText but they + include text nodes in script and style tags. Not document-mode-dependent.
        CAN_USE_PARENT_ELEMENT_PROPERTY
        MSIE, Opera, and Safari>=4 support element.parentElement to access an + element's parent if it is an Element.
        INNER_HTML_NEEDS_SCOPED_ELEMENT
        Whether NoScope elements need a scoped element written before them in + innerHTML. + MSDN: http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx#1
        LEGACY_IE_RANGES
        Whether we use legacy IE range API.
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/enum_goog_dom_NodeType.html b/docs/api/javascript/enum_goog_dom_NodeType.html index a85c299eecddf..d90609874b3cd 100644 --- a/docs/api/javascript/enum_goog_dom_NodeType.html +++ b/docs/api/javascript/enum_goog_dom_NodeType.html @@ -7,4 +7,4 @@ 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 + 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/docs/api/javascript/enum_goog_dom_TagName.html b/docs/api/javascript/enum_goog_dom_TagName.html new file mode 100644 index 0000000000000..7e46c2dddabea --- /dev/null +++ b/docs/api/javascript/enum_goog_dom_TagName.html @@ -0,0 +1,2 @@ +goog.dom.TagName \ No newline at end of file diff --git a/docs/api/javascript/enum_goog_events_BrowserEvent_MouseButton.html b/docs/api/javascript/enum_goog_events_BrowserEvent_MouseButton.html new file mode 100644 index 0000000000000..01bc09bdc379f --- /dev/null +++ b/docs/api/javascript/enum_goog_events_BrowserEvent_MouseButton.html @@ -0,0 +1 @@ +goog.events.BrowserEvent.MouseButton

        Enum goog.events.BrowserEvent.MouseButton

        code »
        Type: number

        Normalized button constants for the mouse.

        Values and Descriptions

        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/enum_goog_events_BrowserFeature.html b/docs/api/javascript/enum_goog_events_BrowserFeature.html new file mode 100644 index 0000000000000..3bb8a01463623 --- /dev/null +++ b/docs/api/javascript/enum_goog_events_BrowserFeature.html @@ -0,0 +1,4 @@ +goog.events.BrowserFeature

        Enum goog.events.BrowserFeature

        code »
        Type: boolean

        Enum of browser capabilities.

        Values and Descriptions

        HAS_HTML5_NETWORK_EVENT_SUPPORT
        Whether HTML5 network online/offline events are supported.
        HAS_NAVIGATOR_ONLINE_PROPERTY
        Whether the navigator.onLine property is supported.
        HAS_W3C_BUTTON
        Whether the button attribute of the event is W3C compliant. False in + Internet Explorer prior to version 9; document-version dependent.
        HAS_W3C_EVENT_SUPPORT
        Whether the browser supports full W3C event model.
        HTML5_NETWORK_EVENTS_FIRE_ON_BODY
        Whether HTML5 network events fire on document.body, or otherwise the + window.
        SET_KEY_CODE_TO_PREVENT_DEFAULT
        To prevent default in IE7-8 for certain keydown events we need set the + keyCode to -1.
        TOUCH_ENABLED
        Whether touch is enabled in the browser.
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/enum_goog_events_CaptureSimulationMode.html b/docs/api/javascript/enum_goog_events_CaptureSimulationMode.html new file mode 100644 index 0000000000000..81b2ea689c3f8 --- /dev/null +++ b/docs/api/javascript/enum_goog_events_CaptureSimulationMode.html @@ -0,0 +1,3 @@ +goog.events.CaptureSimulationMode

        Enum goog.events.CaptureSimulationMode

        code »
        Type: number

        Values and Descriptions

        OFF_AND_FAIL
        Does not perform capture simulation. Will asserts in IE8- when you + add capture listeners.
        OFF_AND_SILENT
        Does not perform capture simulation, silently ignore capture + listeners.
        ON
        Performs capture simulation.
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/enum_goog_events_EventType.html b/docs/api/javascript/enum_goog_events_EventType.html new file mode 100644 index 0000000000000..0315e7f21c7a1 --- /dev/null +++ b/docs/api/javascript/enum_goog_events_EventType.html @@ -0,0 +1 @@ +goog.events.EventType \ No newline at end of file diff --git a/docs/api/javascript/enum_goog_events_KeyCodes.html b/docs/api/javascript/enum_goog_events_KeyCodes.html new file mode 100644 index 0000000000000..ffa4f95a4db3b --- /dev/null +++ b/docs/api/javascript/enum_goog_events_KeyCodes.html @@ -0,0 +1,22 @@ +goog.events.KeyCodes

        Enum goog.events.KeyCodes

        code »
        Type: number

        Key codes for common characters. + + This list is not localized and therefore some of the key codes are not + correct for non US keyboard layouts. See comments below.

        Values and Descriptions

        Show:

        Global Functions

        code »goog.events.KeyCodes.firesKeyPressEvent ( keyCode, opt_heldKeyCode, opt_shiftKey, opt_ctrlKey, opt_altKey )boolean

        Returns true if the key fires a keypress event in the current browser. + + Accoridng to MSDN [1] IE only fires keypress events for the following keys: + - Letters: A - Z (uppercase and lowercase) + - Numerals: 0 - 9 + - Symbols: ! @ # $ % ^ & * ( ) _ - + = < [ ] { } , . / ? \ | ' ` " ~ + - System: ESC, SPACEBAR, ENTER + + That's not entirely correct though, for instance there's no distinction + between upper and lower case letters. + + [1] http://msdn2.microsoft.com/en-us/library/ms536939(VS.85).aspx) + + Safari is similar to IE, but does not fire keypress for ESC. + + Additionally, IE6 does not fire keydown or keypress events for letters when + the control or alt keys are held down and the shift key is not. IE7 does + fire keydown in these cases, though, but not keypress.

        Parameters
        keyCode: number
        A key code.
        opt_heldKeyCode: number=
        Key code of a currently-held key.
        opt_shiftKey: boolean=
        Whether the shift key is held down.
        opt_ctrlKey: boolean=
        Whether the control key is held down.
        opt_altKey: boolean=
        Whether the alt key is held down.
        Returns
        Whether it's a key that fires a keypress event.

        Returns true if the key produces a character. + This does not cover characters on non-US keyboards (Russian, Hebrew, etc.).

        Parameters
        keyCode: number
        A key code.
        Returns
        Whether it's a character key.

        Returns true if the event contains a text modifying key.

        Parameters
        e: goog.events.BrowserEvent
        A key event.
        Returns
        Whether it's a text modifying key.

        Normalizes key codes from their Gecko-specific value to the general one.

        Parameters
        keyCode: number
        The native key code.
        Returns
        The normalized key code.

        Normalizes key codes from OS/Browser-specific value to the general one.

        Parameters
        keyCode: number
        The native key code.
        Returns
        The normalized key code.

        Normalizes key codes from their Mac WebKit-specific value to the general one.

        Parameters
        keyCode: number
        The native key code.
        Returns
        The normalized key code.
        \ No newline at end of file diff --git a/docs/api/javascript/enum_goog_net_XmlHttp_OptionType.html b/docs/api/javascript/enum_goog_net_XmlHttp_OptionType.html index 0a54e805c0542..32b87263bf864 100644 --- a/docs/api/javascript/enum_goog_net_XmlHttp_OptionType.html +++ b/docs/api/javascript/enum_goog_net_XmlHttp_OptionType.html @@ -1,4 +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 + handler instead of null.
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/enum_goog_net_XmlHttp_ReadyState.html b/docs/api/javascript/enum_goog_net_XmlHttp_ReadyState.html index 34c76b333eff4..7c4404e188c6b 100644 --- a/docs/api/javascript/enum_goog_net_XmlHttp_ReadyState.html +++ b/docs/api/javascript/enum_goog_net_XmlHttp_ReadyState.html @@ -1,3 +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 + 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/docs/api/javascript/enum_goog_string_Unicode.html b/docs/api/javascript/enum_goog_string_Unicode.html index becb661424cf7..e0c16832e3bf2 100644 --- a/docs/api/javascript/enum_goog_string_Unicode.html +++ b/docs/api/javascript/enum_goog_string_Unicode.html @@ -1 +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 +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/docs/api/javascript/enum_goog_testing_TestCase_Order.html b/docs/api/javascript/enum_goog_testing_TestCase_Order.html new file mode 100644 index 0000000000000..efa7872e6b8a5 --- /dev/null +++ b/docs/api/javascript/enum_goog_testing_TestCase_Order.html @@ -0,0 +1,2 @@ +goog.testing.TestCase.Order

        Enum goog.testing.TestCase.Order

        code »
        Type: string

        The order to run the auto-discovered tests.

        Values and Descriptions

        NATURAL
        This is browser dependent and known to be different in FF and Safari + compared to others.
        RANDOM
        Random order.
        SORTED
        Sorted based on the name.
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/enum_goog_uri_utils_CharCode_.html b/docs/api/javascript/enum_goog_uri_utils_CharCode_.html index 4c9fb9e9627e6..473287aa1ad5b 100644 --- a/docs/api/javascript/enum_goog_uri_utils_CharCode_.html +++ b/docs/api/javascript/enum_goog_uri_utils_CharCode_.html @@ -1 +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 +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/docs/api/javascript/enum_goog_uri_utils_ComponentIndex.html b/docs/api/javascript/enum_goog_uri_utils_ComponentIndex.html index 82afbbb582823..61588febc74f9 100644 --- a/docs/api/javascript/enum_goog_uri_utils_ComponentIndex.html +++ b/docs/api/javascript/enum_goog_uri_utils_ComponentIndex.html @@ -1 +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 +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/docs/api/javascript/enum_goog_uri_utils_StandardQueryParam.html b/docs/api/javascript/enum_goog_uri_utils_StandardQueryParam.html index ced027a958962..2ae6cf5df9a05 100644 --- a/docs/api/javascript/enum_goog_uri_utils_StandardQueryParam.html +++ b/docs/api/javascript/enum_goog_uri_utils_StandardQueryParam.html @@ -1 +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 +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/docs/api/javascript/enum_webdriver_Browser.html b/docs/api/javascript/enum_webdriver_Browser.html index a50d5662f33c0..37a7bb640b837 100644 --- a/docs/api/javascript/enum_webdriver_Browser.html +++ b/docs/api/javascript/enum_webdriver_Browser.html @@ -1 +1 @@ -webdriver.Browser

        Enum webdriver.Browser

        code »
        Type: string

        Recognized browser names.

        Values and Descriptions

        Show:
        \ No newline at end of file +webdriver.Browser

        Enum webdriver.Browser

        code »
        Type: string

        Recognized browser names.

        Values and Descriptions

        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/enum_webdriver_Button.html b/docs/api/javascript/enum_webdriver_Button.html index 7b2018b04706f..8d5524f466a5d 100644 --- a/docs/api/javascript/enum_webdriver_Button.html +++ b/docs/api/javascript/enum_webdriver_Button.html @@ -1 +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 +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/docs/api/javascript/enum_webdriver_Capability.html b/docs/api/javascript/enum_webdriver_Capability.html index a16afd9eef51c..a6bbb7f122d97 100644 --- a/docs/api/javascript/enum_webdriver_Capability.html +++ b/docs/api/javascript/enum_webdriver_Capability.html @@ -1,14 +1,16 @@ -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 +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, + webdriver.Browser enum.
        ELEMENT_SCROLL_BEHAVIOR
        Defines how elements should be scrolled into the viewport for interaction. + This capability will be set to zero (0) if elements are aligned with the + top of the viewport, or one (1) if aligned with the bottom. The default + behavior is to align with the top of the viewport.
        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 + use webdriver.Capability.UNEXPECTED_ALERT_BEHAVIOR.
        LOGGING_PREFS
        Key for the logging driver logging preferences.
        NATIVE_EVENTS
        Whether this session generates native events when simulating user input.
        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 + webdriver.Capability.ACCEPT_SSL_CERTS.
        SUPPORTS_APPLICATION_CACHE
        Whether the driver supports manipulating the app cache.
        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/docs/api/javascript/enum_webdriver_CommandName.html b/docs/api/javascript/enum_webdriver_CommandName.html index 51e2c1bbe6711..5449a9dbcb31e 100644 --- a/docs/api/javascript/enum_webdriver_CommandName.html +++ b/docs/api/javascript/enum_webdriver_CommandName.html @@ -1,2 +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 + 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/docs/api/javascript/enum_webdriver_FirefoxDomExecutor_Attribute_.html b/docs/api/javascript/enum_webdriver_FirefoxDomExecutor_Attribute_.html index 991d820ee56fd..e8dddada19702 100644 --- a/docs/api/javascript/enum_webdriver_FirefoxDomExecutor_Attribute_.html +++ b/docs/api/javascript/enum_webdriver_FirefoxDomExecutor_Attribute_.html @@ -1 +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 +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/docs/api/javascript/enum_webdriver_FirefoxDomExecutor_EventType_.html b/docs/api/javascript/enum_webdriver_FirefoxDomExecutor_EventType_.html index 77449ebcb0683..f59505ece8d74 100644 --- a/docs/api/javascript/enum_webdriver_FirefoxDomExecutor_EventType_.html +++ b/docs/api/javascript/enum_webdriver_FirefoxDomExecutor_EventType_.html @@ -1 +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 +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/docs/api/javascript/enum_webdriver_Key.html b/docs/api/javascript/enum_webdriver_Key.html index 68acdcf10dd5e..afa2867ee2596 100644 --- a/docs/api/javascript/enum_webdriver_Key.html +++ b/docs/api/javascript/enum_webdriver_Key.html @@ -1,9 +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

        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 + 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/docs/api/javascript/enum_webdriver_logging_Level.html b/docs/api/javascript/enum_webdriver_logging_Level.html index 96cce56872fba..be4d5554b2629 100644 --- a/docs/api/javascript/enum_webdriver_logging_Level.html +++ b/docs/api/javascript/enum_webdriver_logging_Level.html @@ -1 +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 +webdriver.logging.Level

        Enum webdriver.logging.Level

        code »
        Type: {value: number, name: string}

        Logging levels.

        Values and Descriptions

        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/enum_webdriver_logging_LevelName.html b/docs/api/javascript/enum_webdriver_logging_LevelName.html deleted file mode 100644 index 2df7088c31a61..0000000000000 --- a/docs/api/javascript/enum_webdriver_logging_LevelName.html +++ /dev/null @@ -1 +0,0 @@ -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/docs/api/javascript/enum_webdriver_logging_Type.html b/docs/api/javascript/enum_webdriver_logging_Type.html index c69f77797bd0b..c4657a140da2d 100644 --- a/docs/api/javascript/enum_webdriver_logging_Type.html +++ b/docs/api/javascript/enum_webdriver_logging_Type.html @@ -1 +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 +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/docs/api/javascript/enum_webdriver_promise_ControlFlow_EventType.html b/docs/api/javascript/enum_webdriver_promise_ControlFlow_EventType.html index 0375949b6e305..f0bb243a1d662 100644 --- a/docs/api/javascript/enum_webdriver_promise_ControlFlow_EventType.html +++ b/docs/api/javascript/enum_webdriver_promise_ControlFlow_EventType.html @@ -1,4 +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 +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.
        RESET
        Emitted when a ControlFlow has been reset.
        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 + queue and revert to its initial state.
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/enum_webdriver_promise_Deferred_State_.html b/docs/api/javascript/enum_webdriver_promise_Deferred_State_.html index cab3b5ada8603..80ca09e80c88b 100644 --- a/docs/api/javascript/enum_webdriver_promise_Deferred_State_.html +++ b/docs/api/javascript/enum_webdriver_promise_Deferred_State_.html @@ -1 +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 +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/docs/api/javascript/index.html b/docs/api/javascript/index.html index 9ae9991837e35..e8228624ef72f 100644 --- a/docs/api/javascript/index.html +++ b/docs/api/javascript/index.html @@ -59,4 +59,4 @@

        License

        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 + \ No newline at end of file diff --git a/docs/api/javascript/interface_goog_debug_EntryPointMonitor.html b/docs/api/javascript/interface_goog_debug_EntryPointMonitor.html new file mode 100644 index 0000000000000..e730ac1128662 --- /dev/null +++ b/docs/api/javascript/interface_goog_debug_EntryPointMonitor.html @@ -0,0 +1,11 @@ +goog.debug.EntryPointMonitor

        Interface goog.debug.EntryPointMonitor

        code »
        Show:

        Instance Methods

        Try to remove an instrumentation wrapper created by this monitor. + If the function passed to unwrap is not a wrapper created by this + monitor, then we will do nothing. + + Notice that some wrappers may not be unwrappable. For example, if other + monitors have applied their own wrappers, then it will be impossible to + unwrap them because their wrappers will have captured our wrapper. + + So it is important that entry points are unwrapped in the reverse + order that they were wrapped.

        Parameters
        fn: !Function
        A function to unwrap.
        Returns
        The unwrapped function, or fn if it was not + a wrapped function created by this monitor.
        code »wrap ( fn )!Function

        Instruments a function.

        Parameters
        fn: !Function
        A function to instrument.
        Returns
        The instrumented function.
        \ No newline at end of file diff --git a/docs/api/javascript/interface_goog_disposable_IDisposable.html b/docs/api/javascript/interface_goog_disposable_IDisposable.html new file mode 100644 index 0000000000000..54a34115ed98d --- /dev/null +++ b/docs/api/javascript/interface_goog_disposable_IDisposable.html @@ -0,0 +1,3 @@ +goog.disposable.IDisposable

        Interface goog.disposable.IDisposable

        code »

        Interface for a disposable object. If a instance requires cleanup + (references COM objects, DOM notes, or other disposable objects), it should + implement this interface (it may subclass goog.Disposable).

        Show:

        Instance Methods

        code »dispose ( )void

        Disposes of the object and its resources.

        Returns
        Nothing.
        Returns
        Whether the object has been disposed of.
        \ No newline at end of file diff --git a/docs/api/javascript/interface_goog_events_Listenable.html b/docs/api/javascript/interface_goog_events_Listenable.html new file mode 100644 index 0000000000000..e5837e8e03479 --- /dev/null +++ b/docs/api/javascript/interface_goog_events_Listenable.html @@ -0,0 +1,84 @@ +goog.events.Listenable

        Interface goog.events.Listenable

        code »

        A listenable interface. A listenable is an object with the ability + to dispatch/broadcast events to "event listeners" registered via + listen/listenOnce. + + The interface allows for an event propagation mechanism similar + to one offered by native browser event targets, such as + capture/bubble mechanism, stopping propagation, and preventing + default actions. Capture/bubble mechanism depends on the ancestor + tree constructed via #getParentEventTarget; this tree + must be directed acyclic graph. The meaning of default action(s) + in preventDefault is specific to a particular use case. + + Implementations that do not support capture/bubble or can not have + a parent listenable can simply not implement any ability to set the + parent listenable (and have #getParentEventTarget return + null). + + Implementation of this class can be used with or independently from + goog.events. + + Implementation must call #addImplementation(implClass).

        Show:

        Instance Methods

        Dispatches an event (or event like object) and calls all listeners + listening for events of this type. The type of the event is decided by the + type property on the event object. + + If any of the listeners returns false OR calls preventDefault then this + function will return false. If one of the capture listeners calls + stopPropagation, then the bubble listeners won't fire.

        Parameters
        e: goog.events.EventLike
        Event object.
        Returns
        If anyone called preventDefault on the event object (or + if any of the listeners returns false) this will also return false.
        code »<EVENTOBJ> fireListeners ( type, capture, eventObject )boolean

        Fires all registered listeners in this listenable for the given + type and capture mode, passing them the given eventObject. This + does not perform actual capture/bubble. Only implementors of the + interface should be using this.

        Parameters
        type: (string|!goog.events.EventId.<EVENTOBJ>)
        The type of the + listeners to fire.
        capture: boolean
        The capture mode of the listeners to fire.
        eventObject: EVENTOBJ
        The event object to fire.
        Returns
        Whether all listeners succeeded without + attempting to prevent default behavior. If any listener returns + false or called goog.events.Event#preventDefault, this returns + false.
        code »<SCOPE, EVENTOBJ> getListener ( type, listener, capture, opt_listenerScope )goog.events.ListenableKey

        Gets the goog.events.ListenableKey for the event or null if no such + listener is in use.

        Parameters
        type: (string|!goog.events.EventId.<EVENTOBJ>)
        The name of the event + without the 'on' prefix.
        listener: function(this: SCOPE, EVENTOBJ): (boolean|undefined)
        The + listener function to get.
        capture: boolean
        Whether the listener is a capturing listener.
        opt_listenerScope: SCOPE=
        Object in whose scope to call the + listener.
        Returns
        the found listener or null if not found.
        code »<EVENTOBJ> getListeners ( type, capture )!Array.<goog.events.ListenableKey>

        Gets all listeners in this listenable for the given type and + capture mode.

        Parameters
        type: (string|!goog.events.EventId)
        The type of the listeners to fire.
        capture: boolean
        The capture mode of the listeners to fire.
        Returns
        An array of registered + listeners.

        Returns the parent of this event target to use for capture/bubble + mechanism. + + NOTE(user): The name reflects the original implementation of + custom event target (goog.events.EventTarget). We decided + that changing the name is not worth it.

        Returns
        The parent EventTarget or null if + there is no parent.
        code »<EVENTOBJ> hasListener ( opt_type, opt_capture )boolean

        Whether there is any active listeners matching the specified + signature. If either the type or capture parameters are + unspecified, the function will match on the remaining criteria.

        Parameters
        opt_type: (string|!goog.events.EventId.<EVENTOBJ>)=
        Event type.
        opt_capture: boolean=
        Whether to check for capture or bubble + listeners.
        Returns
        Whether there is any active listeners matching + the requested type and/or capture phase.
        code »<SCOPE, EVENTOBJ> listen ( type, listener, opt_useCapture, opt_listenerScope )goog.events.ListenableKey

        Adds an event listener. A listener can only be added once to an + object and if it is added again the key for the listener is + returned. Note that if the existing listener is a one-off listener + (registered via listenOnce), it will no longer be a one-off + listener after a call to listen().

        Parameters
        type: (string|!goog.events.EventId.<EVENTOBJ>)
        The event type id.
        listener: function(this: SCOPE, EVENTOBJ): (boolean|undefined)
        Callback + method.
        opt_useCapture: boolean=
        Whether to fire in capture phase + (defaults to false).
        opt_listenerScope: SCOPE=
        Object in whose scope to call the + listener.
        Returns
        Unique key for the listener.
        code »<SCOPE, EVENTOBJ> listenOnce ( type, listener, opt_useCapture, opt_listenerScope )goog.events.ListenableKey

        Adds an event listener that is removed automatically after the + listener fired once. + + If an existing listener already exists, listenOnce will do + nothing. In particular, if the listener was previously registered + via listen(), listenOnce() will not turn the listener into a + one-off listener. Similarly, if there is already an existing + one-off listener, listenOnce does not modify the listeners (it is + still a once listener).

        Parameters
        type: (string|!goog.events.EventId.<EVENTOBJ>)
        The event type id.
        listener: function(this: SCOPE, EVENTOBJ): (boolean|undefined)
        Callback + method.
        opt_useCapture: boolean=
        Whether to fire in capture phase + (defaults to false).
        opt_listenerScope: SCOPE=
        Object in whose scope to call the + listener.
        Returns
        Unique key for the listener.

        Removes all listeners from this listenable. If type is specified, + it will only remove listeners of the particular type. otherwise all + registered listeners will be removed.

        Parameters
        opt_type: string=
        Type of event to remove, default is to + remove all types.
        Returns
        Number of listeners removed.
        code »<SCOPE, EVENTOBJ> unlisten ( type, listener, opt_useCapture, opt_listenerScope )boolean

        Removes an event listener which was added with listen() or listenOnce().

        Parameters
        type: (string|!goog.events.EventId.<EVENTOBJ>)
        The event type id.
        listener: function(this: SCOPE, EVENTOBJ): (boolean|undefined)
        Callback + method.
        opt_useCapture: boolean=
        Whether to fire in capture phase + (defaults to false).
        opt_listenerScope: SCOPE=
        Object in whose scope to call + the listener.
        Returns
        Whether any listener was removed.

        Removes an event listener which was added with listen() by the key + returned by listen().

        Parameters
        key: goog.events.ListenableKey
        The key returned by + listen() or listenOnce().
        Returns
        Whether any listener was removed.

        Global Functions

        Marks a given class (constructor) as an implementation of + Listenable, do that we can query that fact at runtime. The class + must have already implemented the interface.

        Parameters
        cls: !Function
        The class constructor. The corresponding + class must have already implemented the interface.
        Parameters
        obj: Object
        The object to check.
        Returns
        Whether a given instance implements Listenable. The + class/superclass of the instance must call addImplementation.

        Global Properties

        An expando property to indicate that an object implements + goog.events.Listenable. + + See addImplementation/isImplementedBy.

        \ No newline at end of file diff --git a/docs/api/javascript/interface_goog_events_ListenableKey.html b/docs/api/javascript/interface_goog_events_ListenableKey.html new file mode 100644 index 0000000000000..53fd38b0e280d --- /dev/null +++ b/docs/api/javascript/interface_goog_events_ListenableKey.html @@ -0,0 +1,2 @@ +goog.events.ListenableKey

        Interface goog.events.ListenableKey

        code »

        An interface that describes a single registered listener.

        Show:

        Instance Properties

        Whether the listener works on capture phase.

        The 'this' object for the listener function's scope.

        A globally unique number to identify the key.

        code »listener : (function(?): ?|{handleEvent: function(?): ?}|null)

        The listener function.

        The event type the listener is listening to.

        Global Functions

        Reserves a key to be used for ListenableKey#key field.

        Returns
        A number to be used to fill ListenableKey#key + field.

        Global Properties

        Counter used to create a unique key

        \ No newline at end of file diff --git a/docs/api/javascript/interface_goog_labs_testing_Matcher.html b/docs/api/javascript/interface_goog_labs_testing_Matcher.html index fb8e889593247..9495c9b1164c7 100644 --- a/docs/api/javascript/interface_goog_labs_testing_Matcher.html +++ b/docs/api/javascript/interface_goog_labs_testing_Matcher.html @@ -1,2 +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 + 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/docs/api/javascript/interface_goog_net_XhrLike.html b/docs/api/javascript/interface_goog_net_XhrLike.html index 38583289d9f08..ebff7e3475fa1 100644 --- a/docs/api/javascript/interface_goog_net_XhrLike.html +++ b/docs/api/javascript/interface_goog_net_XhrLike.html @@ -1,3 +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 + 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/docs/api/javascript/interface_goog_structs_Collection.html b/docs/api/javascript/interface_goog_structs_Collection.html new file mode 100644 index 0000000000000..e94fe4809440d --- /dev/null +++ b/docs/api/javascript/interface_goog_structs_Collection.html @@ -0,0 +1 @@ +goog.structs.Collection

        Interface goog.structs.Collection.<T>

        code »

        An interface for a collection of values.

        Show:

        Instance Methods

        code »add ( value )
        Parameters
        value: T
        Value to add to the collection.
        code »contains ( value )boolean
        Parameters
        value: T
        Value to find in the collection.
        Returns
        Whether the collection contains the specified value.
        Returns
        The number of values stored in the collection.
        code »remove ( value )
        Parameters
        value: T
        Value to remove from the collection.
        \ No newline at end of file diff --git a/docs/api/javascript/interface_goog_testing_MockInterface.html b/docs/api/javascript/interface_goog_testing_MockInterface.html new file mode 100644 index 0000000000000..c5af2d40f7542 --- /dev/null +++ b/docs/api/javascript/interface_goog_testing_MockInterface.html @@ -0,0 +1,3 @@ +goog.testing.MockInterface

        Interface goog.testing.MockInterface

        code »
        Show:

        Instance Methods

        Write down all the expected functions that have been called on the + mock so far. From here on out, future function calls will be + compared against this list.

        Reset the mock.

        Assert that the expected function calls match the actual calls.

        \ No newline at end of file diff --git a/docs/api/javascript/interface_webdriver_CommandExecutor.html b/docs/api/javascript/interface_webdriver_CommandExecutor.html index 9b45f411a9e0b..d70a6bc694ca4 100644 --- a/docs/api/javascript/interface_webdriver_CommandExecutor.html +++ b/docs/api/javascript/interface_webdriver_CommandExecutor.html @@ -2,4 +2,4 @@ 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 + to invoke when the command response is ready. \ No newline at end of file diff --git a/docs/api/javascript/interface_webdriver_http_Client.html b/docs/api/javascript/interface_webdriver_http_Client.html index 68f0fcce5a5a9..7d7ee7256407c 100644 --- a/docs/api/javascript/interface_webdriver_http_Client.html +++ b/docs/api/javascript/interface_webdriver_http_Client.html @@ -3,4 +3,4 @@ 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 + invoke when the server's response is ready. \ No newline at end of file diff --git a/docs/api/javascript/interface_webdriver_promise_Thenable.html b/docs/api/javascript/interface_webdriver_promise_Thenable.html new file mode 100644 index 0000000000000..aef12e5f5a5fa --- /dev/null +++ b/docs/api/javascript/interface_webdriver_promise_Thenable.html @@ -0,0 +1,65 @@ +webdriver.promise.Thenable

        Interface webdriver.promise.Thenable.<T>

        code »

        Thenable is a promise-like object with a then method which may be + used to schedule callbacks on a promised value.

        Show:

        Instance Methods

        code »cancel ( opt_reason )

        Cancels the computation of this promise's value, rejecting the promise in the + process. This method is a no-op if the promise has alreayd been resolved.

        Parameters
        opt_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.

        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.

        Global Functions

        Adds a property to a class prototype to allow runtime checks of whether + instances of that class implement the Thenable interface. This function will + also ensure the prototype's then function is exported from compiled + code.

        Parameters
        ctor: function(new: webdriver.promise.Thenable, ?)
        The + constructor whose prototype to modify.

        Checks if an object has been tagged for implementing the Thenable interface + as defined by webdriver.promise.Thenable.addImplementation.

        Parameters
        object: *
        The object to test.
        Returns
        Whether the object is an implementation of the Thenable + interface.

        Global Properties

        Property used to flag constructor's as implementing the Thenable interface + for runtime type checking.

        \ No newline at end of file diff --git a/docs/api/javascript/license.html b/docs/api/javascript/license.html index 962258d729a40..3c544de5efc34 100644 --- a/docs/api/javascript/license.html +++ b/docs/api/javascript/license.html @@ -202,4 +202,4 @@ See the License for the specific language governing permissions and limitations under the License. - \ No newline at end of file + \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver.html b/docs/api/javascript/module_selenium-webdriver.html index 2764d07aa8090..a1310c6e28852 100644 --- a/docs/api/javascript/module_selenium-webdriver.html +++ b/docs/api/javascript/module_selenium-webdriver.html @@ -1,4 +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 + 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.
        WebElementPromise
        WebElementPromise is a promise that will be fulfilled with a WebElement.

        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 + instances. \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver__base.html b/docs/api/javascript/module_selenium-webdriver__base.html index 02cc0a118bc3b..453b4aa87a39b 100644 --- a/docs/api/javascript/module_selenium-webdriver__base.html +++ b/docs/api/javascript/module_selenium-webdriver__base.html @@ -7,8 +7,8 @@

        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 + scripts will be loaded from the Selenium client containing this script.

        Classes

        Context
        Maintains a unique context for Closure library-based code.
        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 + 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/docs/api/javascript/module_selenium-webdriver__base_class_Context.html b/docs/api/javascript/module_selenium-webdriver__base_class_Context.html new file mode 100644 index 0000000000000..7737dc3bd3ee2 --- /dev/null +++ b/docs/api/javascript/module_selenium-webdriver__base_class_Context.html @@ -0,0 +1,3 @@ +Context

        Class Context

        code »

        Maintains a unique context for Closure library-based code.

        Constructor

        Context ( opt_configureForTesting )
        Parameters
        opt_configureForTesting: boolean=
        Whether to configure a fake DOM + for Closure-testing code that (incorrectly) assumes a DOM is always + present.
        Show:

        Instance Properties

        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_builder.html b/docs/api/javascript/module_selenium-webdriver_builder.html index 6b208417b6d7b..5da6d3a54dd5e 100644 --- a/docs/api/javascript/module_selenium-webdriver_builder.html +++ b/docs/api/javascript/module_selenium-webdriver_builder.html @@ -1 +1 @@ -selenium-webdriver/builder

        Module selenium-webdriver/builder

        code »

        Classes

        Builder
        Creates new WebDriver instances.
        Show:
        \ No newline at end of file +selenium-webdriver/builder

        Module selenium-webdriver/builder

        code »

        Classes

        Builder
        Creates new WebDriver instances.
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_builder_class_Builder.html b/docs/api/javascript/module_selenium-webdriver_builder_class_Builder.html index bac7e534aed25..fdf32f7147950 100644 --- a/docs/api/javascript/module_selenium-webdriver_builder_class_Builder.html +++ b/docs/api/javascript/module_selenium-webdriver_builder_class_Builder.html @@ -1,13 +1,56 @@ -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

        Class Builder

        code »

        Creates new WebDriver instances. The environment + variables listed below may be used to override a builder's configuration, + allowing quick runtime changes. +

          +
        • SELENIUM_REMOTE_URL: defines the remote URL for all builder + instances. This environment variable should be set to a fully qualified + URL for a WebDriver server (e.g. http://localhost:4444/wd/hub). + +
        • SELENIUM_BROWSER: defines the target browser in the form + browser[:version][:platform]. +
        + +

        Suppose you had mytest.js that created WebDriver with + var driver = new webdriver.Builder().build();. + + This test could be made to use Firefox on the local machine by running with + SELENIUM_BROWSER=firefox node mytest.js. + +

        Alternatively, you could request Chrome 36 on Linux from a remote + server with SELENIUM_BROWSER=chrome:36:LINUX + SELENIUM_REMOTE_URL=http://www.example.com:4444/wd/hub + node mytest.js.

        Constructor

        Builder ( )
        Show:

        Instance Methods

        Creates a new WebDriver client based on this builder's current + configuration.

        Returns
        A new WebDriver instance.
        Throws
        Error
        If the current configuration is invalid.
        code »forBrowser ( name, opt_version, opt_platform )!Builder

        Configures the target browser for clients created by this instance. + Any calls to #withCapabilities after this function will + overwrite these settings. + +

        You may also define the target browser using the SELENIUM_BROWSER + environment variable. If set, this environment variable should be of the + form browser[:[version][:platform]].

        Parameters
        name: (string|webdriver.Browser)
        The name of the target browser; + common defaults are available on the webdriver.Browser enum.
        opt_version: string=
        A desired version; may be omitted if any + version should be used.
        opt_platform: string=
        The desired platform; may be omitted if any + version may be used.
        Returns
        A self reference.

        Returns the base set of capabilities this instance is currently configured + to use.

        Returns
        The current capabilities for this builder.
        Returns
        The URL of the WebDriver server this instance is configured + to use.
        code »setAlertBehavior ( behavior )!Builder

        Sets the default action to take with an unexpected alert before returning + an error.

        Parameters
        behavior
        Returns
        A self reference.
        code »setChromeOptions ( options )!Builder

        Sets Chrome-specific options for drivers created by this builder. Any + logging or proxy settings defined on the given options will take precedence + over those set through #setLoggingPrefs and #setProxy, + respectively.

        Parameters
        options: !chrome.Options
        The ChromeDriver options to use.
        Returns
        A self reference.
        code »setControlFlow ( flow )!Builder

        Sets the control flow that created drivers should execute actions in. If + the flow is never set, or is set to null, it will use the active + flow at the time #build() is called.

        Parameters
        flow: webdriver.promise.ControlFlow
        The control flow to use, or + null to
        Returns
        A self reference.
        code »setEnableNativeEvents ( enabled )!Builder

        Sets whether native events should be used.

        Parameters
        enabled: boolean
        Whether to enable native events.
        Returns
        A self reference.
        code »setFirefoxOptions ( options )!Builder

        Sets Firefox-specific options for drivers created by this builder. Any + logging or proxy settings defined on the given options will take precedence + over those set through #setLoggingPrefs and #setProxy, + respectively.

        Parameters
        options: !firefox.Options
        The FirefoxDriver options to use.
        Returns
        A self reference.
        code »setLoggingPrefs ( prefs )!Builder

        Sets the logging preferences for the created session. Preferences may be + changed by repeated calls, or by calling #withCapabilities.

        Parameters
        prefs: !(webdriver.logging.Preferences|Object.<string, string>)
        The + desired logging preferences.
        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 + overwrite these settings.
        Parameters
        config: !webdriver.ProxyConfig
        The configuration to use.
        Returns
        A self reference.
        code »setScrollBehavior ( behavior )!Builder

        Sets how elements should be scrolled into view for interaction.

        Parameters
        behavior: number
        The desired scroll behavior: either 0 to align with + the top of the viewport or 1 to align with the bottom.
        Returns
        A self reference.
        code »usingServer ( url )!Builder

        Sets the URL of a remote WebDriver server to use. Once a remote URL has been + specified, the builder direct all new clients to that server. If this method + is never called, the Builder will attempt to create all clients locally. + +

        As an alternative to this method, you may also set the + SELENIUM_REMOTE_URL environment variable.

        Parameters
        url: string
        The URL of a remote server to use.
        Returns
        A self reference.
        code »withCapabilities ( capabilities )!Builder

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

        Parameters
        capabilities: !(Object|webdriver.Capabilities)
        The desired + capabilities for a new session.
        Returns
        A self reference.

        Instance Properties

        code »chromeOptions_ : chrome.Options
        code »firefoxOptions_ : firefox.Options
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_chrome.html b/docs/api/javascript/module_selenium-webdriver_chrome.html index 3adf8b7b303d0..345345ac42a54 100644 --- a/docs/api/javascript/module_selenium-webdriver_chrome.html +++ b/docs/api/javascript/module_selenium-webdriver_chrome.html @@ -1,5 +1,6 @@ -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 +selenium-webdriver/chrome

        Module selenium-webdriver/chrome

        code »

        Classes

        Driver
        Creates a new WebDriver client for Chrome.
        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, opt_flow )!webdriver.WebDriver
        Deprecated: Use new Driver().

        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.
        opt_flow: webdriver.promise.ControlFlow=
        The control flow to use, or + null to use the currently active flow.
        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 + 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/docs/api/javascript/module_selenium-webdriver_chrome_class_Driver.html b/docs/api/javascript/module_selenium-webdriver_chrome_class_Driver.html new file mode 100644 index 0000000000000..b0db80c70264c --- /dev/null +++ b/docs/api/javascript/module_selenium-webdriver_chrome_class_Driver.html @@ -0,0 +1,5 @@ +Driver

        Class Driver

        code »
        WebDriver
        +  └ Driver

        Creates a new WebDriver client for Chrome.

        Constructor

        Driver ( opt_config, opt_service, opt_flow )
        Parameters
        opt_config: (webdriver.Capabilities|Options)=
        The configuration + options.
        opt_service: remote.DriverService=
        The session to use; will use + the default service by default.
        opt_flow: webdriver.promise.ControlFlow=
        The control flow to use, or + null to use the currently active flow.
        Show:

        Instance Properties

        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_chrome_class_Options.html b/docs/api/javascript/module_selenium-webdriver_chrome_class_Options.html index 171be4f4a7891..61a188e6f5ee8 100644 --- a/docs/api/javascript/module_selenium-webdriver_chrome_class_Options.html +++ b/docs/api/javascript/module_selenium-webdriver_chrome_class_Options.html @@ -1,4 +1,4 @@ -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 +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 @@ -14,9 +14,9 @@ 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" + directory.

        Parameters
        state: !Object
        Dictionary of local state preferences.
        Returns
        A self reference.
        code »setLoggingPrefs ( 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: webdriver.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 + object.
        Parameters
        capabilities: !webdriver.Capabilities
        The capabilities object.
        Returns
        The ChromeDriver options.
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_chrome_class_ServiceBuilder.html b/docs/api/javascript/module_selenium-webdriver_chrome_class_ServiceBuilder.html index 1b117df32a1e8..a53eee924d5f9 100644 --- a/docs/api/javascript/module_selenium-webdriver_chrome_class_ServiceBuilder.html +++ b/docs/api/javascript/module_selenium-webdriver_chrome_class_ServiceBuilder.html @@ -1,4 +1,4 @@ -ServiceBuilder

        Class ServiceBuilder

        code »

        Creates remote.DriverService instances that manage a ChromeDriver +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 @@ -10,4 +10,4 @@ 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 + 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/docs/api/javascript/module_selenium-webdriver_docs_dossier.html b/docs/api/javascript/module_selenium-webdriver_docs_dossier.html deleted file mode 100644 index 5eecf54e4ceff..0000000000000 --- a/docs/api/javascript/module_selenium-webdriver_docs_dossier.html +++ /dev/null @@ -1 +0,0 @@ -selenium-webdriver/docs/dossier

        Module selenium-webdriver/docs/dossier

        code »
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_docs_types.html b/docs/api/javascript/module_selenium-webdriver_docs_types.html deleted file mode 100644 index df07054b7698b..0000000000000 --- a/docs/api/javascript/module_selenium-webdriver_docs_types.html +++ /dev/null @@ -1 +0,0 @@ -selenium-webdriver/docs/types

        Module selenium-webdriver/docs/types

        code »
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_error.html b/docs/api/javascript/module_selenium-webdriver_error.html index dc4ba906ccac8..8e7b2026a6276 100644 --- a/docs/api/javascript/module_selenium-webdriver_error.html +++ b/docs/api/javascript/module_selenium-webdriver_error.html @@ -1,4 +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 + http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_executors.html b/docs/api/javascript/module_selenium-webdriver_executors.html index 4cd5307a8a31f..b5a7f02f58b05 100644 --- a/docs/api/javascript/module_selenium-webdriver_executors.html +++ b/docs/api/javascript/module_selenium-webdriver_executors.html @@ -1,3 +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 + or a promise that will resolve to that URL.
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_firefox.html b/docs/api/javascript/module_selenium-webdriver_firefox.html new file mode 100644 index 0000000000000..67a0749e90d84 --- /dev/null +++ b/docs/api/javascript/module_selenium-webdriver_firefox.html @@ -0,0 +1 @@ +selenium-webdriver/firefox

        Module selenium-webdriver/firefox

        code »

        Classes

        Binary
        Manages a Firefox subprocess configured for use with WebDriver.
        Driver
        A WebDriver client for Firefox.
        Options
        Configuration options for the FirefoxDriver.
        Profile
        Models a Firefox proifle directory for use with the FirefoxDriver.
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_firefox_binary.html b/docs/api/javascript/module_selenium-webdriver_firefox_binary.html new file mode 100644 index 0000000000000..8b8d0a02b6eae --- /dev/null +++ b/docs/api/javascript/module_selenium-webdriver_firefox_binary.html @@ -0,0 +1 @@ +selenium-webdriver/firefox/binary

        Module selenium-webdriver/firefox/binary

        code »

        Classes

        Binary
        Manages a Firefox subprocess configured for use with WebDriver.
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_firefox_binary_class_Binary.html b/docs/api/javascript/module_selenium-webdriver_firefox_binary_class_Binary.html new file mode 100644 index 0000000000000..207146a4895ae --- /dev/null +++ b/docs/api/javascript/module_selenium-webdriver_firefox_binary_class_Binary.html @@ -0,0 +1,4 @@ +Binary

        Class Binary

        code »

        Manages a Firefox subprocess configured for use with WebDriver.

        Constructor

        Binary ( opt_exe )
        Parameters
        opt_exe: string=
        Path to the Firefox binary to use. If not + specified, will attempt to locate Firefox on the current system.
        Show:

        Instance Methods

        code »addArguments ( var_args )

        Add arguments to the command line used to start Firefox.

        Parameters
        var_args: ...(string|!Array.<string>)
        Either the arguments to add as + varargs, or the arguments as an array.
        code »kill ( )!promise.Promise

        Kills the managed Firefox process.

        Returns
        A promise for when the process has terminated.
        code »launch ( profile )!promise.Promise

        Launches Firefox and eturns a promise that will be fulfilled when the process + terminates.

        Parameters
        profile: string
        Path to the profile directory to use.
        Returns
        A promise for the process result.
        Throws
        Error
        If this instance has already been started.

        Instance Properties

        code »command_ : promise.Promise
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_firefox_class_Driver.html b/docs/api/javascript/module_selenium-webdriver_firefox_class_Driver.html new file mode 100644 index 0000000000000..c53f20c11009c --- /dev/null +++ b/docs/api/javascript/module_selenium-webdriver_firefox_class_Driver.html @@ -0,0 +1,6 @@ +Driver

        Class Driver

        code »
        WebDriver
        +  └ Driver

        A WebDriver client for Firefox.

        Constructor

        Driver ( opt_config, opt_flow )
        Parameters
        opt_config: (Options|webdriver.Capabilities|Object)=
        The + configuration options for this driver, specified as either an + Options or webdriver.Capabilities, or as a raw hash + object.
        opt_flow: webdriver.promise.ControlFlow=
        The flow to + schedule commands through. Defaults to the active flow object.
        Show:

        Instance Properties

        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_firefox_class_Options.html b/docs/api/javascript/module_selenium-webdriver_firefox_class_Options.html new file mode 100644 index 0000000000000..6f08ef1f3ed5a --- /dev/null +++ b/docs/api/javascript/module_selenium-webdriver_firefox_class_Options.html @@ -0,0 +1,4 @@ +Options

        Class Options

        code »

        Configuration options for the FirefoxDriver.

        Constructor

        Options ( )
        Show:

        Instance Methods

        code »setBinary ( binary )!Options

        Sets the binary to use. The binary may be specified as the path to a Firefox + executable, or as a Binary object.

        Parameters
        binary: (string|!Binary)
        The binary to use.
        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 »setProfile ( profile )!Options

        Sets the profile to use. The profile may be specified as a + Profile object or as the path to an existing Firefox profile to use + as a template.

        Parameters
        profile: (string|!Profile)
        The profile to use.
        Returns
        A self reference.
        code »setProxy ( proxy )!Options

        Sets the proxy to use.

        Parameters
        proxy: webdriver.ProxyConfig
        The proxy configuration to use.
        Returns
        A self reference.

        Converts these options to a webdriver.Capabilities instance.

        Parameters
        opt_remote
        Returns
        A new capabilities object.

        Instance Properties

        code »profile_ : Profile
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_firefox_extension.html b/docs/api/javascript/module_selenium-webdriver_firefox_extension.html new file mode 100644 index 0000000000000..5e65963013af1 --- /dev/null +++ b/docs/api/javascript/module_selenium-webdriver_firefox_extension.html @@ -0,0 +1,3 @@ +selenium-webdriver/firefox/extension

        Module selenium-webdriver/firefox/extension

        code »

        Utilities for working with Firefox extensions.

        Show:

        Type Definitions

        code »AddonDetails : {id: string, name: string, version: string, unpack: boolean}
        Describes a Firefox add-on.

        Functions

        code »install ( extension, dir )!promise.Promise.<string>

        Installs an extension to the given directory.

        Parameters
        extension: string
        Path to the extension to install, as either a xpi + file or a directory.
        dir: string
        Path to the directory to install the extension in.
        Returns
        A promise for the add-on ID once + installed.
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_firefox_profile.html b/docs/api/javascript/module_selenium-webdriver_firefox_profile.html new file mode 100644 index 0000000000000..7ec6e53b70572 --- /dev/null +++ b/docs/api/javascript/module_selenium-webdriver_firefox_profile.html @@ -0,0 +1,4 @@ +selenium-webdriver/firefox/profile

        Module selenium-webdriver/firefox/profile

        code »

        Classes

        Profile
        Models a Firefox proifle directory for use with the FirefoxDriver.
        Show:

        Functions

        code »decode ( data )!promise.Promise.<string>

        Decodes a base64 encoded profile.

        Parameters
        data: string
        The base64 encoded string.
        Returns
        A promise for the path to the decoded + profile directory.
        code »loadUserPrefs ( f )!promise.Promise

        Parses a user.js file in a Firefox profile directory.

        Parameters
        f: string
        Path to the file to parse.
        Returns
        A promise for the parsed preferences as + a JSON object. If the file does not exist, an empty object will be + returned.
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_firefox_profile_class_Profile.html b/docs/api/javascript/module_selenium-webdriver_firefox_profile_class_Profile.html new file mode 100644 index 0000000000000..7083b163ec733 --- /dev/null +++ b/docs/api/javascript/module_selenium-webdriver_firefox_profile_class_Profile.html @@ -0,0 +1,18 @@ +Profile

        Class Profile

        code »

        Models a Firefox proifle directory for use with the FirefoxDriver. The + Proifle directory uses an in-memory model until #writeToDisk + is called.

        Constructor

        Profile ( opt_dir )
        Parameters
        opt_dir: string=
        Path to an existing Firefox profile directory to + use a template for this profile. If not specified, a blank profile will + be used.
        Show:

        Instance Methods

        Returns
        Whether the FirefoxDriver is configured to automatically + accept untrusted SSL certificates.
        code »addExtension ( extension )

        Registers an extension to be included with this profile.

        Parameters
        extension: string
        Path to the extension to include, as either an + unpacked extension directory or the path to a xpi file.
        Returns
        Whether to assume untrusted certs come from untrusted + issuers.
        code »encode ( )!promise.Promise.<string>

        Encodes this profile as a zipped, base64 encoded directory.

        Returns
        A promise for the encoded profile.
        Returns
        The port this profile is currently configured to use, or + 0 if the port will be selected at random when the profile is written + to disk.

        Returns the currently configured value of a profile preference. This does + not include any defaults defined in the profile's template directory user.js + file (if a template were specified on construction).

        Parameters
        key: string
        The desired preference.
        Returns
        The current value of the + requested preference.

        Returns whether native events are enabled in this profile.

        Returns
        .

        Sets whether the FirefoxDriver should automatically accept untrusted SSL + certificates.

        Parameters
        value: boolean
        .

        Sets whether to assume untrusted certificates come from untrusted issuers.

        Parameters
        value: boolean
        .

        Sets whether to use native events with this profile.

        Parameters
        enabled: boolean
        .

        Sets the port to use for the WebDriver extension loaded by this profile.

        Parameters
        port: number
        The desired port, or 0 to use any free port.
        code »setPreference ( key, value )

        Sets a desired preference for this profile.

        Parameters
        key: string
        The preference key.
        value: (string|number|boolean)
        The preference value.
        Throws
        Error
        If attempting to set a frozen preference.
        code »writeToDisk ( opt_excludeWebDriverExt )!promise.Promise.<string>

        Writes this profile to disk.

        Parameters
        opt_excludeWebDriverExt: boolean=
        Whether to exclude the WebDriver + extension from the generated profile. Used to reduce the size of an + encoded profile since the server will always install + the extension itself.
        Returns
        A promise for the path to the new + profile directory.

        Instance Properties

        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_http.html b/docs/api/javascript/module_selenium-webdriver_http.html index a5b2f988b5146..2b4316b3418f2 100644 --- a/docs/api/javascript/module_selenium-webdriver_http.html +++ b/docs/api/javascript/module_selenium-webdriver_http.html @@ -1,4 +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 + module.
        Request
        Describes a partial HTTP request.
        Response
        Represents a HTTP response.
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_http_class_HttpClient.html b/docs/api/javascript/module_selenium-webdriver_http_class_HttpClient.html index d61157e9c2b2b..e438a1f78ceea 100644 --- a/docs/api/javascript/module_selenium-webdriver_http_class_HttpClient.html +++ b/docs/api/javascript/module_selenium-webdriver_http_class_HttpClient.html @@ -1,2 +1,3 @@ -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 +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, opt_agent )
        Parameters
        serverUrl: string
        URL for the WebDriver server to send commands to.
        opt_agent: http.Agent=
        The agent to use for each request. + Defaults to http.globalAgent.
        Show:

        Instance Methods

        code »send ( httpRequest, callback )
        Parameters
        httpRequest
        callback

        Instance Properties

        code »agent_ : http.Agent

        Base options for each request.

        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_http_util.html b/docs/api/javascript/module_selenium-webdriver_http_util.html index e85d1000b81be..d1065b22492c4 100644 --- a/docs/api/javascript/module_selenium-webdriver_http_util.html +++ b/docs/api/javascript/module_selenium-webdriver_http_util.html @@ -2,4 +2,4 @@ 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 + URL responds with 2xx. \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_io.html b/docs/api/javascript/module_selenium-webdriver_io.html index aabdf7fd0e1a5..fa50d71635113 100644 --- a/docs/api/javascript/module_selenium-webdriver_io.html +++ b/docs/api/javascript/module_selenium-webdriver_io.html @@ -1,4 +1,9 @@ -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 +selenium-webdriver/io

        Module selenium-webdriver/io

        code »
        Show:

        Functions

        code »copy ( src, dst )!promise.Promise.<string>

        Copies one file to another.

        Parameters
        src: string
        The source file.
        dst: string
        The destination file.
        Returns
        A promise for the copied file's path.
        code »copyDir ( src, dst, opt_exclude )!promise.Promise.<string>

        Recursively copies the contents of one directory to another.

        Parameters
        src: string
        The source directory to copy.
        dst: string
        The directory to copy into.
        opt_exclude: (RegEx|function(string): boolean)=
        An exclusion filter + as either a regex or predicate function. All files matching this filter + will not be copied.
        Returns
        A promise for the destination + directory's path once all files have been copied.
        code »exists ( path )!promise.Promise.<boolean>

        Tests if a file path exists.

        Parameters
        path: string
        The path to test.
        Returns
        A promise for whether the file exists.
        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 + not be found.
        code »tmpDir ( )!promise.Promise.<string>
        Returns
        A promise for the path to a temporary + directory.
        code »tmpFile ( )!promise.Promise.<string>
        Returns
        A promise for the path to a temporary + file.
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_io_exec.html b/docs/api/javascript/module_selenium-webdriver_io_exec.html new file mode 100644 index 0000000000000..36bb4d59c39f2 --- /dev/null +++ b/docs/api/javascript/module_selenium-webdriver_io_exec.html @@ -0,0 +1,10 @@ +selenium-webdriver/io/exec

        Module selenium-webdriver/io/exec

        code »

        Main

        exec ( command, opt_options )!Command
        Parameters
        command: string
        The executable to spawn.
        opt_options: Options=
        The command options.
        Returns
        The launched command.
        Show:

        Type Definitions

        A hash with configuration options for an executed command. +
          +
        • +
        • args - Command line arguments. +
        • env - Command environment; will inherit from the current process + if missing. +
        • 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/docs/api/javascript/module_selenium-webdriver_net.html b/docs/api/javascript/module_selenium-webdriver_net.html index 128d586e96d4e..9e0b3df4b912d 100644 --- a/docs/api/javascript/module_selenium-webdriver_net.html +++ b/docs/api/javascript/module_selenium-webdriver_net.html @@ -1 +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 +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/docs/api/javascript/module_selenium-webdriver_net_portprober.html b/docs/api/javascript/module_selenium-webdriver_net_portprober.html index 0ae96a6780acb..9af4a4686b7ba 100644 --- a/docs/api/javascript/module_selenium-webdriver_net_portprober.html +++ b/docs/api/javascript/module_selenium-webdriver_net_portprober.html @@ -3,4 +3,4 @@ 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 + with whether the port is free. \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_phantomjs.html b/docs/api/javascript/module_selenium-webdriver_phantomjs.html index a4fd791508b45..53a46783aeb56 100644 --- a/docs/api/javascript/module_selenium-webdriver_phantomjs.html +++ b/docs/api/javascript/module_selenium-webdriver_phantomjs.html @@ -1 +1,2 @@ -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 +selenium-webdriver/phantomjs

        Module selenium-webdriver/phantomjs

        code »

        Classes

        Driver
        Creates a new WebDriver client for PhantomJS.
        Show:

        Functions

        code »createDriver ( opt_capabilities, opt_flow )!webdriver.WebDriver
        Deprecated: Use Driver.

        Creates a new PhantomJS WebDriver client.

        Parameters
        opt_capabilities: webdriver.Capabilities=
        The desired capabilities.
        opt_flow: webdriver.promise.ControlFlow=
        The control flow to use, or + null to use the currently active flow.
        Returns
        A new WebDriver instance.
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_phantomjs_class_Driver.html b/docs/api/javascript/module_selenium-webdriver_phantomjs_class_Driver.html new file mode 100644 index 0000000000000..2ad20b1ff799e --- /dev/null +++ b/docs/api/javascript/module_selenium-webdriver_phantomjs_class_Driver.html @@ -0,0 +1,3 @@ +Driver

        Class Driver

        code »
        WebDriver
        +  └ Driver

        Creates a new WebDriver client for PhantomJS.

        Constructor

        Driver ( opt_capabilities, opt_flow )
        Parameters
        opt_capabilities: webdriver.Capabilities=
        The desired capabilities.
        opt_flow: webdriver.promise.ControlFlow=
        The control flow to use, or + null to use the currently active flow.
        Show:

        Instance Properties

        Defined in Driver

        Defined in WebDriver

        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_proxy.html b/docs/api/javascript/module_selenium-webdriver_proxy.html index 67b9e60b66fa2..4a26aa1ee44fb 100644 --- a/docs/api/javascript/module_selenium-webdriver_proxy.html +++ b/docs/api/javascript/module_selenium-webdriver_proxy.html @@ -7,7 +7,7 @@ .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 +

        Show:

        Functions

        Configures WebDriver to bypass all browser proxies.

        Returns
        A new proxy configuration object.

        Manually configures the browser proxy. The following options are supported:

        • ftp: Proxy host to use for FTP requests @@ -20,5 +20,5 @@ 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 + configuration options.Returns
        A new proxy configuration object.

        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.

        Configures WebDriver to use the current system's proxy.

        Returns
        A new proxy configuration object.
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_remote.html b/docs/api/javascript/module_selenium-webdriver_remote.html index 1abf5aa3d2b7d..3078ff7f89208 100644 --- a/docs/api/javascript/module_selenium-webdriver_remote.html +++ b/docs/api/javascript/module_selenium-webdriver_remote.html @@ -1,4 +1,4 @@ -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. +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 @@ -16,4 +16,4 @@
        • 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 +
        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_remote_class_DriverService.html b/docs/api/javascript/module_selenium-webdriver_remote_class_DriverService.html index 44a90b5348a95..7656f1fb51d9b 100644 --- a/docs/api/javascript/module_selenium-webdriver_remote_class_DriverService.html +++ b/docs/api/javascript/module_selenium-webdriver_remote_class_DriverService.html @@ -1,19 +1,21 @@ -DriverService

        Class DriverService

        code »

        Manages the life and death of a native executable WebDriver server. +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 + 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 process is still running. This does not take + into account whether the process is in the process of shutting down.

        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 + the server has been stopped.
        code »start ( opt_timeoutMs )!promise.Promise.<string>

        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 + 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 + the server has been stopped.

        Instance Properties

        code »address_ : promise.Promise.<string>

        Promise that resolves to the server's address or null if the server has + not been started. This promise will be rejected if the server terminates + before it starts accepting WebDriver requests.

        code »command_ : promise.Promise

        A promise for the managed subprocess, or null if the server has not been + started yet. This promise will never be rejected.

        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/docs/api/javascript/module_selenium-webdriver_remote_class_SeleniumServer.html b/docs/api/javascript/module_selenium-webdriver_remote_class_SeleniumServer.html index 0b5bcceb20085..951e0ebdc5584 100644 --- a/docs/api/javascript/module_selenium-webdriver_remote_class_SeleniumServer.html +++ b/docs/api/javascript/module_selenium-webdriver_remote_class_SeleniumServer.html @@ -1,7 +1,7 @@ -SeleniumServer

        Class SeleniumServer

        code »
        DriverService
        +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: + 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 @@ -16,16 +16,18 @@
        • 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 +

        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 process is still running. This does not take + into account whether the process is in the process of shutting down.

        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 + the server has been stopped.
        code »start ( opt_timeoutMs )!promise.Promise.<string>

        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 + 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 + the server has been stopped.

        Instance Properties

        code »address_ : promise.Promise.<string>

        Promise that resolves to the server's address or null if the server has + not been started. This promise will be rejected if the server terminates + before it starts accepting WebDriver requests.

        code »command_ : promise.Promise

        A promise for the managed subprocess, or null if the server has not been + started yet. This promise will never be rejected.

        Static Properties

        \ No newline at end of file diff --git a/docs/api/javascript/module_selenium-webdriver_testing.html b/docs/api/javascript/module_selenium-webdriver_testing.html index ed26401633343..9b9c41efa5a44 100644 --- a/docs/api/javascript/module_selenium-webdriver_testing.html +++ b/docs/api/javascript/module_selenium-webdriver_testing.html @@ -11,8 +11,8 @@
      • xit -

        The provided wrappers leverage the webdriver.promise.ControlFlow to - simplify writing asynchronous tests: +

        The provided wrappers leverage the webdriver.promise.ControlFlow + to simplify writing asynchronous tests:

        
          var webdriver = require('selenium-webdriver'),
              portprober = require('selenium-webdriver/net/portprober'),
        @@ -61,13 +61,13 @@
            });
         
            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 +

        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 + #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 + 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/docs/api/javascript/module_selenium-webdriver_testing_assert.html b/docs/api/javascript/module_selenium-webdriver_testing_assert.html index d214b1fcb0ff6..4984939e4b877 100644 --- a/docs/api/javascript/module_selenium-webdriver_testing_assert.html +++ b/docs/api/javascript/module_selenium-webdriver_testing_assert.html @@ -16,4 +16,4 @@ 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 + matcher constructor to use, or an object literal defining a matcher. \ No newline at end of file diff --git a/docs/api/javascript/namespace_PRIMITIVE_EQUALITY_PREDICATES.html b/docs/api/javascript/namespace_PRIMITIVE_EQUALITY_PREDICATES.html new file mode 100644 index 0000000000000..55bf9cd1bfb02 --- /dev/null +++ b/docs/api/javascript/namespace_PRIMITIVE_EQUALITY_PREDICATES.html @@ -0,0 +1 @@ +PRIMITIVE_EQUALITY_PREDICATES

        Namespace PRIMITIVE_EQUALITY_PREDICATES

        code »
        Show:

        Global Functions

        Parameters
        var1
        var2
        Parameters
        date1
        date2
        Parameters
        var1
        var2
        Parameters
        var1
        var2
        Parameters
        var1
        var2
        Parameters
        var1
        var2
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_bot.html b/docs/api/javascript/namespace_bot.html index b3d27b10a6d17..b31a7eb479a4b 100644 --- a/docs/api/javascript/namespace_bot.html +++ b/docs/api/javascript/namespace_bot.html @@ -1,4 +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 + http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_bot_json.html b/docs/api/javascript/namespace_bot_json.html index fa0a57e3d0bc0..589e154ff9747 100644 --- a/docs/api/javascript/namespace_bot_json.html +++ b/docs/api/javascript/namespace_bot_json.html @@ -1,4 +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 + 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/docs/api/javascript/namespace_bot_response.html b/docs/api/javascript/namespace_bot_response.html index 3525f53aa468c..e41e0310b7f64 100644 --- a/docs/api/javascript/namespace_bot_response.html +++ b/docs/api/javascript/namespace_bot_response.html @@ -2,4 +2,4 @@ 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 + 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/docs/api/javascript/namespace_bot_userAgent.html b/docs/api/javascript/namespace_bot_userAgent.html index cde2533289267..817bcc26b28e5 100644 --- a/docs/api/javascript/namespace_bot_userAgent.html +++ b/docs/api/javascript/namespace_bot_userAgent.html @@ -18,4 +18,4 @@ 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 + 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/docs/api/javascript/namespace_goog.html b/docs/api/javascript/namespace_goog.html index 10818ad5384ba..4d1beec1fbe23 100644 --- a/docs/api/javascript/namespace_goog.html +++ b/docs/api/javascript/namespace_goog.html @@ -1,17 +1,18 @@ 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: + base.js is loaded more than once.

        Classes

        goog.Disposable
        Class that provides the basic implementation for disposable objects.
        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 + 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, opt_isModule )

        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 + this file requires.

        opt_isModule: boolean=
        Whether this dependency must be loaded as + a module as declared by goog.module.

        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. + 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. @@ -26,7 +27,7 @@ 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 + 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'. @@ -40,13 +41,13 @@ 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 + 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 + 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 + 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: @@ -58,13 +59,30 @@ 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 + options.

        Parameters
        name: string
        The distinguished name to provide.
        defaultValue
        code »goog.defineClass ( superClass, def )!Function

        Creates a restricted form of a Closure "class": + - from the compiler's perspective, the instance returned from the + constructor is sealed (no new properties may be added). This enables + better checks. + - the compiler will rewrite this definition to a form that is optimal + for type checking and optimization (initially this will be a more + traditional form).

        Parameters
        superClass: Function
        The superclass, Object or null.
        def: goog.defineClass.ClassDescriptor
        An object literal describing the + the class. It may have the following properties: + "constructor": the constructor function + "statics": an object literal containing methods to add to the constructor + as "static" methods or a function that will receive the constructor + function as its only parameter to which static properties can + be added. + all other properties are added to the prototype.
        Returns
        The class constructor.

        Calls dispose on the argument if it supports it. If obj is not an + object with a dispose() method, this is a no-op.

        Parameters
        obj: *
        The object to dispose of.

        Calls dispose on each member of the list that supports it. (If the + member is an ArrayLike, then goog.disposeAll() will be called + recursively on each of its members.) If the member is not an object with a + dispose() method, then it is ignored.

        Parameters
        var_args: ...*
        The list.
        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. + 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. + 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. @@ -78,7 +96,7 @@ 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 + 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. @@ -88,7 +106,7 @@ 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. + "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. @@ -112,8 +130,8 @@ 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. + 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 @@ -122,7 +140,7 @@ 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 +

        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 @@ -130,59 +148,65 @@ 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 + 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 + |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 + 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. + 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. + 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.

        Given a URL initiate retrieval and execution of the module.

        Parameters
        src: string
        Script source URL.
        code »goog.importScript_ ( src, opt_sourceText )

        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.
        opt_sourceText: string=
        The optionally source text to evaluate

        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) { }
        + ParentClass.prototype.foo = function(a) { };
         
          function ChildClass(a, b, c) {
        -   goog.base(this, a, b);
        +   ChildClass.base(this, 'constructor', 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 +

        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 + 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 + 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
        Whether a goog.module is currently being initialized.

        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.
        Parameters
        moduleDef: (function(?): ?|string)
        The module definition.

        Load any deferred goog.module loads.

        Parameters
        msg
        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 + toString or hasOwnProperty. Use goog.object.extend for this purpose.

        Parameters
        target: Object
        Target.
        source: Object
        Source.

        goog.module serves two purposes: + - marks a file that must be loaded as a module + - reserves a namespace (it can not also be goog.provided) + and has three requirements: + - goog.module may not be used in the same file as goog.provide. + - goog.module must be the first statement in the file. + - only one goog.module is allowed per file. + When a goog.module annotated file is loaded, it is loaded enclosed in + a strict function closure. This means that: + - any variable declared in a goog.module file are private to the file, + not global. Although the compiler is expected to inline the module. + - The code must obey all the rules of "strict" JavaScript. + - the file will be marked as "use strict" + + NOTE: unlike goog.provide, goog.module does not declare any symbols by + itself.

        Parameters
        name: string
        Namespace provided by this file in the form + "goog.package.part", is expected but not required.
        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.onScriptLoad_ ( script, scriptIndex )boolean

        A readystatechange handler for legacy IE

        Parameters
        script
        scriptIndex
        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: @@ -193,17 +217,18 @@ 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 + "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 + 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 + the form "goog.package.part".Returns

        If called within a goog.module file, the associated namespace or + module otherwise null.

        Retrieve and execute a module.

        Parameters
        src: string
        Script source URL.

        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: + (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",
        @@ -219,24 +244,30 @@
          --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 + 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 + raised when used in production code.

        Sealing classes breaks the older idiom of assigning properties on the + prototype rather than in the constructor. As such, goog.defineClass + must not seal subclasses of these old-style classes until they are fixed. + Until then, this marks a class as "broken", instructing defineClass + not to seal subclasses.

        Parameters
        ctr: !Function
        The legacy constructor to tag as unsealable.

        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.
        code »goog.wrapModule_ ( srcUrl, scriptText )string

        Return an appropriate module text. Suitable to insert into + a script tag (that is unescaped).

        Parameters
        srcUrl
        scriptText
        code »goog.writeScriptTag_ ( src, opt_sourceText )boolean

        The default implementation of the import function. Writes a script tag to + import the script.

        Parameters
        src: string
        The script url.
        opt_sourceText: string=
        The optionally source text to evaluate
        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.

        Name for unsealable tag property.

        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, + 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 + '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 + removes this variable if unused.

        The registry of initialized modules: + the module identifier to module exports map.

        code »goog.moduleLoaderState_ : ({moduleName: (string|undefined), exportTestMethods: boolean}|null)

        Compiler Constants

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_array.html b/docs/api/javascript/namespace_goog_array.html index 1eb2185db0c0d..ae5a09b487a50 100644 --- a/docs/api/javascript/namespace_goog_array.html +++ b/docs/api/javascript/namespace_goog_array.html @@ -1,13 +1,13 @@ -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 +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 + 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 + 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 @@ -24,7 +24,7 @@ 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 + 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 @@ -41,7 +41,7 @@ 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. + 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) @@ -55,14 +55,14 @@ 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 + 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 + 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 @@ -70,7 +70,7 @@ 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 + 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. @@ -95,9 +95,9 @@ 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 > + 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 + 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 @@ -110,7 +110,7 @@ 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. + 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: @@ -152,7 +152,7 @@ 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 + 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 @@ -170,11 +170,11 @@ 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 + 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. + 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. @@ -186,12 +186,12 @@ 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 + 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. + 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:

        @@ -234,8 +234,12 @@
              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 + value.

        obj: T
        Object to remove.Returns
        True if an element was removed.
        code »<T, S> goog.array.removeAllIf ( arr, f, opt_obj )number

        Removes all values that satisfy 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
        The number of items 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. @@ -255,13 +259,13 @@ 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 + 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 + 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. @@ -269,7 +273,7 @@ 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 + 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 @@ -281,7 +285,7 @@ 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 + 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 @@ -295,18 +299,18 @@ 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 + 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 + 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 + 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 @@ -317,11 +321,11 @@ 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 + 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 + 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 @@ -329,9 +333,9 @@ 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 + 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 + 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/docs/api/javascript/namespace_goog_asserts.html b/docs/api/javascript/namespace_goog_asserts.html index bdb36c70d89c7..2c97fd2180eed 100644 --- a/docs/api/javascript/namespace_goog_asserts.html +++ b/docs/api/javascript/namespace_goog_asserts.html @@ -1,14 +1,14 @@ -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

        Namespace goog.asserts

        code »

        Classes

        goog.asserts.AssertionError
        Error object for failed assertions.
        Show:

        Global Functions

        The default error handler.

        Parameters
        e: !goog.asserts.AssertionError
        The exception to be handled.
        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 + 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.

        The handler responsible for throwing or logging assertion errors.

        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: @@ -19,4 +19,6 @@ 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 +
        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.

        Sets a custom error handler that can be used to customize the behavior of + assertion failures, for example by turning all assertion failures into log + messages.

        Parameters
        errorHandler

        Compiler Constants

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_async.html b/docs/api/javascript/namespace_goog_async.html new file mode 100644 index 0000000000000..75fad2ac26fae --- /dev/null +++ b/docs/api/javascript/namespace_goog_async.html @@ -0,0 +1,14 @@ +goog.async

        Namespace goog.async

        code »
        Show:

        Global Functions

        code »<SCOPE> goog.async.nextTick ( callback, opt_context )

        Fires the provided callbacks as soon as possible after the current JS + execution context. setTimeout(…, 0) takes at least 4ms when called from + within another setTimeout(…, 0) for legacy reasons. + + This will not schedule the callback as a microtask (i.e. a task that can + preempt user input or networking callbacks). It is meant to emulate what + setTimeout(_, 0) would do if it were not throttled. If you desire microtask + behavior, use goog.Promise instead.

        Parameters
        callback: function(this: SCOPE)
        Callback function to fire as soon as + possible.
        opt_context: SCOPE=
        Object in whose scope to call the listener.
        code »<THIS> goog.async.run ( callback, opt_context )

        Fires the provided callback just before the current callstack unwinds, or as + soon as possible after the current JS execution context.

        Parameters
        callback
        opt_context: THIS=
        Object to use as the "this value" when calling + the provided function.

        Throw an item without interrupting the current execution context. For + example, if processing a group of items in a loop, sometimes it is useful + to report an error while still allowing the rest of the batch to be + processed.

        Parameters
        exception
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_async_nextTick.html b/docs/api/javascript/namespace_goog_async_nextTick.html new file mode 100644 index 0000000000000..26a5026c924f5 --- /dev/null +++ b/docs/api/javascript/namespace_goog_async_nextTick.html @@ -0,0 +1,11 @@ +goog.async.nextTick

        Namespace goog.async.nextTick.<SCOPE>

        code »

        Fires the provided callbacks as soon as possible after the current JS + execution context. setTimeout(…, 0) takes at least 4ms when called from + within another setTimeout(…, 0) for legacy reasons. + + This will not schedule the callback as a microtask (i.e. a task that can + preempt user input or networking callbacks). It is meant to emulate what + setTimeout(_, 0) would do if it were not throttled. If you desire microtask + behavior, use goog.Promise instead.

        Main

        <SCOPE> nextTick ( callback, opt_context )
        Parameters
        callback: function(this: SCOPE)
        Callback function to fire as soon as + possible.
        opt_context: SCOPE=
        Object in whose scope to call the listener.
        Show:

        Global Functions

        Determines the best possible implementation to run a function as soon as + the JS event loop is idle.

        Returns
        The "setImmediate" implementation.

        Cache for the setImmediate implementation.

        code »goog.async.nextTick.wrapCallback_ ( callback )function()

        Helper function that is overrided to protect callbacks with entry point + monitor if the application monitors entry points.

        Parameters
        callback: function()
        Callback function to fire as soon as possible.
        Returns
        The wrapped callback.
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_async_run.html b/docs/api/javascript/namespace_goog_async_run.html new file mode 100644 index 0000000000000..80a1ddca71526 --- /dev/null +++ b/docs/api/javascript/namespace_goog_async_run.html @@ -0,0 +1,9 @@ +goog.async.run

        Namespace goog.async.run.<THIS>

        code »

        Fires the provided callback just before the current callstack unwinds, or as + soon as possible after the current JS execution context.

        Main

        <THIS> run ( callback, opt_context )
        Parameters
        callback
        opt_context: THIS=
        Object to use as the "this value" when calling + the provided function.

        Classes

        Show:

        Global Functions

        Forces goog.async.run to use nextTick instead of Promise. + + This should only be done in unit tests. It's useful because MockClock + replaces nextTick, but not the browser Promise implementation, so it allows + Promise-based code to be tested with MockClock.

        Initializes the function to use to process the work queue.

        Run any pending goog.async.run work items. This function is not intended + for general use, but for use by entry point handlers to run items ahead of + goog.async.nextTick.

        Reset the event queue.

        The function used to schedule work asynchronousely.

        Global Properties

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_debug.html b/docs/api/javascript/namespace_goog_debug.html index 351be286309b4..45efc3db4d239 100644 --- a/docs/api/javascript/namespace_goog_debug.html +++ b/docs/api/javascript/namespace_goog_debug.html @@ -1 +1,27 @@ -goog.debug

        Namespace goog.debug

        code »

        Classes

        goog.debug.Error
        Base class for custom error objects.
        Show:
        \ No newline at end of file +goog.debug

        Namespace goog.debug

        code »

        Interfaces

        Classes

        goog.debug.Error
        Base class for custom error objects.
        goog.debug.LogBuffer
        Creates the log buffer.
        goog.debug.LogRecord
        LogRecord objects are used to pass logging requests between + the logging framework and individual log Handlers.
        goog.debug.Logger
        The Logger is an object used for logging debug messages.
        Show:

        Type Definitions

        A message value that can be handled by a Logger. + + Functions are treated like callbacks, but are only called when the event's + log level is enabled. This is useful for logging messages that are expensive + to construct.

        Global Functions

        code »goog.debug.catchErrors ( logFunc, opt_cancel, opt_target )

        Catches onerror events fired by windows and similar objects.

        Parameters
        logFunc: function(Object)
        The function to call with the error + information.
        opt_cancel: boolean=
        Whether to stop the error from reaching the + browser.
        opt_target: Object=
        Object that fires onerror events.
        code »goog.debug.deepExpose ( obj, opt_showFn )string

        Creates a string representing a given primitive or object, and for an + object, all its properties and nested objects. WARNING: If an object is + given, it and all its nested objects will be modified. To detect reference + cycles, this method identifies objects using goog.getUid() which mutates the + object.

        Parameters
        obj: *
        Object to expose.
        opt_showFn: boolean=
        Also show properties that are functions (by + default, functions are omitted).
        Returns
        A string representation of obj.
        code »goog.debug.enhanceError ( err, opt_message )!Error

        Converts an object to an Error if it's a String, + adds a stacktrace if there isn't one, + and optionally adds an extra message.

        Parameters
        err: (Error|string)
        the original thrown object or string.
        opt_message: string=
        optional additional message to add to the + error.
        Returns
        If err is a string, it is used to create a new Error, + which is enhanced and returned. Otherwise err itself is enhanced + and returned.
        code »goog.debug.expose ( obj, opt_showFn )string

        Creates a string representing an object and all its properties.

        Parameters
        obj: (Object|null|undefined)
        Object to expose.
        opt_showFn: boolean=
        Show the functions as well as the properties, + default is false.
        Returns
        The string representation of obj.

        Recursively outputs a nested array as a string.

        Parameters
        arr: Array
        The array.
        Returns
        String representing nested array.

        Exposes an exception that has been caught by a try...catch and outputs the + error with a stack trace.

        Parameters
        err: Object
        Error object or string.
        opt_fn: Function=
        Optional function to start stack trace from.
        Returns
        Details of exception.

        Resolves functions to their names. Resolved function names will be cached.

        Gets a function name

        Parameters
        fn: Function
        Function to get name of.
        Returns
        Function's name.
        Parameters
        fn: Function
        The function to start getting the trace from.

        Gets the current stack trace, either starting from the caller or starting + from a specified function that's currently on the call stack.

        Parameters
        opt_fn: Function=
        Optional function to start getting the trace from. + If not provided, defaults to the function that called this.
        Returns
        Stack trace.

        Private helper for getStacktrace().

        Parameters
        fn: Function
        Function to start getting the trace from.
        visited: Array
        List of functions visited so far.
        Returns
        Stack trace starting from function fn.

        Gets the current stack trace. Simple and iterative - doesn't worry about + catching circular references or getting the args.

        Parameters
        opt_depth: number=
        Optional maximum depth to trace back to.
        Returns
        A string with the function names of all functions in the + stack, separated by \n.

        Makes whitespace visible by replacing it with printable characters. + This is useful in finding diffrences between the expected and the actual + output strings of a testcase.

        Parameters
        string: string
        whose whitespace needs to be made visible.
        Returns
        string whose whitespace is made visible.

        Normalizes the error/exception object between browsers.

        Parameters
        err: Object
        Raw error object.
        Returns
        Normalized error object.

        Set a custom function name resolver.

        Parameters
        resolver: function(Function): string
        Resolves functions to their + names.

        Global Properties

        Max length of stack to try and output

        Hash map for storing function names that have already been looked up.

        Compiler Constants

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_debug_LogManager.html b/docs/api/javascript/namespace_goog_debug_LogManager.html new file mode 100644 index 0000000000000..4d2a93365863b --- /dev/null +++ b/docs/api/javascript/namespace_goog_debug_LogManager.html @@ -0,0 +1,10 @@ +goog.debug.LogManager

        Namespace goog.debug.LogManager

        code »

        There is a single global LogManager object that is used to maintain a set of + shared state about Loggers and log services. This is loosely based on the + java class java.util.logging.LogManager.

        Show:

        Global Functions

        Creates a function that can be passed to goog.debug.catchErrors. The function + will log all reported errors using the given logger.

        Parameters
        opt_logger: goog.debug.Logger=
        The logger to log the errors to. + Defaults to the root logger.
        Returns
        The created function.

        Creates the named logger. Will also create the parents of the named logger + if they don't yet exist.

        Parameters
        name: string
        The name of the logger.
        Returns
        The named logger.

        Finds a named logger.

        Parameters
        name: string
        A name for the logger. This should be a dot-separated + name and should normally be based on the package name or class name of the + subsystem, such as goog.net.BrowserChannel.
        Returns
        The named logger.

        Returns all the loggers.

        Returns
        Map of logger names to logger + objects.

        Returns the root of the logger tree namespace, the logger with the empty + string as its name.

        Returns
        The root logger.

        Initializes the LogManager if not already initialized.

        Global Properties

        Map of logger names to logger objects.

        The root logger which is the root of the logger tree.

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_debug_entryPointRegistry.html b/docs/api/javascript/namespace_goog_debug_entryPointRegistry.html new file mode 100644 index 0000000000000..c76becc70d4b3 --- /dev/null +++ b/docs/api/javascript/namespace_goog_debug_entryPointRegistry.html @@ -0,0 +1,17 @@ +goog.debug.entryPointRegistry

        Namespace goog.debug.entryPointRegistry

        code »
        Show:

        Global Functions

        Configures a monitor to wrap all entry points. + + Entry points that have already been registered are immediately wrapped by + the monitor. When an entry point is registered in the future, it will also + be wrapped by the monitor when it is registered.

        Parameters
        monitor: !goog.debug.EntryPointMonitor
        An entry point monitor.

        Register an entry point with this module. + + The entry point will be instrumented when a monitor is passed to + goog.debug.entryPointRegistry.monitorAll. If this has already occurred, the + entry point is instrumented immediately.

        Parameters
        callback: function(!Function)
        A callback function which is called + with a transforming function to instrument the entry point. The callback + is responsible for wrapping the relevant entry point with the + transforming function.

        Try to unmonitor all the entry points that have already been registered. If + an entry point is registered in the future, it will not be wrapped by the + monitor when it is registered. Note that this may fail if the entry points + have additional wrapping.

        Parameters
        monitor: !goog.debug.EntryPointMonitor
        The last monitor to wrap + the entry points.
        Throws
        Error
        If the monitor is not the most recently configured monitor.

        Global Properties

        Whether goog.debug.entryPointRegistry.monitorAll has ever been called. + Checking this allows the compiler to optimize out the registrations.

        Monitors that should wrap all the entry points.

        An array of entry point callbacks.

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_defineClass.html b/docs/api/javascript/namespace_goog_defineClass.html new file mode 100644 index 0000000000000..e0d1d139c7da0 --- /dev/null +++ b/docs/api/javascript/namespace_goog_defineClass.html @@ -0,0 +1,16 @@ +goog.defineClass

        Namespace goog.defineClass

        code »

        Creates a restricted form of a Closure "class": + - from the compiler's perspective, the instance returned from the + constructor is sealed (no new properties may be added). This enables + better checks. + - the compiler will rewrite this definition to a form that is optimal + for type checking and optimization (initially this will be a more + traditional form).

        Main

        defineClass ( superClass, def )!Function
        Parameters
        superClass: Function
        The superclass, Object or null.
        def: goog.defineClass.ClassDescriptor
        An object literal describing the + the class. It may have the following properties: + "constructor": the constructor function + "statics": an object literal containing methods to add to the constructor + as "static" methods or a function that will receive the constructor + function as its only parameter to which static properties can + be added. + all other properties are added to the prototype.
        Returns
        The class constructor.
        Show:

        Type Definitions

        code »goog.defineClass.ClassDescriptor : (!Object|{constructor: !Function}|{constructor: !Function, statics: (Object|function(Function): void)})
        No description.

        Global Functions

        Parameters
        target: !Object
        The object to add properties to.
        source: !Object
        The object to copy properites from.

        If goog.defineClass.SEAL_CLASS_INSTANCES is enabled and Object.seal is + defined, this function will wrap the constructor in a function that seals the + results of the provided constructor function.

        Parameters
        ctr: !Function
        The constructor whose results maybe be sealed.
        superClass: Function
        The superclass constructor.
        Returns
        The replacement constructor.

        Global Properties

        The names of the fields that are defined on Object.prototype.

        Compiler Constants

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_disposable.html b/docs/api/javascript/namespace_goog_disposable.html new file mode 100644 index 0000000000000..bedb3135fd513 --- /dev/null +++ b/docs/api/javascript/namespace_goog_disposable.html @@ -0,0 +1 @@ +goog.disposable

        Namespace goog.disposable

        code »

        Interfaces

        goog.disposable.IDisposable
        Interface for a disposable object.
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_dom.html b/docs/api/javascript/namespace_goog_dom.html index 3331708ceb832..8a76354dbdcf0 100644 --- a/docs/api/javascript/namespace_goog_dom.html +++ b/docs/api/javascript/namespace_goog_dom.html @@ -1 +1,232 @@ -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 +goog.dom

        Namespace goog.dom

        code »

        Classes

        goog.dom.DomHelper
        Create an instance of a DOM helper with a new document object.

        Enumerations

        goog.dom.BrowserFeature
        Enum of browser capabilities.
        goog.dom.NodeType
        Constants for the nodeType attribute in the Node interface.
        goog.dom.TagName
        Enum of all html tag names specified by the W3C HTML4.01 and HTML5 + specifications.
        Show:

        Type Definitions

        Typedef for use with goog.dom.createDom and goog.dom.append.

        Global Functions

        code »goog.dom.$ ( element )Element
        Deprecated: Use goog.dom.getElement instead.

        Alias for getElement.

        Parameters
        element: (string|Element)
        Element ID or a DOM node.
        Returns
        The element with the given ID, or the node passed in.
        code »goog.dom.$$ ( opt_tag, opt_class, opt_el ){length: number}
        Deprecated: Use goog.dom.getElementsByTagNameAndClass instead.

        Alias for getElementsByTagNameAndClass.

        Parameters
        opt_tag: ?string=
        Element tag name.
        opt_class: ?string=
        Optional class name.
        opt_el: Element=
        Optional element to look in.
        Returns
        Array-like list of elements (only a length + property and numerical indices are guaranteed to exist).
        code »goog.dom.$dom ( tagName, opt_attributes, var_args )!Element
        Deprecated: Use goog.dom.createDom instead.

        Alias for createDom.

        Parameters
        tagName: string
        Tag to create.
        opt_attributes: (string|Object)=
        If object, then a map of name-value + pairs for attributes. If a string, then this is the className of the new + element.
        var_args: ...(Object|string|Array|NodeList)
        Further DOM nodes or + strings for text nodes. If one of the var_args is an array, its + children will be added as childNodes instead.
        Returns
        Reference to a DOM node.
        code »goog.dom.append ( parent, var_args )

        Appends a node with text or other nodes.

        Parameters
        parent: !Node
        The node to append nodes to.
        var_args: ...goog.dom.Appendable
        The things to append to the node. + If this is a Node it is appended as is. + If this is a string then a text node is appended. + If this is an array like object then fields 0 to length - 1 are appended.
        code »goog.dom.appendChild ( parent, child )

        Appends a child to a node.

        Parameters
        parent: Node
        Parent.
        child: Node
        Child.
        code »goog.dom.append_ ( doc, parent, args, startIndex )

        Appends a node with text or other nodes.

        Parameters
        doc: !Document
        The document to create new nodes in.
        parent: !Node
        The node to append nodes to.
        args: !Arguments
        The values to add. See goog.dom.append.
        startIndex: number
        The index of the array to start from.

        Determines if the given node can contain children, intended to be used for + HTML generation. + + IE natively supports node.canHaveChildren but has inconsistent behavior. + Prior to IE8 the base tag allows children and in IE9 all nodes return true + for canHaveChildren. + + In practice all non-IE browsers allow you to add children to any node, but + the behavior is inconsistent: + +

        +   var a = document.createElement('br');
        +   a.appendChild(document.createTextNode('foo'));
        +   a.appendChild(document.createTextNode('bar'));
        +   console.log(a.childNodes.length);  // 2
        +   console.log(a.innerHTML);  // Chrome: "", IE9: "foobar", FF3.5: "foobar"
        + 
        + + For more information, see: + http://dev.w3.org/html5/markup/syntax.html#syntax-elements + + TODO(user): Rename shouldAllowChildren() ?
        Parameters
        node: Node
        The node to check.
        Returns
        Whether the node can contain children.

        Prefer the standardized (http://www.w3.org/TR/selectors-api/), native and + fast W3C Selectors API.

        Parameters
        parent: !(Element|Document)
        The parent document object.
        Returns
        whether or not we can use parent.querySelector* APIs.

        Compares the document order of two nodes, returning 0 if they are the same + node, a negative number if node1 is before node2, and a positive number if + node2 is before node1. Note that we compare the order the tags appear in the + document so in the tree text the B node is considered to be + before the I node.

        Parameters
        node1: Node
        The first node to compare.
        node2: Node
        The second node to compare.
        Returns
        0 if the nodes are the same node, a negative number if node1 + is before node2, and a positive number if node2 is before node1.

        Utility function to compare the position of two nodes, when + textNode's parent is an ancestor of node. If this entry + condition is not met, this function will attempt to reference a null object.

        Parameters
        textNode: Node
        The textNode to compare.
        node: Node
        The node to compare.
        Returns
        -1 if node is before textNode, +1 otherwise.

        Utility function to compare the position of two nodes known to be non-equal + siblings.

        Parameters
        node1: Node
        The first node to compare.
        node2: Node
        The second node to compare.
        Returns
        -1 if node1 is before node2, +1 otherwise.
        code »goog.dom.contains ( parent, descendant )boolean

        Whether a node contains another node.

        Parameters
        parent: Node
        The node that should contain the other node.
        descendant: Node
        The node to test presence of.
        Returns
        Whether the parent node contains the descendent node.
        code »goog.dom.createDom ( tagName, opt_attributes, var_args )!Element

        Returns a dom node with a set of attributes. This function accepts varargs + for subsequent nodes to be added. Subsequent nodes will be added to the + first node as childNodes. + + So: + createDom('div', null, createDom('p'), createDom('p')); + would return a div with two child paragraphs

        Parameters
        tagName: string
        Tag to create.
        opt_attributes: (Object|Array.<string>|string)=
        If object, then a map + of name-value pairs for attributes. If a string, then this is the + className of the new element. If an array, the elements will be joined + together as the className of the new element.
        var_args: ...(Object|string|Array|NodeList)
        Further DOM nodes or + strings for text nodes. If one of the var_args is an array or NodeList,i + its elements will be added as childNodes instead.
        Returns
        Reference to a DOM node.

        Helper for createDom.

        Parameters
        doc: !Document
        The document to create the DOM in.
        args: !Arguments
        Argument object passed from the callers. See + goog.dom.createDom for details.
        Returns
        Reference to a DOM node.

        Creates a new element.

        Parameters
        name: string
        Tag name.
        Returns
        The new element.
        code »goog.dom.createTable ( rows, columns, opt_fillWithNbsp )!Element

        Create a table.

        Parameters
        rows: number
        The number of rows in the table. Must be >= 1.
        columns: number
        The number of columns in the table. Must be >= 1.
        opt_fillWithNbsp: boolean=
        If true, fills table entries with nsbps.
        Returns
        The created table.
        code »goog.dom.createTable_ ( doc, rows, columns, fillWithNbsp )!Element

        Create a table.

        Parameters
        doc: !Document
        Document object to use to create the table.
        rows: number
        The number of rows in the table. Must be >= 1.
        columns: number
        The number of columns in the table. Must be >= 1.
        fillWithNbsp: boolean
        If true, fills table entries with nsbps.
        Returns
        The created table.

        Creates a new text node.

        Parameters
        content: (number|string)
        Content.
        Returns
        The new text node.

        Find the deepest common ancestor of the given nodes.

        Parameters
        var_args: ...Node
        The nodes to find a common ancestor of.
        Returns
        The common ancestor of the nodes, or null if there is none. + null will only be returned if two or more of the nodes are from different + documents.

        Finds the first descendant node that matches the filter function, using + a depth first search. This function offers the most general purpose way + of finding a matching element. You may also wish to consider + goog.dom.query which can express many matching criteria using + CSS selector expressions. These expressions often result in a more + compact representation of the desired result.

        Parameters
        root: Node
        The root of the tree to search.
        p: function(Node): boolean
        The filter function.
        Returns
        The found node or undefined if none is found.

        Finds all the descendant nodes that match the filter function, using a + a depth first search. This function offers the most general-purpose way + of finding a set of matching elements. You may also wish to consider + goog.dom.query which can express many matching criteria using + CSS selector expressions. These expressions often result in a more + compact representation of the desired result.

        Parameters
        root: Node
        The root of the tree to search.
        p: function(Node): boolean
        The filter function.
        Returns
        The found nodes or an empty array if none are found.
        code »goog.dom.findNodes_ ( root, p, rv, findOne )boolean

        Finds the first or all the descendant nodes that match the filter function, + using a depth first search.

        Parameters
        root: Node
        The root of the tree to search.
        p: function(Node): boolean
        The filter function.
        rv: !Array
        The found nodes are added to this array.
        findOne: boolean
        If true we exit after the first found node.
        Returns
        Whether the search is complete or not. True in case findOne + is true and the node is found. False otherwise.

        Flattens an element. That is, removes it and replace it with its children. + Does nothing if the element is not in the document.

        Parameters
        element: Element
        The element to flatten.
        Returns
        The original element, detached from the document + tree, sans children; or undefined, if the element was not in the document + to begin with.

        Determines the active element in the given document.

        Parameters
        doc: Document
        The document to look in.
        Returns
        The active element.
        code »goog.dom.getAncestor ( element, matcher, opt_includeNode, opt_maxSearchSteps )Node

        Walks up the DOM hierarchy returning the first ancestor that passes the + matcher function.

        Parameters
        element: Node
        The DOM node to start with.
        matcher: function(Node): boolean
        A function that returns true if the + passed node matches the desired criteria.
        opt_includeNode: boolean=
        If true, the node itself is included in + the search (the first call to the matcher will pass startElement as + the node to test).
        opt_maxSearchSteps: number=
        Maximum number of levels to search up the + dom.
        Returns
        DOM node that matched the matcher, or null if there was + no match.
        code »goog.dom.getAncestorByClass ( element, className )Element

        Walks up the DOM hierarchy returning the first ancestor that has the passed + class name. If the passed element matches the specified criteria, the + element itself is returned.

        Parameters
        element: Node
        The DOM node to start with.
        className: string
        The class name to match.
        Returns
        The first ancestor that matches the passed criteria, or + null if none match.
        code »goog.dom.getAncestorByTagNameAndClass ( element, opt_tag, opt_class )Element

        Walks up the DOM hierarchy returning the first ancestor that has the passed + tag name and/or class name. If the passed element matches the specified + criteria, the element itself is returned.

        Parameters
        element: Node
        The DOM node to start with.
        opt_tag: ?(goog.dom.TagName|string)=
        The tag name to match (or + null/undefined to match only based on class name).
        opt_class: ?string=
        The class name to match (or null/undefined to + match only based on tag name).
        Returns
        The first ancestor that matches the passed criteria, or + null if no match is found.

        Returns an array containing just the element children of the given element.

        Parameters
        element: Element
        The element whose element children we want.
        Returns
        An array or array-like list of just the element + children of the given element.

        Gets the document object being used by the dom library.

        Returns
        Document object.

        Calculates the height of the document.

        Returns
        The height of the current document.

        Calculates the height of the document of the given window. + + Function code copied from the opensocial gadget api: + gadgets.window.adjustHeight(opt_height)

        Parameters
        win: Window
        The window whose document height to retrieve.
        Returns
        The height of the document of the given window.

        Gets the document scroll distance as a coordinate object.

        Returns
        Object with values 'x' and 'y'.

        Gets the document scroll element.

        Returns
        Scrolling element.

        Helper for getDocumentScrollElement.

        Parameters
        doc: !Document
        The document to get the scroll element for.
        Returns
        Scrolling element.

        Helper for getDocumentScroll.

        Parameters
        doc: !Document
        The document to get the scroll for.
        Returns
        Object with values 'x' and 'y'.

        Gets the DomHelper object for the document where the element resides.

        Parameters
        opt_element: (Node|Window)=
        If present, gets the DomHelper for this + element.
        Returns
        The DomHelper.

        Gets an element from the current document by element id. + + If an Element is passed in, it is returned.

        Parameters
        element: (string|Element)
        Element ID or a DOM node.
        Returns
        The element with the given ID, or the node passed in.
        code »goog.dom.getElementByClass ( className, opt_el )Element

        Returns the first element with the provided className.

        Parameters
        className: string
        the name of the class to look for.
        opt_el: (Element|Document)=
        Optional element to look in.
        Returns
        The first item with the class name provided.

        Gets an element by id from the given document (if present). + If an element is given, it is returned.

        Parameters
        doc
        element: (string|Element)
        Element ID or a DOM node.
        Returns
        The resulting element.
        code »goog.dom.getElementsByClass ( className, opt_el ){length: number}

        Returns a static, array-like list of the elements with the provided + className.

        Parameters
        className: string
        the name of the class to look for.
        opt_el: (Document|Element)=
        Optional element to look in.
        Returns
        The items found with the class name provided.
        code »goog.dom.getElementsByTagNameAndClass ( opt_tag, opt_class, opt_el ){length: number}

        Looks up elements by both tag and class name, using browser native functions + (querySelectorAll, getElementsByTagName or + getElementsByClassName) where possible. This function + is a useful, if limited, way of collecting a list of DOM elements + with certain characteristics. goog.dom.query offers a + more powerful and general solution which allows matching on CSS3 + selector expressions, but at increased cost in code size. If all you + need is particular tags belonging to a single class, this function + is fast and sleek. + + Note that tag names are case sensitive in the SVG namespace, and this + function converts opt_tag to uppercase for comparisons. For queries in the + SVG namespace you should use querySelector or querySelectorAll instead. + https://bugzilla.mozilla.org/show_bug.cgi?id=963870 + https://bugs.webkit.org/show_bug.cgi?id=83438

        Parameters
        opt_tag: ?string=
        Element tag name.
        opt_class: ?string=
        Optional class name.
        opt_el: (Document|Element)=
        Optional element to look in.
        Returns
        Array-like list of elements (only a length + property and numerical indices are guaranteed to exist).
        code »goog.dom.getElementsByTagNameAndClass_ ( doc, opt_tag, opt_class, opt_el ){length: number}

        Helper for getElementsByTagNameAndClass.

        Parameters
        doc: !Document
        The document to get the elements in.
        opt_tag: ?string=
        Element tag name.
        opt_class: ?string=
        Optional class name.
        opt_el: (Document|Element)=
        Optional element to look in.
        Returns
        Array-like list of elements (only a length + property and numerical indices are guaranteed to exist).

        Returns the first child node that is an element.

        Parameters
        node: Node
        The node to get the first child element of.
        Returns
        The first child node of node that is an element.

        Cross-browser function for getting the document element of a frame or iframe.

        Parameters
        frame: Element
        Frame element.
        Returns
        The frame content document.

        Cross-browser function for getting the window of a frame or iframe.

        Parameters
        frame: Element
        Frame element.
        Returns
        The window associated with the given frame.

        Returns the last child node that is an element.

        Parameters
        node: Node
        The node to get the last child element of.
        Returns
        The last child node of node that is an element.

        Returns the first node that is an element in the specified direction, + starting with node.

        Parameters
        node: Node
        The node to get the next element from.
        forward: boolean
        Whether to look forwards or backwards.
        Returns
        The first element.

        Returns the first next sibling that is an element.

        Parameters
        node: Node
        The node to get the next sibling element of.
        Returns
        The next sibling of node that is an element.

        Returns the next node in source order from the given node.

        Parameters
        node: Node
        The node.
        Returns
        The next node in the DOM tree, or null if this was the last + node.
        code »goog.dom.getNodeAtOffset ( parent, offset, opt_result )Node

        Returns the node at a given offset in a parent node. If an object is + provided for the optional third parameter, the node and the remainder of the + offset will stored as properties of this object.

        Parameters
        parent: Node
        The parent node.
        offset: number
        The offset into the parent node.
        opt_result: Object=
        Object to be used to store the return value. The + return value will be stored in the form {node: Node, remainder: number} + if this object is provided.
        Returns
        The node at the given offset.

        Returns the text length of the text contained in a node, without markup. This + is equivalent to the selection length if the node was selected, or the number + of cursor movements to traverse the node. Images & BRs take one space. New + lines are ignored.

        Parameters
        node: Node
        The node whose text content length is being calculated.
        Returns
        The length of node's text content.
        code »goog.dom.getNodeTextOffset ( node, opt_offsetParent )number

        Returns the text offset of a node relative to one of its ancestors. The text + length is the same as the length calculated by goog.dom.getNodeTextLength.

        Parameters
        node: Node
        The node whose offset is being calculated.
        opt_offsetParent: Node=
        The node relative to which the offset will + be calculated. Defaults to the node's owner document's body.
        Returns
        The text offset.

        Gets the outerHTML of a node, which islike innerHTML, except that it + actually contains the HTML of the node itself.

        Parameters
        element: Element
        The element to get the HTML of.
        Returns
        The outerHTML of the given element.

        Returns the owner document for a node.

        Parameters
        node: (Node|Window)
        The node to get the document for.
        Returns
        The document owning the node.
        Deprecated: Use goog.dom.getDocumentScroll instead.

        Gets the page scroll distance as a coordinate object.

        Parameters
        opt_window: Window=
        Optional window element to test.
        Returns
        Object with values 'x' and 'y'.

        Returns an element's parent, if it's an Element.

        Parameters
        element: Element
        The DOM element.
        Returns
        The parent, or null if not an Element.

        Gives the current devicePixelRatio. + + By default, this is the value of window.devicePixelRatio (which should be + preferred if present). + + If window.devicePixelRatio is not present, the ratio is calculated with + window.matchMedia, if present. Otherwise, gives 1.0. + + Some browsers (including Chrome) consider the browser zoom level in the pixel + ratio, so the value may change across multiple calls.

        Returns
        The number of actual pixels per virtual pixel.

        Returns the first previous sibling that is an element.

        Parameters
        node: Node
        The node to get the previous sibling element of.
        Returns
        The first previous sibling of node that is + an element.

        Returns the previous node in source order from the given node.

        Parameters
        node: Node
        The node.
        Returns
        The previous node in the DOM tree, or null if this was the + first node.

        Returns the text content of the current node, without markup. + + Unlike getTextContent this method does not collapse whitespaces + or normalize lines breaks.

        Parameters
        node: Node
        The node from which we are getting content.
        Returns
        The raw text content.

        Gets an element by id, asserting that the element is found. + + This is used when an element is expected to exist, and should fail with + an assertion error if it does not (if assertions are enabled).

        Parameters
        id: string
        Element ID.
        Returns
        The element with the given ID, if it exists.

        Ensures an element with the given className exists, and then returns the + first element with the provided className.

        Parameters
        className: string
        the name of the class to look for.
        opt_root: (!Element|!Document)=
        Optional element or document to look + in.
        Returns
        The first item with the class name provided.
        Throws
        goog.asserts.AssertionError
        Thrown if no element is found.

        Helper function for getRequiredElementHelper functions, both static and + on DomHelper. Asserts the element with the given id exists.

        Parameters
        doc
        id
        Returns
        The element with the given ID, if it exists.

        Returns the text content of the current node, without markup and invisible + symbols. New lines are stripped and whitespace is collapsed, + such that each character would be visible. + + In browsers that support it, innerText is used. Other browsers attempt to + simulate it via node traversal. Line breaks are canonicalized in IE.

        Parameters
        node: Node
        The node from which we are getting content.
        Returns
        The text content.
        code »goog.dom.getTextContent_ ( node, buf, normalizeWhitespace )

        Recursive support function for text content retrieval.

        Parameters
        node: Node
        The node from which we are getting content.
        buf: Array
        string buffer.
        normalizeWhitespace: boolean
        Whether to normalize whitespace.

        Gets the dimensions of the viewport. + + Gecko Standards mode: + docEl.clientWidth Width of viewport excluding scrollbar. + win.innerWidth Width of viewport including scrollbar. + body.clientWidth Width of body element. + + docEl.clientHeight Height of viewport excluding scrollbar. + win.innerHeight Height of viewport including scrollbar. + body.clientHeight Height of document. + + Gecko Backwards compatible mode: + docEl.clientWidth Width of viewport excluding scrollbar. + win.innerWidth Width of viewport including scrollbar. + body.clientWidth Width of viewport excluding scrollbar. + + docEl.clientHeight Height of document. + win.innerHeight Height of viewport including scrollbar. + body.clientHeight Height of viewport excluding scrollbar. + + IE6/7 Standards mode: + docEl.clientWidth Width of viewport excluding scrollbar. + win.innerWidth Undefined. + body.clientWidth Width of body element. + + docEl.clientHeight Height of viewport excluding scrollbar. + win.innerHeight Undefined. + body.clientHeight Height of document element. + + IE5 + IE6/7 Backwards compatible mode: + docEl.clientWidth 0. + win.innerWidth Undefined. + body.clientWidth Width of viewport excluding scrollbar. + + docEl.clientHeight 0. + win.innerHeight Undefined. + body.clientHeight Height of viewport excluding scrollbar. + + Opera 9 Standards and backwards compatible mode: + docEl.clientWidth Width of viewport excluding scrollbar. + win.innerWidth Width of viewport including scrollbar. + body.clientWidth Width of viewport excluding scrollbar. + + docEl.clientHeight Height of document. + win.innerHeight Height of viewport including scrollbar. + body.clientHeight Height of viewport excluding scrollbar. + + WebKit: + Safari 2 + docEl.clientHeight Same as scrollHeight. + docEl.clientWidth Same as innerWidth. + win.innerWidth Width of viewport excluding scrollbar. + win.innerHeight Height of the viewport including scrollbar. + frame.innerHeight Height of the viewport exluding scrollbar. + + Safari 3 (tested in 522) + + docEl.clientWidth Width of viewport excluding scrollbar. + docEl.clientHeight Height of viewport excluding scrollbar in strict mode. + body.clientHeight Height of viewport excluding scrollbar in quirks mode.

        Parameters
        opt_window: Window=
        Optional window element to test.
        Returns
        Object with values 'width' and 'height'.

        Helper for getViewportSize.

        Parameters
        win: Window
        The window to get the view port size for.
        Returns
        Object with values 'width' and 'height'.
        code »goog.dom.getWindow ( opt_doc )!Window

        Gets the window object associated with the given document.

        Parameters
        opt_doc: Document=
        Document object to get window for.
        Returns
        The window associated with the given document.
        code »goog.dom.getWindow_ ( doc )!Window

        Helper for getWindow.

        Parameters
        doc: !Document
        Document object to get window for.
        Returns
        The window associated with the given document.

        Returns true if the element has a bounding rectangle that would be visible + (i.e. its width and height are greater than zero).

        Parameters
        element: Element
        Element to check.
        Returns
        Whether the element has a non-zero bounding rectangle.

        Returns true if the element has a specified tab index.

        Parameters
        element: Element
        Element to check.
        Returns
        Whether the element has a specified tab index.

        Converts an HTML string into a document fragment. The string must be + sanitized in order to avoid cross-site scripting. For example + goog.dom.htmlToDocumentFragment('&lt;img src=x onerror=alert(0)&gt;') + triggers an alert in all browsers, even if the returned document fragment + is thrown away immediately.

        Parameters
        htmlString: string
        The HTML string to convert.
        Returns
        The resulting document fragment.

        Helper for htmlToDocumentFragment.

        Parameters
        doc: !Document
        The document.
        htmlString: string
        The HTML string to convert.
        Returns
        The resulting document fragment.
        code »goog.dom.insertChildAt ( parent, child, index )

        Insert a child at a given index. If index is larger than the number of child + nodes that the parent currently has, the node is inserted as the last child + node.

        Parameters
        parent: Element
        The element into which to insert the child.
        child: Node
        The element to insert.
        index: number
        The index at which to insert the new child node. Must + not be negative.

        Inserts a new node after an existing reference node (i.e. as the next + sibling). If the reference node has no parent, then does nothing.

        Parameters
        newNode: Node
        Node to insert.
        refNode: Node
        Reference node to insert after.

        Inserts a new node before an existing reference node (i.e. as the previous + sibling). If the reference node has no parent, then does nothing.

        Parameters
        newNode: Node
        Node to insert.
        refNode: Node
        Reference node to insert before.

        Returns true if the browser is in "CSS1-compatible" (standards-compliant) + mode, false otherwise.

        Returns
        True if in CSS1-compatible mode.

        Returns true if the browser is in "CSS1-compatible" (standards-compliant) + mode, false otherwise.

        Parameters
        doc: Document
        The document to check.
        Returns
        True if in CSS1-compatible mode.

        Whether the object looks like an Element.

        Parameters
        obj: ?
        The object being tested for Element likeness.
        Returns
        Whether the object looks like an Element.

        Returns true if the element can be focused, i.e. it has a tab index that + allows it to receive keyboard focus (tabIndex >= 0), or it is an element + that natively supports keyboard focus.

        Parameters
        element: Element
        Element to check.
        Returns
        Whether the element allows keyboard focus.

        Returns true if the element has a tab index that allows it to receive + keyboard focus (tabIndex >= 0), false otherwise. Note that some elements + natively support keyboard focus, even if they have no tab index.

        Parameters
        element: Element
        Element to check.
        Returns
        Whether the element has a tab index that allows keyboard + focus.

        Whether the object looks like a DOM node.

        Parameters
        obj: ?
        The object being tested for node likeness.
        Returns
        Whether the object looks like a DOM node.

        Returns true if the object is a NodeList. To qualify as a NodeList, + the object must have a numeric length property and an item function (which + has type 'string' on IE for some reason).

        Parameters
        val: Object
        Object to test.
        Returns
        Whether the object is a NodeList.

        Returns true if the element's tab index allows the element to be focused.

        Parameters
        element: Element
        Element to check.
        Returns
        Whether the element's tab index allows focus.

        Returns true if the specified value is a Window object. This includes the + global window for HTML pages, and iframe windows.

        Parameters
        obj: ?
        Variable to test.
        Returns
        Whether the variable is a window.

        Calculates a mediaQuery to check if the current device supports the + given actual to virtual pixel ratio.

        Parameters
        pixelRatio: number
        The ratio of actual pixels to virtual pixels.
        Returns
        pixelRatio if applicable, otherwise 0.

        Returns true if the element is focusable even when tabIndex is not set.

        Parameters
        element: Element
        Element to check.
        Returns
        Whether the element natively supports focus.

        Removes all the child nodes on a DOM node.

        Parameters
        node: Node
        Node to remove children from.

        Removes a node from its parent.

        Parameters
        node: Node
        The node to remove.
        Returns
        The node removed if removed; else, null.
        code »goog.dom.replaceNode ( newNode, oldNode )

        Replaces a node in the DOM tree. Will do nothing if oldNode has no + parent.

        Parameters
        newNode: Node
        Node to insert.
        oldNode: Node
        Node to replace.

        Enables or disables keyboard focus support on the element via its tab index. + Only elements for which goog.dom.isFocusableTabIndex returns true + (or elements that natively support keyboard focus, like form elements) can + receive keyboard focus. See http://go/tabindex for more info.

        Parameters
        element: Element
        Element whose tab index is to be changed.
        enable: boolean
        Whether to set or remove a tab index on the element + that supports keyboard focus.
        code »goog.dom.setProperties ( element, properties )

        Sets multiple properties on a node.

        Parameters
        element: Element
        DOM node to set properties on.
        properties: Object
        Hash of property:value pairs.

        Sets the text content of a node, with cross-browser support.

        Parameters
        node: Node
        The node to change the text content of.
        text: (string|number)
        The value that should replace the node's content.

        Global Properties

        Whether we know the compatibility mode at compile time.

        Map of attributes that should be set using + element.setAttribute(key, val) instead of element[key] = val. Used + by goog.dom.setProperties.

        Map of tags which have predefined values with regard to whitespace.

        Map of tags whose content to ignore when calculating text length.

        Compiler Constants

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_dom_vendor.html b/docs/api/javascript/namespace_goog_dom_vendor.html new file mode 100644 index 0000000000000..b8e21e7053d74 --- /dev/null +++ b/docs/api/javascript/namespace_goog_dom_vendor.html @@ -0,0 +1,4 @@ +goog.dom.vendor

        Namespace goog.dom.vendor

        code »
        Show:

        Global Functions

        Parameters
        eventType: string
        An event type.
        Returns
        A lower-cased vendor prefixed event type.
        code »goog.dom.vendor.getPrefixedPropertyName ( propertyName, opt_object )?string
        Parameters
        propertyName: string
        A property name.
        opt_object: !Object=
        If provided, we verify if the property exists in + the object.
        Returns
        A vendor prefixed property name, or null if it does not + exist.

        Returns the JS vendor prefix used in CSS properties. Different vendors + use different methods of changing the case of the property names.

        Returns
        The JS vendor prefix or null if there is none.

        Returns the vendor prefix used in CSS properties.

        Returns
        The vendor prefix or null if there is none.
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_events.html b/docs/api/javascript/namespace_goog_events.html new file mode 100644 index 0000000000000..a072eb5af600b --- /dev/null +++ b/docs/api/javascript/namespace_goog_events.html @@ -0,0 +1,97 @@ +goog.events

        Namespace goog.events

        code »

        Interfaces

        goog.events.Listenable
        A listenable interface.
        goog.events.ListenableKey
        An interface that describes a single registered listener.

        Classes

        goog.events.BrowserEvent
        Accepts a browser event object and creates a patched, cross browser event + object.
        goog.events.Event
        A base class for event objects, so that they can support preventDefault and + stopPropagation.
        goog.events.EventId
        A templated class that is used when registering for events.
        goog.events.EventTarget
        An implementation of goog.events.Listenable with full W3C + EventTarget-like support (capture/bubble mechanism, stopping event + propagation, preventing default actions).
        goog.events.Listener
        Simple class that stores information about a listener
        goog.events.ListenerMap
        Creates a new listener map.

        Enumerations

        goog.events.BrowserFeature
        Enum of browser capabilities.
        goog.events.CaptureSimulationMode
        No Description.
        goog.events.EventType
        Constants for event names.
        goog.events.KeyCodes
        Key codes for common characters.
        Show:

        Type Definitions

        A typedef for event like objects that are dispatchable via the + goog.events.dispatchEvent function. strings are treated as the type for a + goog.events.Event. Objects are treated as an extension of a new + goog.events.Event with the type property of the object being used as the type + of the Event.

        Global Functions

        Dispatches an event (or event like object) and calls all listeners + listening for events of this type. The type of the event is decided by the + type property on the event object. + + If any of the listeners returns false OR calls preventDefault then this + function will return false. If one of the capture listeners calls + stopPropagation, then the bubble listeners won't fire.

        Parameters
        src: goog.events.Listenable
        The event target.
        e: goog.events.EventLike
        Event object.
        Returns
        If anyone called preventDefault on the event object (or + if any of the handlers returns false) this will also return false. + If there are no handlers, or if all handlers return true, this returns + true.

        Provides a nice string showing the normalized event objects public members

        Parameters
        e: Object
        Event Object.
        Returns
        String of the public members of the normalized event object.
        code »goog.events.fireListener ( listener, eventObject )boolean

        Fires a listener with a set of arguments

        Parameters
        listener: goog.events.Listener
        The listener object to call.
        eventObject: Object
        The event object to pass to the listener.
        Returns
        Result of listener.
        code »goog.events.fireListeners ( obj, type, capture, eventObject )boolean

        Fires an object's listeners of a particular type and phase

        Parameters
        obj: Object
        Object whose listeners to call.
        type: (string|!goog.events.EventId)
        Event type.
        capture: boolean
        Which event phase.
        eventObject: Object
        Event object to be passed to listener.
        Returns
        True if all listeners returned true else false.
        code »goog.events.fireListeners_ ( obj, type, capture, eventObject )boolean

        Fires an object's listeners of a particular type and phase.

        Parameters
        obj: Object
        Object whose listeners to call.
        type: (string|!goog.events.EventId)
        Event type.
        capture: boolean
        Which event phase.
        eventObject: Object
        Event object to be passed to listener.
        Returns
        True if all listeners returned true else false.
        code »<EVENTOBJ> goog.events.getListener ( src, type, listener, opt_capt, opt_handler )goog.events.ListenableKey

        Gets the goog.events.Listener for the event or null if no such listener is + in use.

        Parameters
        src: (EventTarget|goog.events.Listenable)
        The target from + which to get listeners.
        type: (?string|!goog.events.EventId.<EVENTOBJ>)
        The type of the event.
        listener: (function(EVENTOBJ): ?|{handleEvent: function(?): ?}|null)
        The + listener function to get.
        opt_capt: boolean=
        In DOM-compliant browsers, this determines + whether the listener is fired during the + capture or bubble phase of the event.
        opt_handler: Object=
        Element in whose scope to call the listener.
        Returns
        the found listener or null if not found.
        Parameters
        src: EventTarget
        The source object.
        Returns
        A listener map for the given + source object, or null if none exists.

        Gets the listeners for a given object, type and capture phase.

        Parameters
        obj: Object
        Object to get listeners for.
        type: (string|!goog.events.EventId)
        Event type.
        capture: boolean
        Capture phase?.
        Returns
        Array of listener objects.

        Returns a string with on prepended to the specified type. This is used for IE + which expects "on" to be prepended. This function caches the string in order + to avoid extra allocations in steady state.

        Parameters
        type: string
        Event type.
        Returns
        The type string with 'on' prepended.

        Helper function for returning a proxy function.

        Returns
        A new or reused function object.
        Deprecated: This returns estimated count, now that Closure no longer + stores a central listener registry. We still return an estimation + to keep existing listener-related tests passing. In the near future, + this function will be removed.

        Gets the total number of listeners currently in the system.

        Returns
        Number of listeners.

        Creates a unique event id.

        Parameters
        identifier: string
        The identifier.
        Returns
        A unique identifier.

        Returns a prefixed event name for the current browser.

        Parameters
        eventName: string
        The name of the event.
        Returns
        The prefixed event name.

        Handles an event and dispatches it to the correct listeners. This + function is a proxy for the real listener the user specified.

        Parameters
        listener: goog.events.Listener
        The listener object.
        opt_evt: Event=
        Optional event object that gets passed in via the + native event handlers.
        Returns
        Result of the event handler.
        code »goog.events.hasListener ( obj, opt_type, opt_capture )boolean

        Returns whether an event target has any active listeners matching the + specified signature. If either the type or capture parameters are + unspecified, the function will match on the remaining criteria.

        Parameters
        obj: (EventTarget|goog.events.Listenable)
        Target to get + listeners for.
        opt_type: (string|!goog.events.EventId)=
        Event type.
        opt_capture: boolean=
        Whether to check for capture or bubble-phase + listeners.
        Returns
        Whether an event target has one or more listeners matching + the requested type and/or capture phase.

        This is used to check if an IE event has already been handled by the Closure + system so we do not do the Closure pass twice for a bubbling event.

        Parameters
        e: Event
        The IE browser event.
        Returns
        True if the event object has been marked.
        code »<T, EVENTOBJ> goog.events.listen ( src, type, listener, opt_capt, opt_handler )goog.events.Key

        Adds an event listener for a specific event on a native event + target (such as a DOM element) or an object that has implemented + goog.events.Listenable. A listener can only be added once + to an object and if it is added again the key for the listener is + returned. Note that if the existing listener is a one-off listener + (registered via listenOnce), it will no longer be a one-off + listener after a call to listen().

        Parameters
        src: (EventTarget|goog.events.Listenable)
        The node to listen + to events on.
        type: (string|Array.<string>|!goog.events.EventId.<EVENTOBJ>|!Array)
        Event type or array of event types.
        listener: (function(this: T, EVENTOBJ): ?|{handleEvent: function(?): ?}|null)
        Callback method, or an object with a handleEvent function. + WARNING: passing an Object is now softly deprecated.
        opt_capt: boolean=
        Whether to fire in capture phase (defaults to + false).
        opt_handler: T=
        Element in whose scope to call the listener.
        Returns
        Unique key for the listener.
        code »<T, EVENTOBJ> goog.events.listenOnce ( src, type, listener, opt_capt, opt_handler )goog.events.Key

        Adds an event listener for a specific event on a native event + target (such as a DOM element) or an object that has implemented + goog.events.Listenable. After the event has fired the event + listener is removed from the target. + + If an existing listener already exists, listenOnce will do + nothing. In particular, if the listener was previously registered + via listen(), listenOnce() will not turn the listener into a + one-off listener. Similarly, if there is already an existing + one-off listener, listenOnce does not modify the listeners (it is + still a once listener).

        Parameters
        src: (EventTarget|goog.events.Listenable)
        The node to listen + to events on.
        type: (string|Array.<string>|!goog.events.EventId.<EVENTOBJ>|!Array)
        Event type or array of event types.
        listener: (function(this: T, EVENTOBJ): ?|{handleEvent: function(?): ?}|null)
        Callback method.
        opt_capt: boolean=
        Fire in capture phase?.
        opt_handler: T=
        Element in whose scope to call the listener.
        Returns
        Unique key for the listener.
        code »<T> goog.events.listenWithWrapper ( src, wrapper, listener, opt_capt, opt_handler )

        Adds an event listener with a specific event wrapper on a DOM Node or an + object that has implemented goog.events.Listenable. A listener can + only be added once to an object.

        Parameters
        src: (EventTarget|goog.events.Listenable)
        The target to + listen to events on.
        wrapper: goog.events.EventWrapper
        Event wrapper to use.
        listener: (function(this: T, ?): ?|{handleEvent: function(?): ?}|null)
        Callback method, or an object with a handleEvent function.
        opt_capt: boolean=
        Whether to fire in capture phase (defaults to + false).
        opt_handler: T=
        Element in whose scope to call the listener.
        code »goog.events.listen_ ( src, type, listener, callOnce, opt_capt, opt_handler )goog.events.ListenableKey

        Adds an event listener for a specific event on a native event + target. A listener can only be added once to an object and if it + is added again the key for the listener is returned. + + Note that a one-off listener will not change an existing listener, + if any. On the other hand a normal listener will change existing + one-off listener to become a normal listener.

        Parameters
        src: EventTarget
        The node to listen to events on.
        type: (string|!goog.events.EventId)
        Event type.
        listener: !Function
        Callback function.
        callOnce: boolean
        Whether the listener is a one-off + listener or otherwise.
        opt_capt: boolean=
        Whether to fire in capture phase (defaults to + false).
        opt_handler: Object=
        Element in whose scope to call the listener.
        Returns
        Unique key for the listener.

        This is used to mark the IE event object so we do not do the Closure pass + twice for a bubbling event.

        Parameters
        e: Event
        The IE browser event.

        Installs exception protection for the browser event entry point using the + given error handler.

        Parameters
        errorHandler: goog.debug.ErrorHandler
        Error handler with which to + protect the entry point.
        code »goog.events.removeAll ( obj, opt_type )number

        Removes all listeners from an object. You can also optionally + remove listeners of a particular type.

        Parameters
        obj: (Object|undefined)
        Object to remove listeners from. Must be an + EventTarget or a goog.events.Listenable.
        opt_type: (string|!goog.events.EventId)=
        Type of event to remove. + Default is all types.
        Returns
        Number of listeners removed.
        Deprecated: This doesn't do anything, now that Closure no longer + stores a central listener registry.

        Removes all native listeners registered via goog.events. Native + listeners are listeners on native browser objects (such as DOM + elements). In particular, goog.events.Listenable and + goog.events.EventTarget listeners will NOT be removed.

        Returns
        Number of listeners removed.
        code »<EVENTOBJ> goog.events.unlisten ( src, type, listener, opt_capt, opt_handler )?boolean

        Removes an event listener which was added with listen().

        Parameters
        src: (EventTarget|goog.events.Listenable)
        The target to stop + listening to events on.
        type: (string|Array.<string>|!goog.events.EventId.<EVENTOBJ>|!Array)
        Event type or array of event types to unlisten to.
        listener: (function(?): ?|{handleEvent: function(?): ?}|null)
        The + listener function to remove.
        opt_capt: boolean=
        In DOM-compliant browsers, this determines + whether the listener is fired during the capture or bubble phase of the + event.
        opt_handler: Object=
        Element in whose scope to call the listener.
        Returns
        indicating whether the listener was there to remove.

        Removes an event listener which was added with listen() by the key + returned by listen().

        Parameters
        key: goog.events.Key
        The key returned by listen() for this + event listener.
        Returns
        indicating whether the listener was there to remove.
        code »goog.events.unlistenWithWrapper ( src, wrapper, listener, opt_capt, opt_handler )

        Removes an event listener which was added with listenWithWrapper().

        Parameters
        src: (EventTarget|goog.events.Listenable)
        The target to stop + listening to events on.
        wrapper: goog.events.EventWrapper
        Event wrapper to use.
        listener: (function(?): ?|{handleEvent: function(?): ?}|null)
        The + listener function to remove.
        opt_capt: boolean=
        In DOM-compliant browsers, this determines + whether the listener is fired during the capture or bubble phase of the + event.
        opt_handler: Object=
        Element in whose scope to call the listener.
        Parameters
        listener: (Object|Function)
        The listener function or an + object that contains handleEvent method.
        Returns
        Either the original function or a function that + calls obj.handleEvent. If the same listener is passed to this + function more than once, the same function is guaranteed to be + returned.

        Global Properties

        Property name on a native event target for the listener map + associated with the event target.

        Expando property for listener function wrapper for Object with + handleEvent.

        Estimated count of total native listeners.

        Map of computed "on" strings for IE event types. Caching + this removes an extra object allocation in goog.events.listen which + improves IE6 performance.

        String used to prepend to IE event types.

        Counter to create unique event ids.

        Compiler Constants

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_functions.html b/docs/api/javascript/namespace_goog_functions.html index 2c6b22d5d997e..a40a71094c307 100644 --- a/docs/api/javascript/namespace_goog_functions.html +++ b/docs/api/javascript/namespace_goog_functions.html @@ -27,4 +27,4 @@ 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 + 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/docs/api/javascript/namespace_goog_iter.html b/docs/api/javascript/namespace_goog_iter.html index d2c1cc4f337c8..eacac6f1b6838 100644 --- a/docs/api/javascript/namespace_goog_iter.html +++ b/docs/api/javascript/namespace_goog_iter.html @@ -186,4 +186,4 @@ 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 + 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/docs/api/javascript/namespace_goog_json.html b/docs/api/javascript/namespace_goog_json.html index 401618f0de685..a8d41253f9f47 100644 --- a/docs/api/javascript/namespace_goog_json.html +++ b/docs/api/javascript/namespace_goog_json.html @@ -1,10 +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 +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 + 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 + 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/docs/api/javascript/namespace_goog_labs.html b/docs/api/javascript/namespace_goog_labs.html index 275cd5427fee4..ec6f76c15d8d6 100644 --- a/docs/api/javascript/namespace_goog_labs.html +++ b/docs/api/javascript/namespace_goog_labs.html @@ -1 +1 @@ -goog.labs

        Namespace goog.labs

        code »
        Show:
        \ No newline at end of file +goog.labs

        Namespace goog.labs

        code »
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_labs_testing.html b/docs/api/javascript/namespace_goog_labs_testing.html index 2d4df991e5f73..e97e64365c2c9 100644 --- a/docs/api/javascript/namespace_goog_labs_testing.html +++ b/docs/api/javascript/namespace_goog_labs_testing.html @@ -1 +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 +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/docs/api/javascript/namespace_goog_labs_userAgent.html b/docs/api/javascript/namespace_goog_labs_userAgent.html index 1108d076245aa..732c4b750dd38 100644 --- a/docs/api/javascript/namespace_goog_labs_userAgent.html +++ b/docs/api/javascript/namespace_goog_labs_userAgent.html @@ -1 +1 @@ -goog.labs.userAgent

        Namespace goog.labs.userAgent

        code »
        Show:
        \ No newline at end of file +goog.labs.userAgent

        Namespace goog.labs.userAgent

        code »
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_labs_userAgent_browser.html b/docs/api/javascript/namespace_goog_labs_userAgent_browser.html index 306bf260fd25d..acc4108adae46 100644 --- a/docs/api/javascript/namespace_goog_labs_userAgent_browser.html +++ b/docs/api/javascript/namespace_goog_labs_userAgent_browser.html @@ -1,15 +1,13 @@ -goog.labs.userAgent.browser

        Namespace goog.labs.userAgent.browser

        code »
        Show:

        Global Functions

        Determines IE version. More information: +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 + 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.
        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 + details.)
        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/docs/api/javascript/namespace_goog_labs_userAgent_engine.html b/docs/api/javascript/namespace_goog_labs_userAgent_engine.html index 90ed19b95d438..1f9b838a91b7c 100644 --- a/docs/api/javascript/namespace_goog_labs_userAgent_engine.html +++ b/docs/api/javascript/namespace_goog_labs_userAgent_engine.html @@ -1,4 +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 + as the given version.
        Returns
        Whether the rendering engine is WebKit.
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_labs_userAgent_util.html b/docs/api/javascript/namespace_goog_labs_userAgent_util.html index b84a141e89e4f..e56994c688ea4 100644 --- a/docs/api/javascript/namespace_goog_labs_userAgent_util.html +++ b/docs/api/javascript/namespace_goog_labs_userAgent_util.html @@ -6,4 +6,4 @@ 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 + navigator.userAgent but use a specified value for detection instead. \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_math.html b/docs/api/javascript/namespace_goog_math.html index 7ba748a1ae116..224a4e663599f 100644 --- a/docs/api/javascript/namespace_goog_math.html +++ b/docs/api/javascript/namespace_goog_math.html @@ -1,4 +1,4 @@ -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). +goog.math

        Namespace goog.math

        code »

        Classes

        goog.math.Box
        Class for representing a box.
        goog.math.Coordinate
        Class for representing coordinates and positions.
        goog.math.Rect
        Class for representing rectangular regions.
        goog.math.Size
        Class for representing sizes consisting of a width and height.
        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 @@ -58,4 +58,4 @@ 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 + 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/docs/api/javascript/namespace_goog_net.html b/docs/api/javascript/namespace_goog_net.html index a8e5b1dc111fe..8079e415c6bcc 100644 --- a/docs/api/javascript/namespace_goog_net.html +++ b/docs/api/javascript/namespace_goog_net.html @@ -1 +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 +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/docs/api/javascript/namespace_goog_net_XmlHttp.html b/docs/api/javascript/namespace_goog_net_XmlHttp.html index e116d8959b654..6d28fc5eb2a23 100644 --- a/docs/api/javascript/namespace_goog_net_XmlHttp.html +++ b/docs/api/javascript/namespace_goog_net_XmlHttp.html @@ -1,4 +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 + 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/docs/api/javascript/namespace_goog_net_XmlHttpDefines.html b/docs/api/javascript/namespace_goog_net_XmlHttpDefines.html index eaedcebe8c407..18c999c13250d 100644 --- a/docs/api/javascript/namespace_goog_net_XmlHttpDefines.html +++ b/docs/api/javascript/namespace_goog_net_XmlHttpDefines.html @@ -1 +1 @@ -goog.net.XmlHttpDefines

        Namespace goog.net.XmlHttpDefines

        code »
        Show:

        Compiler Constants

        \ No newline at end of file +goog.net.XmlHttpDefines

        Namespace goog.net.XmlHttpDefines

        code »
        Show:

        Compiler Constants

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_object.html b/docs/api/javascript/namespace_goog_object.html index 11a0649abb734..c9af760a4b494 100644 --- a/docs/api/javascript/namespace_goog_object.html +++ b/docs/api/javascript/namespace_goog_object.html @@ -1,22 +1,22 @@ -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 +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 + 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 + 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 + as the property names.Returns

        The new object.

        Compares two objects for equality using === on the values.

        Parameters
        a
        b
        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. + 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: @@ -26,47 +26,47 @@ 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 + 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 + 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 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 + 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. + 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. + 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 + 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 + 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 + 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 + 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 + 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: @@ -74,4 +74,4 @@ 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 + 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/docs/api/javascript/namespace_goog_reflect.html b/docs/api/javascript/namespace_goog_reflect.html new file mode 100644 index 0000000000000..68871f5877651 --- /dev/null +++ b/docs/api/javascript/namespace_goog_reflect.html @@ -0,0 +1,7 @@ +goog.reflect

        Namespace goog.reflect

        code »
        Show:

        Global Functions

        Check if a property can be accessed without throwing an exception.

        Parameters
        obj: Object
        The owner of the property.
        prop: string
        The property name.
        Returns
        Whether the property is accessible. Will also return true + if obj is null.
        code »goog.reflect.object ( type, object )Object

        Syntax for object literal casts.

        Parameters
        type: !Function
        Type to cast to.
        object: Object
        Object literal to cast.
        Returns
        The object literal.

        To assert to the compiler that an operation is needed when it would + otherwise be stripped. For example: + + // Force a layout + goog.reflect.sinkValue(dialog.offsetHeight); +

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_string.html b/docs/api/javascript/namespace_goog_string.html index 3ccce5b4fada6..e4ace34fba831 100644 --- a/docs/api/javascript/namespace_goog_string.html +++ b/docs/api/javascript/namespace_goog_string.html @@ -1,4 +1,4 @@ -goog.string

        Namespace goog.string

        code »

        Enumerations

        goog.string.Unicode
        Common Unicode string characters.
        Show:

        Global Functions

        Concatenates string expressions. This is useful +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 @@ -10,24 +10,24 @@ 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 + 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. + 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. + -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. + -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. + 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(). + 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 @@ -71,12 +71,12 @@ 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"). + 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"). + 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 + 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 @@ -89,12 +89,12 @@ 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. + 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. + 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 @@ -107,13 +107,13 @@ 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 + 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. + 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 @@ -134,18 +134,16 @@ 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 + %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. + 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.

        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 + (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 + 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 @@ -183,6 +181,6 @@ 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. + 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 + 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/docs/api/javascript/namespace_goog_structs.html b/docs/api/javascript/namespace_goog_structs.html index d80ee826a2596..3b83e2bd990c0 100644 --- a/docs/api/javascript/namespace_goog_structs.html +++ b/docs/api/javascript/namespace_goog_structs.html @@ -1,4 +1,4 @@ -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 +goog.structs

        Namespace goog.structs

        code »

        Interfaces

        goog.structs.Collection
        An interface for a collection of values.

        Classes

        goog.structs.Map
        Class for Hash Map datastructure.
        goog.structs.Set
        A set that can contain both primitives and objects.
        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 @@ -35,4 +35,4 @@ 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 + within f.Returns
        True if any value passes the test.
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_style.html b/docs/api/javascript/namespace_goog_style.html new file mode 100644 index 0000000000000..0c25e81b35470 --- /dev/null +++ b/docs/api/javascript/namespace_goog_style.html @@ -0,0 +1,211 @@ +goog.style

        Namespace goog.style

        code »
        Show:

        Global Functions

        Clears the background image of an element in a browser independent manner.

        Parameters
        el: Element
        The element to clear background image for.

        Call fn on element such that element's dimensions are + accurate when it's passed to fn.

        Parameters
        fn: function(!Element): T
        Function to call with element as + an argument after temporarily changing element's display such + that its dimensions are accurate.
        element: !Element
        Element (which may have display none) to use as + argument to fn.
        Returns
        Value returned by calling fn with element.

        Retrieves the computed background color string for a given element. The + string returned is suitable for assigning to another element's + background-color, but is not guaranteed to be in any particular string + format. Accessing the color in a numeric form may not be possible in all + browsers or with all input. + + If the background color for the element is defined as a hexadecimal value, + the resulting string can be parsed by goog.color.parse in all supported + browsers. + + Whether named colors like "red" or "lightblue" get translated into a + format which can be parsed is browser dependent. Calling this function on + transparent elements will return "transparent" in most browsers or + "rgba(0, 0, 0, 0)" in WebKit.

        Parameters
        element: Element
        The element to get the background color of.
        Returns
        The computed string value of the background color.

        Gets the computed border widths (on all sides) in pixels

        Parameters
        element: Element
        The element to get the border widths for.
        Returns
        The computed border widths.

        Gets the border box size for an element.

        Parameters
        element: Element
        The element to get the size for.
        Returns
        The border box size.

        Gets the client rectangle of the DOM element. + + getBoundingClientRect is part of a new CSS object model draft (with a + long-time presence in IE), replacing the error-prone parent offset + computation and the now-deprecated Gecko getBoxObjectFor. + + This utility patches common browser bugs in getBoundingClientRect. It + will fail if getBoundingClientRect is unsupported. + + If the element is not in the DOM, the result is undefined, and an error may + be thrown depending on user agent.

        Parameters
        el: !Element
        The element whose bounding rectangle is being queried.
        Returns
        A native bounding rectangle with numerical left, top, + right, and bottom. Reported by Firefox to be of object type ClientRect.

        Returns a bounding rectangle for a given element in page space.

        Parameters
        element: Element
        Element to get bounds of. Must not be display none.
        Returns
        Bounding rectangle for the element.
        code »goog.style.getBox_ ( element, stylePrefix )!goog.math.Box

        Gets the computed paddings or margins (on all sides) in pixels.

        Parameters
        element: Element
        The element to get the padding for.
        stylePrefix: string
        Pass 'padding' to retrieve the padding box, + or 'margin' to retrieve the margin box.
        Returns
        The computed paddings or margins.

        Gets the cascaded style value of a node, or null if the value cannot be + computed (only Internet Explorer can do this).

        Parameters
        element: Element
        Element to get style of.
        style: string
        Property to get (camel-case).
        Returns
        Style value.

        Returns clientLeft (width of the left border and, if the directionality is + right to left, the vertical scrollbar) and clientTop as a coordinate object.

        Parameters
        el: Element
        Element to get clientLeft for.
        Returns
        Client left and top.

        Returns the position of the event or the element's border box relative to + the client viewport.

        Parameters
        el: (Element|Event|goog.events.Event)
        Element or a mouse / touch event.
        Returns
        The position.

        Returns the position of the event or the element's border box relative to + the client viewport.

        Parameters
        el: !Element
        Element whose position to get.
        Returns
        The position.

        Returns the viewport element for a particular document

        Parameters
        opt_node: Node=
        DOM node (Document is OK) to get the viewport element + of.
        Returns
        document.documentElement or document.body.

        Retrieves the computed value of the box-sizing CSS attribute. + Browser support: http://caniuse.com/css3-boxsizing.

        Parameters
        element: !Element
        The element whose box-sizing to get.
        Returns
        'content-box', 'border-box' or 'padding-box'. null if + box-sizing is not supported (IE7 and below).

        Retrieves the computed value of the cursor CSS attribute.

        Parameters
        element: Element
        The element to get the cursor of.
        Returns
        The computed string value of the cursor attribute.

        Retrieves the computed value of the overflow-x CSS attribute.

        Parameters
        element: Element
        The element to get the overflow-x of.
        Returns
        The computed string value of the overflow-x attribute.

        Retrieves the computed value of the overflow-y CSS attribute.

        Parameters
        element: Element
        The element to get the overflow-y of.
        Returns
        The computed string value of the overflow-y attribute.

        Retrieves the computed value of the position CSS attribute.

        Parameters
        element: Element
        The element to get the position of.
        Returns
        Position value.
        code »goog.style.getComputedStyle ( element, property )string

        Retrieves a computed style value of a node. It returns empty string if the + value cannot be computed (which will be the case in Internet Explorer) or + "none" if the property requested is an SVG one and it has not been + explicitly set (firefox and webkit).

        Parameters
        element: Element
        Element to get style of.
        property: string
        Property to get (camel-case).
        Returns
        Style value.

        Retrieves the computed value of the text-align CSS attribute.

        Parameters
        element: Element
        The element to get the text-align of.
        Returns
        The computed string value of the text-align attribute.

        Retrieves the computed value of the CSS transform attribute.

        Parameters
        element: Element
        The element to get the transform of.
        Returns
        The computed string representation of the transform matrix.

        Retrieves the computed value of the z-index CSS attribute.

        Parameters
        element: Element
        The element to get the z-index of.
        Returns
        The computed value of the z-index attribute.

        Calculate the scroll position of container with the minimum amount so + that the content and the borders of the given element become visible. + If the element is bigger than the container, its top left corner will be + aligned as close to the container's top left corner as possible.

        Parameters
        element: Element
        The element to make visible.
        container: Element
        The container to scroll.
        opt_center: boolean=
        Whether to center the element in the container. + Defaults to false.
        Returns
        The new scroll position of the container, + in form of goog.math.Coordinate(scrollLeft, scrollTop).

        Gets the content box size for an element. This is potentially expensive in + all browsers.

        Parameters
        element: Element
        The element to get the size for.
        Returns
        The content box size.

        Returns the x,y translation component of any CSS transforms applied to the + element, in pixels.

        Parameters
        element: !Element
        The element to get the translation of.
        Returns
        The CSS translation of the element in px.

        Gets value of explicitly-set float CSS property on an element.

        Parameters
        el: Element
        The element to get float property of.
        Returns
        The value of explicitly-set float CSS property on this + element.

        Returns the font face applied to a given node. Opera and IE should return + the font actually displayed. Firefox returns the author's most-preferred + font (whether the browser is capable of displaying it or not.)

        Parameters
        el: Element
        The element whose font family is returned.
        Returns
        The font family applied to el.

        Returns the font size, in pixels, of text in an element.

        Parameters
        el: Element
        The element whose font size is returned.
        Returns
        The font size (in pixels).

        Returns a Coordinate object relative to the top-left of an HTML document + in an ancestor frame of this element. Used for measuring the position of + an element inside a frame relative to a containing frame.

        Parameters
        el: Element
        Element to get the page offset for.
        relativeWin: Window
        The window to measure relative to. If relativeWin + is not in the ancestor frame chain of the element, we measure relative to + the top-most window.
        Returns
        The page offset.

        Helper function for IE to get the pixel border.

        Parameters
        element: Element
        The element to get the pixel border for.
        prop: string
        The part of the property name.
        Returns
        The value in pixels.

        Helper function for getting the pixel padding or margin for IE.

        Parameters
        element: Element
        The element to get the padding for.
        propName: string
        The property name.
        Returns
        The pixel padding.
        code »goog.style.getIePixelValue_ ( element, value, name, pixelName )number

        IE specific function that converts a non pixel unit to pixels.

        Parameters
        element: Element
        The element to convert the value for.
        value: string
        The current value as a string. The value must not be + ''.
        name: string
        The CSS property name to use for the converstion. This + should be 'left', 'top', 'width' or 'height'.
        pixelName: string
        The CSS pixel property name to use to get the + value in pixels.
        Returns
        The value in pixels.

        Returns the units used for a CSS length measurement.

        Parameters
        value: string
        A CSS length quantity.
        Returns
        The units of measurement.

        Gets the computed margins (on all sides) in pixels.

        Parameters
        element: Element
        The element to get the margins for.
        Returns
        The computed margins.

        Returns the first parent that could affect the position of a given element.

        Parameters
        element: Element
        The element to get the offset parent for.
        Returns
        The first offset parent or null if one cannot be found.

        Gets the opacity of a node (x-browser). This gets the inline style opacity + of the node, and does not take into account the cascaded or the computed + style for this node.

        Parameters
        el: Element
        Element whose opacity has to be found.
        Returns
        Opacity between 0 and 1 or an empty string '' + if the opacity is not set.

        Gets the computed paddings (on all sides) in pixels.

        Parameters
        element: Element
        The element to get the padding for.
        Returns
        The computed paddings.

        Returns a Coordinate object relative to the top-left of the HTML document. + Implemented as a single function to save having to do two recursive loops in + opera and safari just to get both coordinates. If you just want one value do + use goog.style.getPageOffsetLeft() and goog.style.getPageOffsetTop(), but + note if you call both those methods the tree will be analysed twice.

        Parameters
        el: Element
        Element to get the page offset for.
        Returns
        The page offset.

        Returns the left coordinate of an element relative to the HTML document

        Parameters
        el: Element
        Elements.
        Returns
        The left coordinate.

        Returns the top coordinate of an element relative to the HTML document

        Parameters
        el: Element
        Elements.
        Returns
        The top coordinate.

        Helper function to create a string to be set into a pixel-value style + property of an element. Can round to the nearest integer value.

        Parameters
        value: (string|number)
        The style value to be used. If a number, + 'px' will be appended, otherwise the value will be applied directly.
        round: boolean
        Whether to round the nearest integer (if property + is a number).
        Returns
        The string value for the property.

        Gets the offsetLeft and offsetTop properties of an element and returns them + in a Coordinate object

        Parameters
        element: Element
        Element.
        Returns
        The position.

        Returns the position of an element relative to another element in the + document. A relative to B

        Parameters
        a: (Element|Event|goog.events.Event)
        Element or mouse event whose + position we're calculating.
        b: (Element|Event|goog.events.Event)
        Element or mouse event position + is relative to.
        Returns
        The relative position.

        Returns the scroll bar width (represents the width of both horizontal + and vertical scroll).

        Parameters
        opt_className: string=
        An optional class name (or names) to apply + to the invisible div created to measure the scrollbar. This is necessary + if some scrollbars are styled differently than others.
        Returns
        The scroll bar width in px.

        Gets the height and width of an element, even if its display is none. + + Specifically, this returns the height and width of the border box, + irrespective of the box model in effect. + + Note that this function does not take CSS transforms into account. Please see + goog.style.getTransformedSize.

        Parameters
        element: Element
        Element to get size of.
        Returns
        Object with width/height properties.

        Gets the height and width of an element when the display is not none.

        Parameters
        element: Element
        Element to get size of.
        Returns
        Object with width/height properties.
        code »goog.style.getStyle ( element, property )string

        Retrieves an explicitly-set style value of a node. This returns '' if there + isn't a style attribute on the element or if this style property has not been + explicitly set in script.

        Parameters
        element: Element
        Element to get style of.
        property: string
        Property to get, css-style (if you have a camel-case + property, use element.style[style]).
        Returns
        Style value.
        code »goog.style.getStyle_ ( element, style )string

        Cross-browser pseudo get computed style. It returns the computed style where + available. If not available it tries the cascaded style value (IE + currentStyle) and in worst case the inline style value. It shouldn't be + called directly, see http://wiki/Main/ComputedStyleVsCascadedStyle for + discussion.

        Parameters
        element: Element
        Element to get style of.
        style: string
        Property to get (must be camelCase, not css-style.).
        Returns
        Style value.

        Gets the height and width of an element, post transform, even if its display + is none. + + This is like goog.style.getSize, except: +

          +
        1. Takes webkitTransforms such as rotate and scale into account. +
        2. Will return null if element doesn't respond to + getBoundingClientRect. +
        3. Currently doesn't make sense on non-WebKit browsers which don't support + webkitTransforms. +
        Parameters
        element: !Element
        Element to get size of.
        Returns
        Object with width/height properties.

        Returns the style property name in camel-case. If it does not exist and a + vendor-specific version of the property does exist, then return the vendor- + specific property name instead.

        Parameters
        element: Element
        The element to change.
        style: string
        Style name.
        Returns
        Vendor-specific style.

        Returns the style property name in CSS notation. If it does not exist and a + vendor-specific version of the property does exist, then return the vendor- + specific property name instead.

        Parameters
        element: Element
        The element to change.
        style: string
        Style name.
        Returns
        Vendor-specific style.

        Calculates the viewport coordinates relative to the page/document + containing the node. The viewport may be the browser viewport for + non-iframe document, or the iframe container for iframe'd document.

        Parameters
        doc: !Document
        The document to use as the reference point.
        Returns
        The page offset of the viewport.

        Calculates and returns the visible rectangle for a given element. Returns a + box describing the visible portion of the nearest scrollable offset ancestor. + Coordinates are given relative to the document.

        Parameters
        element: Element
        Element to get the visible rect for.
        Returns
        Bounding elementBox describing the visible rect or + null if scrollable ancestor isn't inside the visible viewport.
        code »goog.style.installStyles ( stylesString, opt_node )(Element|StyleSheet)

        Installs the styles string into the window that contains opt_element. If + opt_element is null, the main window is used.

        Parameters
        stylesString: string
        The style string to install.
        opt_node: Node=
        Node whose parent document should have the + styles installed.
        Returns
        The style element created.

        Test whether the given element has been shown or hidden via a call to + #setElementShown. + + Note this is strictly a companion method for a call + to #setElementShown and the same caveats apply; in particular, this + method does not guarantee that the return value will be consistent with + whether or not the element is actually visible.

        Parameters
        el: Element
        The element to test.
        Returns
        Whether the element has been shown.

        Returns true if the element is using right to left (rtl) direction.

        Parameters
        el: Element
        The element to test.
        Returns
        True for right to left, false for left to right.

        Returns true if the element is set to be unselectable, false otherwise. + Note that on some platforms (e.g. Mozilla), even if an element isn't set + to be unselectable, it will behave as such if any of its ancestors is + unselectable.

        Parameters
        el: Element
        Element to check.
        Returns
        Whether the element is set to be unselectable.

        Parses a style attribute value. Converts CSS property names to camel case.

        Parameters
        value: string
        The style attribute value.
        Returns
        Map of CSS properties to string values.
        code »goog.style.scrollIntoContainerView ( element, container, opt_center )

        Changes the scroll position of container with the minimum amount so + that the content and the borders of the given element become visible. + If the element is bigger than the container, its top left corner will be + aligned as close to the container's top left corner as possible.

        Parameters
        element: Element
        The element to make visible.
        container: Element
        The container to scroll.
        opt_center: boolean=
        Whether to center the element in the container. + Defaults to false.

        Sets the border box size of an element. This is potentially expensive in IE + if the document is CSS1Compat mode

        Parameters
        element: Element
        The element to set the size on.
        size: goog.math.Size
        The new size.
        code »goog.style.setBoxSizingSize_ ( element, size, boxSizing )

        Helper function that sets the box sizing as well as the width and height

        Parameters
        element: Element
        The element to set the size on.
        size: goog.math.Size
        The new size to set.
        boxSizing: string
        The box-sizing value.

        Sets the content box size of an element. This is potentially expensive in IE + if the document is BackCompat mode.

        Parameters
        element: Element
        The element to set the size on.
        size: goog.math.Size
        The new size.

        Shows or hides an element from the page. Hiding the element is done by + setting the display property to "none", removing the element from the + rendering hierarchy so it takes up no space. To show the element, the default + inherited display property is restored (defined either in stylesheets or by + the browser's default style rules). + + Caveat 1: if the inherited display property for the element is set to "none" + by the stylesheets, that is the property that will be restored by a call to + setElementShown(), effectively toggling the display between "none" and + "none". + + Caveat 2: if the element display style is set inline (by setting either + element.style.display or a style attribute in the HTML), a call to + setElementShown will clear that setting and defer to the inherited style in + the stylesheet.

        Parameters
        el: Element
        Element to show or hide.
        isShown: *
        True to render the element in its default style, + false to disable rendering the element.

        Sets CSS float property on an element.

        Parameters
        el: Element
        The element to set float property on.
        value: string
        The value of float CSS property to set on this element.
        code »goog.style.setHeight ( element, height )

        Set the height of an element. Sets the element's style property.

        Parameters
        element: Element
        Element to set the height of.
        height: (string|number)
        The height value to set. If a number, 'px' + will be appended, otherwise the value will be applied directly.

        Sets 'display: inline-block' for an element (cross-browser).

        Parameters
        el: Element
        Element to which the inline-block display style is to be + applied.

        Sets the opacity of a node (x-browser).

        Parameters
        el: Element
        Elements whose opacity has to be set.
        alpha: (number|string)
        Opacity between 0 and 1 or an empty string + '' to clear the opacity.

        Moves an element to the given coordinates relative to the client viewport.

        Parameters
        el: Element
        Absolutely positioned element to set page offset for. + It must be in the document.
        x: (number|goog.math.Coordinate)
        Left position of the element's margin + box or a coordinate object.
        opt_y: number=
        Top position of the element's margin box.
        code »goog.style.setPosition ( el, arg1, opt_arg2 )

        Sets the top/left values of an element. If no unit is specified in the + argument then it will add px. The second argument is required if the first + argument is a string or number and is ignored if the first argument + is a coordinate.

        Parameters
        el: Element
        Element to move.
        arg1: (string|number|goog.math.Coordinate)
        Left position or coordinate.
        opt_arg2: (string|number)=
        Top position.

        Sets 'white-space: pre-wrap' for a node (x-browser). + + There are as many ways of specifying pre-wrap as there are browsers. + + CSS3/IE8: white-space: pre-wrap; + Mozilla: white-space: -moz-pre-wrap; + Opera: white-space: -o-pre-wrap; + IE6/7: white-space: pre; word-wrap: break-word;

        Parameters
        el: Element
        Element to enable pre-wrap for.
        code »goog.style.setSize ( element, w, opt_h )

        Sets the width/height values of an element. If an argument is numeric, + or a goog.math.Size is passed, it is assumed to be pixels and will add + 'px' after converting it to an integer in string form. (This just sets the + CSS width and height properties so it might set content-box or border-box + size depending on the box model the browser is using.)

        Parameters
        element: Element
        Element to set the size of.
        w: (string|number|goog.math.Size)
        Width of the element, or a + size object.
        opt_h: (string|number)=
        Height of the element. Required if w is not a + size object.
        code »goog.style.setStyle ( element, style, opt_value )

        Sets a style value on an element. + + This function is not indended to patch issues in the browser's style + handling, but to allow easy programmatic access to setting dash-separated + style properties. An example is setting a batch of properties from a data + object without overwriting old styles. When possible, use native APIs: + elem.style.propertyKey = 'value' or (if obliterating old styles is fine) + elem.style.cssText = 'property1: value1; property2: value2'.

        Parameters
        element: Element
        The element to change.
        style: (string|Object)
        If a string, a style name. If an object, a hash + of style names to style values.
        opt_value: (string|number|boolean)=
        If style was a string, then this + should be the value.
        code »goog.style.setStyle_ ( element, value, style )

        Sets a style value on an element, with parameters swapped to work with + goog.object.forEach(). Prepends a vendor-specific prefix when + necessary.

        Parameters
        element: Element
        The element to change.
        value: (string|number|boolean|undefined)
        Style value.
        style: string
        Style name.
        code »goog.style.setStyles ( element, stylesString )

        Sets the content of a style element. The style element can be any valid + style element. This element will have its content completely replaced by + the new stylesString.

        Parameters
        element: (Element|StyleSheet)
        A stylesheet element as returned by + installStyles.
        stylesString: string
        The new content of the stylesheet.

        Sets the background of an element to a transparent image in a browser- + independent manner. + + This function does not support repeating backgrounds or alternate background + positions to match the behavior of Internet Explorer. It also does not + support sizingMethods other than crop since they cannot be replicated in + browsers other than Internet Explorer.

        Parameters
        el: Element
        The element to set background on.
        src: string
        The image source URL.
        code »goog.style.setUnselectable ( el, unselectable, opt_noRecurse )

        Makes the element and its descendants selectable or unselectable. Note + that on some platforms (e.g. Mozilla), even if an element isn't set to + be unselectable, it will behave as such if any of its ancestors is + unselectable.

        Parameters
        el: Element
        The element to alter.
        unselectable: boolean
        Whether the element and its descendants + should be made unselectable.
        opt_noRecurse: boolean=
        Whether to only alter the element's own + selectable state, and leave its descendants alone; defaults to false.
        code »goog.style.setWidth ( element, width )

        Set the width of an element. Sets the element's style property.

        Parameters
        element: Element
        Element to set the width of.
        width: (string|number)
        The width value to set. If a number, 'px' + will be appended, otherwise the value will be applied directly.
        Deprecated: Use goog.style.setElementShown instead.

        Shows or hides an element from the page. Hiding the element is done by + setting the display property to "none", removing the element from the + rendering hierarchy so it takes up no space. To show the element, the default + inherited display property is restored (defined either in stylesheets or by + the browser's default style rules.) + + Caveat 1: if the inherited display property for the element is set to "none" + by the stylesheets, that is the property that will be restored by a call to + showElement(), effectively toggling the display between "none" and "none". + + Caveat 2: if the element display style is set inline (by setting either + element.style.display or a style attribute in the HTML), a call to + showElement will clear that setting and defer to the inherited style in the + stylesheet.

        Parameters
        el: Element
        Element to show or hide.
        display: *
        True to render the element in its default style, + false to disable rendering the element.
        Deprecated: Use goog.string.toCamelCase instead.

        Converts a CSS selector in the form style-property to styleProperty.

        Parameters
        selector: *
        CSS Selector.
        Returns
        Camel case selector.
        Deprecated: Use goog.string.toSelectorCase instead.

        Converts a CSS selector in the form styleProperty to style-property.

        Parameters
        selector: string
        Camel case selector.
        Returns
        Selector cased.

        Reverse of parseStyleAttribute; that is, takes a style object and returns the + corresponding attribute value. Converts camel case property names to proper + CSS selector names.

        Parameters
        obj: Object
        Map of CSS properties to values.
        Returns
        The style attribute value.

        Translates the specified rect relative to origBase page, for newBase page. + If origBase and newBase are the same, this function does nothing.

        Parameters
        rect: goog.math.Rect
        The source rectangle relative to origBase page, + and it will have the translated result.
        origBase: goog.dom.DomHelper
        The DomHelper for the input rectangle.
        newBase: goog.dom.DomHelper
        The DomHelper for the resultant + coordinate. This must be a DOM for an ancestor frame of origBase + or the same as origBase.

        Removes the styles added by #installStyles.

        Parameters
        styleSheet: (Element|StyleSheet)
        The value returned by + #installStyles.

        Global Properties

        Map of absolute CSS length units

        Map of relative CSS length units that can be accurately converted to px + font-size values using getIePixelValue_. Only units that are defined in + relation to a font size are convertible (%, small, etc. are not).

        Regular expression to extract x and y translation components from a CSS + transform Matrix representation.

        A map used to map the border width keywords to a pixel width.

        Regular expression used for getLengthUnits.

        The CSS style property corresponding to an element being + unselectable on the current browser platform (null if none). + Opera and IE instead use a DOM attribute 'unselectable'.

        Compiler Constants

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_testing.html b/docs/api/javascript/namespace_goog_testing.html new file mode 100644 index 0000000000000..f20920e3f0f95 --- /dev/null +++ b/docs/api/javascript/namespace_goog_testing.html @@ -0,0 +1,28 @@ +goog.testing

        Namespace goog.testing

        code »

        Interfaces

        Classes

        goog.testing.AsyncTestCase
        A test case that is capable of running tests the contain asynchronous logic.
        goog.testing.FunctionCall
        Struct for a single function call.
        goog.testing.JsUnitException
        No Description.
        goog.testing.LooseExpectationCollection
        This class is an ordered collection of expectations for one method.
        goog.testing.LooseMock
        This is a mock that does not care about the order of method calls.
        goog.testing.Mock
        The base class for a mock object.
        goog.testing.MockClock
        Class for unit testing code that uses setTimeout and clearTimeout.
        goog.testing.MockControl
        Controls a set of mocks.
        goog.testing.MockExpectation
        This is a class that represents an expectation.
        goog.testing.ObjectPropertyString
        Object to pass a property name as a string literal and its containing object + when the JSCompiler is rewriting these names.
        goog.testing.PropertyReplacer
        Helper class for stubbing out variables and object properties for unit tests.
        goog.testing.StrictMock
        This is a mock that verifies that methods are called in the order that they + are specified during the recording phase.
        goog.testing.TestCase
        A class representing a JsUnit test case.
        goog.testing.TestRunner
        Construct a test runner.
        Show:

        Global Functions

        code »goog.testing.FunctionMock ( opt_functionName, opt_strictness )goog.testing.MockInterface

        Class used to mock a function. Useful for mocking closures and anonymous + callbacks etc. Creates a function object that extends goog.testing.Mock.

        Parameters
        opt_functionName: string=
        The optional name of the function to mock. + Set to '[anonymous mocked function]' if not passed in.
        opt_strictness: number=
        One of goog.testing.Mock.LOOSE or + goog.testing.Mock.STRICT. The default is STRICT.
        Returns
        The mocked function.

        Mocks a global / top-level function. Creates a goog.testing.MethodMock + in the global scope with the name specified by functionName.

        Parameters
        functionName: string
        The name of the function we're going to mock.
        opt_strictness: number=
        One of goog.testing.Mock.LOOSE or + goog.testing.Mock.STRICT. The default is STRICT.
        Returns
        The mocked global function.
        code »goog.testing.MethodMock ( scope, functionName, opt_strictness )!goog.testing.MockInterface

        Mocks an existing function. Creates a goog.testing.FunctionMock + and registers it in the given scope with the name specified by functionName.

        Parameters
        scope: Object
        The scope of the method to be mocked out.
        functionName: string
        The name of the function we're going to mock.
        opt_strictness: number=
        One of goog.testing.Mock.LOOSE or + goog.testing.Mock.STRICT. The default is STRICT.
        Returns
        The mocked method.
        code »goog.testing.createConstructorMock ( scope, constructorName, opt_strictness )!goog.testing.MockInterface

        Convenience method for creating a mock for a constructor. Copies class + members to the mock. + +

        When mocking a constructor to return a mocked instance, remember to create + the instance mock before mocking the constructor. If you mock the constructor + first, then the mock framework will be unable to examine the prototype chain + when creating the mock instance.

        Parameters
        scope: Object
        The scope of the constructor to be mocked out.
        constructorName: string
        The name of the constructor we're going to + mock.
        opt_strictness: number=
        One of goog.testing.Mock.LOOSE or + goog.testing.Mock.STRICT. The default is STRICT.
        Returns
        The mocked constructor.

        Convenience method for creating a mock for a function.

        Parameters
        opt_functionName: string=
        The optional name of the function to mock + set to '[anonymous mocked function]' if not passed in.
        opt_strictness: number=
        One of goog.testing.Mock.LOOSE or + goog.testing.Mock.STRICT. The default is STRICT.
        Returns
        The mocked function.

        Convenience method for creating a mocks for a global / top-level function.

        Parameters
        functionName: string
        The name of the function we're going to mock.
        opt_strictness: number=
        One of goog.testing.Mock.LOOSE or + goog.testing.Mock.STRICT. The default is STRICT.
        Returns
        The mocked global function.
        code »goog.testing.createMethodMock ( scope, functionName, opt_strictness )!goog.testing.MockInterface

        Convenience method for creating a mock for a method.

        Parameters
        scope: Object
        The scope of the method to be mocked out.
        functionName: string
        The name of the function we're going to mock.
        opt_strictness: number=
        One of goog.testing.Mock.LOOSE or + goog.testing.Mock.STRICT. The default is STRICT.
        Returns
        The mocked global function.

        Same as goog.testing.recordFunction but the recorded function will + have the same prototype and static fields as the original one. It can be + used with constructors.

        Parameters
        ctor: !Function
        The function to wrap and record.
        Returns
        The wrapped function.

        Wraps the function into another one which calls the inner function and + records its calls. The recorded function will have 3 static methods: + getCallCount, getCalls and getLastCall but won't + inherit the original function's prototype and static fields.

        Parameters
        opt_f: !Function=
        The function to wrap and record. Defaults to + goog.nullFunction.
        Returns
        The wrapped function.
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_testing_MethodMock.html b/docs/api/javascript/namespace_goog_testing_MethodMock.html new file mode 100644 index 0000000000000..6cc86c6e2be1e --- /dev/null +++ b/docs/api/javascript/namespace_goog_testing_MethodMock.html @@ -0,0 +1,3 @@ +goog.testing.MethodMock

        Namespace goog.testing.MethodMock

        code »

        Mocks an existing function. Creates a goog.testing.FunctionMock + and registers it in the given scope with the name specified by functionName.

        Main

        MethodMock ( scope, functionName, opt_strictness )!goog.testing.MockInterface
        Parameters
        scope: Object
        The scope of the method to be mocked out.
        functionName: string
        The name of the function we're going to mock.
        opt_strictness: number=
        One of goog.testing.Mock.LOOSE or + goog.testing.Mock.STRICT. The default is STRICT.
        Returns
        The mocked method.
        Show:

        Global Functions

        Resets the global function that we mocked back to its original state.

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_testing_asserts.html b/docs/api/javascript/namespace_goog_testing_asserts.html new file mode 100644 index 0000000000000..7eeb88e86e4b8 --- /dev/null +++ b/docs/api/javascript/namespace_goog_testing_asserts.html @@ -0,0 +1,15 @@ +goog.testing.asserts

        Namespace goog.testing.asserts

        code »
        Show:

        Type Definitions

        Global Functions

        Runs a function in an environment where test failures are not logged. This is + useful for testing test code, where failures can be a normal part of a test.

        Parameters
        fn: function(): void
        Function to run without logging failures.
        code »goog.testing.asserts.contains_ ( container, contained )boolean

        Tells whether the array contains the given element.

        Parameters
        container: goog.testing.asserts.ArrayLike
        The array to + find the element in.
        contained: *
        Element to find.
        Returns
        Whether the element is in the array.
        code »goog.testing.asserts.findDifferences ( expected, actual, opt_equalityPredicate )?string

        Determines if two items of any type match, and formulates an error message + if not.

        Parameters
        expected: *
        Expected argument to match.
        actual: *
        Argument as a result of performing the test.
        opt_equalityPredicate: (function(string, *, *): ?string)=
        An optional + function that can be used to check equality of variables. It accepts 3 + arguments: type-of-variables, var1, var2 (in that order) and returns an + error message if the variables are not equal, + goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL if the variables + are equal, or + goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS if the predicate + couldn't check the input variables. The function will be called only if + the types of var1 and var2 are identical.
        Returns
        Null on success, error message on failure.
        Parameters
        expected: *
        The expected value.
        actual: *
        The actual value.
        Returns
        A failure message of the values don't match.
        code »goog.testing.asserts.indexOf_ ( container, contained )number

        Finds the position of the first occurrence of an element in a container.

        Parameters
        container: goog.testing.asserts.ArrayLike
        The array to find the element in.
        contained: *
        Element to find.
        Returns
        Index of the first occurrence or -1 if not found.

        Helper function for assertObjectEquals.

        Parameters
        prop: string
        A property name.
        Returns
        If the property name is an array index.

        Compares equality of two numbers, allowing them to differ up to a given + tolerance.

        Parameters
        var1: number
        A number.
        var2: number
        A number.
        tolerance: number
        the maximum allowed difference.
        Returns
        Whether the two variables are sufficiently close.

        Raises a JsUnit exception with the given comment.

        Parameters
        comment: string
        A summary for the exception.
        opt_message: string=
        A description of the exception.

        Converts an array like object to array or clones it if it's already array.

        Parameters
        arrayLike: goog.testing.asserts.ArrayLike
        The collection.
        Returns
        Copy of the collection as array.

        Global Properties

        The return value of the equality predicate passed to findDifferences below, + in cases where the predicate can't test the input variables for equality.

        The return value of the equality predicate passed to findDifferences below, + in cases where the input vriables are equal.

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_testing_events.html b/docs/api/javascript/namespace_goog_testing_events.html new file mode 100644 index 0000000000000..930c01fdc701a --- /dev/null +++ b/docs/api/javascript/namespace_goog_testing_events.html @@ -0,0 +1,80 @@ +goog.testing.events

        Namespace goog.testing.events

        code »

        Classes

        goog.testing.events.Event
        goog.events.BrowserEvent expects an Event so we provide one for JSCompiler.
        Show:

        Global Functions

        Asserts an event target exists. This will fail if target is not defined. + + TODO(nnaze): Gradually add this to the methods in this file, and eventually + update the method signatures to not take nullables. See http://b/8961907

        Parameters
        target: EventTarget
        A target to assert.
        Returns
        The target, guaranteed to exist.

        Simulate a blur event on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        Returns
        The value returned by firing the blur browser event, + which returns false iff 'preventDefault' was invoked.

        Simulates an event's capturing and bubbling phases.

        Parameters
        event: Event
        A simulated native event. It will be wrapped in a + normalized BrowserEvent and dispatched to Closure listeners on all + ancestors of its target (inclusive).
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.
        code »goog.testing.events.fireClickEvent ( target, opt_button, opt_coords, opt_eventProperties )boolean

        Simulates a click event on the given target. IE only supports click with + the left mouse button.

        Parameters
        target: EventTarget
        The target for the event.
        opt_button: goog.events.BrowserEvent.MouseButton=
        Mouse button; + defaults to goog.events.BrowserEvent.MouseButton.LEFT.
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.
        code »goog.testing.events.fireClickSequence ( target, opt_button, opt_coords, opt_eventProperties )boolean

        Simulates a mousedown, mouseup, and then click on the given event target, + with the left mouse button.

        Parameters
        target: EventTarget
        The target for the event.
        opt_button: goog.events.BrowserEvent.MouseButton=
        Mouse button; + defaults to goog.events.BrowserEvent.MouseButton.LEFT.
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the sequence: false if preventDefault() + was called on any of the events, true otherwise.

        Simulates a contextmenu event on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.

        Simulates a mousedown, contextmenu, and the mouseup on the given event + target, with the right mouse button.

        Parameters
        target: EventTarget
        The target for the event.
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        Returns
        The returnValue of the sequence: false if preventDefault() + was called on any of the events, true otherwise.
        code »goog.testing.events.fireDoubleClickEvent ( target, opt_coords, opt_eventProperties )boolean

        Simulates a double-click event on the given target. Always double-clicks + with the left mouse button since no browser supports double-clicking with + any other buttons.

        Parameters
        target: EventTarget
        The target for the event.
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.
        code »goog.testing.events.fireDoubleClickSequence ( target, opt_coords, opt_eventProperties )boolean

        Simulates the sequence of events fired by the browser when the user double- + clicks the given target.

        Parameters
        target: EventTarget
        The target for the event.
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the sequence: false if preventDefault() + was called on any of the events, true otherwise.

        Simulate a focus event on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        Returns
        The value returned by firing the focus browser event, + which returns false iff 'preventDefault' was invoked.
        code »goog.testing.events.fireKeySequence ( target, keyCode, opt_eventProperties )boolean

        Simulates a complete keystroke (keydown, keypress, and keyup). Note that + if preventDefault is called on the keydown, the keypress will not fire.

        Parameters
        target: EventTarget
        The target for the event.
        keyCode: number
        The keycode of the key pressed.
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the sequence: false if preventDefault() + was called on any of the events, true otherwise.
        code »goog.testing.events.fireMouseButtonEvent_ ( type, target, opt_button, opt_coords, opt_eventProperties )boolean

        Helper function to fire a mouse event. + with the left mouse button since no browser supports double-clicking with + any other buttons.

        Parameters
        type: string
        The event type.
        target: EventTarget
        The target for the event.
        opt_button: number=
        Mouse button; defaults to + goog.events.BrowserEvent.MouseButton.LEFT.
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.
        code »goog.testing.events.fireMouseDownEvent ( target, opt_button, opt_coords, opt_eventProperties )boolean

        Simulates a mousedown event on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        opt_button: goog.events.BrowserEvent.MouseButton=
        Mouse button; + defaults to goog.events.BrowserEvent.MouseButton.LEFT.
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.

        Simulates a mousemove event on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.
        code »goog.testing.events.fireMouseOutEvent ( target, relatedTarget, opt_coords )boolean

        Simulates a mouseout event on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        relatedTarget: EventTarget
        The related target for the event (e.g., + the node that the mouse is being moved into).
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.
        code »goog.testing.events.fireMouseOverEvent ( target, relatedTarget, opt_coords )boolean

        Simulates a mouseover event on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        relatedTarget: EventTarget
        The related target for the event (e.g., + the node that the mouse is being moved out of).
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.
        code »goog.testing.events.fireMouseUpEvent ( target, opt_button, opt_coords, opt_eventProperties )boolean

        Simulates a mouseup event on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        opt_button: goog.events.BrowserEvent.MouseButton=
        Mouse button; + defaults to goog.events.BrowserEvent.MouseButton.LEFT.
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.
        code »goog.testing.events.fireNonAsciiKeySequence ( target, keyCode, keyPressKeyCode, opt_eventProperties )boolean

        Simulates a complete keystroke (keydown, keypress, and keyup) when typing + a non-ASCII character. Same as fireKeySequence, the keypress will not fire + if preventDefault is called on the keydown.

        Parameters
        target: EventTarget
        The target for the event.
        keyCode: number
        The keycode of the keydown and keyup events.
        keyPressKeyCode: number
        The keycode of the keypress event.
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the sequence: false if preventDefault() + was called on any of the events, true otherwise.

        Simulates a popstate event on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        state: Object
        History state object.
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.
        code »goog.testing.events.fireTouchEndEvent ( target, opt_coords, opt_eventProperties )boolean

        Simulates a touchend event on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        opt_coords: goog.math.Coordinate=
        Touch position. Defaults to event's + target's position (if available), otherwise (0, 0).
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.
        code »goog.testing.events.fireTouchMoveEvent ( target, opt_coords, opt_eventProperties )boolean

        Simulates a touchmove event on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        opt_coords: goog.math.Coordinate=
        Touch position. Defaults to event's + target's position (if available), otherwise (0, 0).
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.
        code »goog.testing.events.fireTouchSequence ( target, opt_coords, opt_eventProperties )boolean

        Simulates a simple touch sequence on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        opt_coords: goog.math.Coordinate=
        Touch position. Defaults to event + target's position (if available), otherwise (0, 0).
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the sequence: false if preventDefault() + was called on any of the events, true otherwise.
        code »goog.testing.events.fireTouchStartEvent ( target, opt_coords, opt_eventProperties )boolean

        Simulates a touchstart event on the given target.

        Parameters
        target: EventTarget
        The target for the event.
        opt_coords: goog.math.Coordinate=
        Touch position. Defaults to event's + target's position (if available), otherwise (0, 0).
        opt_eventProperties: Object=
        Event properties to be mixed into the + BrowserEvent.
        Returns
        The returnValue of the event: false if preventDefault() was + called on it, true otherwise.
        Parameters
        e: goog.testing.events.Event
        The event.
        Returns
        Whether this is the Gecko/Mac's Meta-C/V/X, which + is broken and requires special handling.

        Mixins a listenable into the given object. This turns the object + into a goog.events.Listenable. This is useful, for example, when + you need to mock a implementation of listenable and still want it + to work with goog.events.

        Parameters
        obj: !Object
        The object to mixin into.

        A static helper function that sets the mouse position to the event.

        Parameters
        event: Event
        A simulated native event.
        opt_coords: goog.math.Coordinate=
        Mouse position. Defaults to event's + target's position (if available), otherwise (0, 0).
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_testing_jsunit.html b/docs/api/javascript/namespace_goog_testing_jsunit.html new file mode 100644 index 0000000000000..df7f96322e92a --- /dev/null +++ b/docs/api/javascript/namespace_goog_testing_jsunit.html @@ -0,0 +1 @@ +goog.testing.jsunit

        Namespace goog.testing.jsunit

        code »
        Show:

        Global Properties

        Base path for JsUnit app files, relative to Closure's base path.

        Filename for the core JS Unit script.

        Compiler Constants

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_testing_mockmatchers.html b/docs/api/javascript/namespace_goog_testing_mockmatchers.html new file mode 100644 index 0000000000000..a44ee244d95f3 --- /dev/null +++ b/docs/api/javascript/namespace_goog_testing_mockmatchers.html @@ -0,0 +1,9 @@ +goog.testing.mockmatchers

        Namespace goog.testing.mockmatchers

        code »

        Classes

        goog.testing.mockmatchers.ArgumentMatcher
        A simple interface for executing argument matching.
        goog.testing.mockmatchers.IgnoreArgument
        A matcher that always returns true.
        goog.testing.mockmatchers.InstanceOf
        A matcher that verifies that an argument is an instance of a given class.
        goog.testing.mockmatchers.ObjectEquals
        A matcher that verifies that the argument is an object that equals the given + expected object, using a deep comparison.
        goog.testing.mockmatchers.RegexpMatch
        A matcher that verifies that an argument matches a given RegExp.
        goog.testing.mockmatchers.SaveArgument
        A matcher that saves the argument that it is verifying so that your unit test + can perform extra tests with this argument later.
        goog.testing.mockmatchers.TypeOf
        A matcher that verifies that an argument is of a given type (e.g.
        Show:

        Global Functions

        code »goog.testing.mockmatchers.flexibleArrayMatcher ( expectedArr, arr, opt_expectation )boolean

        A function that checks to see if an array matches a given set of + expectations. The expectations array can be a mix of ArgumentMatcher + implementations and values. True will be returned if values are identical or + if a matcher returns a positive result.

        Parameters
        expectedArr: Array
        An array of expectations which can be either + values to check for equality or ArgumentMatchers.
        arr: Array
        The array to match.
        opt_expectation: ?goog.testing.MockExpectation=
        The expectation + for this match.
        Returns
        Whether or not the given array matches the expectations.

        Global Properties

        An instance of the IgnoreArgument matcher. Returns true for all matches.

        A matcher that verifies that an argument is an array.

        A matcher that verifies that an argument is a array-like. A NodeList is an + example of a collection that is very close to an array.

        A matcher that verifies that an argument is a boolean.

        A matcher that verifies that an argument is a date-like.

        A matcher that verifies that an argument is a function.

        A matcher that verifies that an argument is like a DOM node.

        A matcher that verifies that an argument is a number.

        A matcher that verifies that an argument is an object.

        A matcher that verifies that an argument is a string.

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_testing_stacktrace.html b/docs/api/javascript/namespace_goog_testing_stacktrace.html new file mode 100644 index 0000000000000..642554004fa06 --- /dev/null +++ b/docs/api/javascript/namespace_goog_testing_stacktrace.html @@ -0,0 +1,29 @@ +goog.testing.stacktrace

        Namespace goog.testing.stacktrace

        code »

        Classes

        goog.testing.stacktrace.Frame
        Class representing one stack frame.
        Show:

        Global Functions

        Converts an array of CallSite (elements of a stack trace in V8) to an array + of Frames.

        Parameters
        stack: !Array
        The stack as an array of CallSites.
        Returns
        The stack as an array of + Frames.

        Brings the stack trace into a common format across browsers.

        Parameters
        stack: string
        Browser-specific stack trace.
        Returns
        Same stack trace in common format.

        Function to deobfuscate function names.

        Creates a stack trace by following the call chain. Based on + goog.debug.getStacktrace.

        Returns
        Stack frames.

        Converts the stack frames into canonical format. Chops the beginning and the + end of it which come from the testing environment, not from the test itself.

        Parameters
        frames: !Array.<goog.testing.stacktrace.Frame>
        The frames.
        Returns
        Canonical, pretty printed stack trace.

        Gets the native stack trace if available otherwise follows the call chain.

        Returns
        The stack trace in canonical format.

        Returns the native stack trace.

        Escapes the special character in HTML.

        Parameters
        text: string
        Plain text.
        Returns
        Escaped text.

        Deobfuscates a compiled function name with the function passed to + #setDeobfuscateFunctionName. Returns the original function name if + the deobfuscator hasn't been set.

        Parameters
        name: string
        The function name to deobfuscate.
        Returns
        The deobfuscated function name.

        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 the browser's native stack trace.

        Parameters
        stack: string
        Stack trace.
        Returns
        Stack frames. The + unrecognized frames will be nulled out.

        Sets function to deobfuscate function names.

        Parameters
        fn: function(string): string
        function to deobfuscate function names.

        Global Properties

        RegExp pattern for an URL + line number + column number in V8. + The URL is either in submatch 1 or submatch 2.

        RegExp pattern for function call in the Firefox stack trace. + Creates 2 submatches with function name (optional) and arguments.

        Regular expression for parsing one stack frame in Firefox.

        Regular expression for finding the function name in its source.

        RegExp pattern for JavaScript identifiers. We don't support Unicode + identifiers defined in ECMAScript v3.

        RegExp pattern for function call in a IE stack trace. This expression allows + for identifiers like 'Anonymous function', 'eval code', and 'Global code'.

        Regular expression for parsing a stack frame in IE.

        Maximum number of steps while the call chain is followed.

        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 4 (optional) submatches: the function name (if not anonymous), + the aliased context object and function name (if anonymous), and the + function call arguments.

        Regular expression for parsing on stack frame in Opera 11.68 - 12.17. + Newer versions of Opera use V8 and stack frames should match against + goog.testing.stacktrace.V8_STACK_FRAME_REGEXP_.

        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 a V8 stack trace. + Creates an optional submatch for the namespace identifier including the + "new" keyword for constructor calls (e.g. "new foo.Bar").

        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.

        Regular expression for parsing one stack frame in V8. For more information + on V8 stack frame formats, see + https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi.

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_testing_watchers.html b/docs/api/javascript/namespace_goog_testing_watchers.html new file mode 100644 index 0000000000000..de314395f8305 --- /dev/null +++ b/docs/api/javascript/namespace_goog_testing_watchers.html @@ -0,0 +1 @@ +goog.testing.watchers

        Namespace goog.testing.watchers

        code »
        Show:

        Global Functions

        Fires clock reset watching functions.

        Enqueues a function to be called when the clock used for setTimeout is reset.

        Parameters
        fn

        Global Properties

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_uri.html b/docs/api/javascript/namespace_goog_uri.html index 2bf8bb8ce3877..45706589dd28d 100644 --- a/docs/api/javascript/namespace_goog_uri.html +++ b/docs/api/javascript/namespace_goog_uri.html @@ -1 +1 @@ -goog.uri

        Namespace goog.uri

        code »
        Show:
        \ No newline at end of file +goog.uri

        Namespace goog.uri

        code »
        Show:
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_uri_utils.html b/docs/api/javascript/namespace_goog_uri_utils.html index be49e7b375dcd..b41e0cb0a6dcb 100644 --- a/docs/api/javascript/namespace_goog_uri_utils.html +++ b/docs/api/javascript/namespace_goog_uri_utils.html @@ -1,4 +1,4 @@ -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 +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 @@ -14,18 +14,18 @@ // Multi-valued param: &house=LosAngeles&house=NewYork&house=null 'house', ['LosAngeles', 'NewYork', null] ]; -
        Supported query parameter values by the parameter serializing utilities. +
        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. + &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. + 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, @@ -44,69 +44,70 @@ 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, + 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 + 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. + 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 + 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. + 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 + 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 + 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. + 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. + are dropped.Returns

        The encoded query string, in the form 'a=1&b=2'.
        code »goog.uri.utils.decodeIfPossible_ ( uri, opt_preserveReserved )?string
        Parameters
        uri: ?string
        A possibly null string.
        opt_preserveReserved: boolean=
        If true, percent-encoding of RFC-3986 + reserved characters will not be removed.
        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. + 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. + 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. + 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. + 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 scheme, 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. + 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:

        @@ -115,7 +116,7 @@
              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., + 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/ @@ -189,4 +190,4 @@ $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 +

        Regexp to find trailing question marks and ampersands.

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_userAgent.html b/docs/api/javascript/namespace_goog_userAgent.html index 5b2e3a40719a5..f36462f13ed97 100644 --- a/docs/api/javascript/namespace_goog_userAgent.html +++ b/docs/api/javascript/namespace_goog_userAgent.html @@ -32,4 +32,4 @@ '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 + version number is unlikely to change during a session, we cache the results.

        Compiler Constants

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_goog_userAgent_product.html b/docs/api/javascript/namespace_goog_userAgent_product.html index f06d1546d2489..4ad8688227119 100644 --- a/docs/api/javascript/namespace_goog_userAgent_product.html +++ b/docs/api/javascript/namespace_goog_userAgent_product.html @@ -6,4 +6,4 @@ 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 + '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/docs/api/javascript/namespace_webdriver.html b/docs/api/javascript/namespace_webdriver.html index dc25a7d7c5231..6c6332fe791ce 100644 --- a/docs/api/javascript/namespace_webdriver.html +++ b/docs/api/javascript/namespace_webdriver.html @@ -1,4 +1,5 @@ -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 +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.AlertPromise
        AlertPromise is a promise that will be fulfilled with an Alert.
        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.
        webdriver.WebElementPromise
        WebElementPromise is a promise that will be fulfilled with a WebElement.

        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:

        Type Definitions

        code »webdriver.ProxyConfig : ({proxyType: string}|{proxyType: string, proxyAutoconfigUrl: string}|{proxyType: string, ftpProxy: string, httpProxy: string, sslProxy: string, noProxy: string})
        Describes how a proxy should be configured for a WebDriver session. + Proxy configuration object, as defined by the WebDriver wire protocol.
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_webdriver_By.html b/docs/api/javascript/namespace_webdriver_By.html index 342af00c61eda..297c445689973 100644 --- a/docs/api/javascript/namespace_webdriver_By.html +++ b/docs/api/javascript/namespace_webdriver_By.html @@ -23,4 +23,4 @@ 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 + WebElement.
        Parameters
        xpath: string
        The XPath selector to use.
        Returns
        The new locator.
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_webdriver_http.html b/docs/api/javascript/namespace_webdriver_http.html index 19bb8c3f52b33..20a60aa3ed575 100644 --- a/docs/api/javascript/namespace_webdriver_http.html +++ b/docs/api/javascript/namespace_webdriver_http.html @@ -1,4 +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 + 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/docs/api/javascript/namespace_webdriver_logging.html b/docs/api/javascript/namespace_webdriver_logging.html index 2cd469f9bf292..2fec2076b3f2f 100644 --- a/docs/api/javascript/namespace_webdriver_logging.html +++ b/docs/api/javascript/namespace_webdriver_logging.html @@ -1,4 +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. +webdriver.logging

        Namespace webdriver.logging

        code »

        Classes

        webdriver.logging.Entry
        A single log entry.
        webdriver.logging.Preferences
        Describes the log preferences for a WebDriver session.

        Enumerations

        webdriver.logging.Level
        Logging levels.
        webdriver.logging.Type
        Common log types.
        Show:

        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 + convert .Returns
        The converted level.
        \ No newline at end of file diff --git a/docs/api/javascript/namespace_webdriver_process.html b/docs/api/javascript/namespace_webdriver_process.html index eafcd04a6f426..b8d1b2e50bfca 100644 --- a/docs/api/javascript/namespace_webdriver_process.html +++ b/docs/api/javascript/namespace_webdriver_process.html @@ -5,4 +5,4 @@ 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 + environment. \ No newline at end of file diff --git a/docs/api/javascript/namespace_webdriver_promise.html b/docs/api/javascript/namespace_webdriver_promise.html index c6239470824ec..3533da875be6c 100644 --- a/docs/api/javascript/namespace_webdriver_promise.html +++ b/docs/api/javascript/namespace_webdriver_promise.html @@ -1,28 +1,61 @@ -webdriver.promise

        Namespace webdriver.promise

        code »

        Classes

        webdriver.promise.CanceledTaskError_
        Special error used to signal when a task is canceled because a previous +webdriver.promise

        Namespace webdriver.promise

        code »

        Interfaces

        webdriver.promise.Thenable
        Thenable is a promise-like object with a then method which may be + used to schedule callbacks on a promised value.

        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 + 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 + 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 + 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 + be resolved with the result.

        Parameters
        fn: !Function
        The function to wrap.
        var_args: ...?
        The arguments to apply to the function, excluding the + final callback.
        Returns
        A promise that will be resolved with the + result of the provided function's callback.
        code »webdriver.promise.consume ( generatorFn, opt_self, var_args )!webdriver.promise.Promise

        Consumes a GeneratorFunction. Each time the generator yields a + promise, this function will wait for it to be fulfilled before feeding the + fulfilled value back into next. Likewise, if a yielded promise is + rejected, the rejection error will be passed to throw. + +

        Example 1: the Fibonacci Sequence. +

        
        + webdriver.promise.consume(function* fibonacci() {
        +   var n1 = 1, n2 = 1;
        +   for (var i = 0; i < 4; ++i) {
        +     var tmp = yield n1 + n2;
        +     n1 = n2;
        +     n2 = tmp;
        +   }
        +   return n1 + n2;
        + }).then(function(result) {
        +   console.log(result);  // 13
        + });
        + 
        + +

        Example 2: a generator that throws. +

        
        + webdriver.promise.consume(function* () {
        +   yield webdriver.promise.delayed(250).then(function() {
        +     throw Error('boom');
        +   });
        + }).thenCatch(function(e) {
        +   console.log(e.toString());  // Error: boom
        + });
        + 
        Parameters
        generatorFn: !Function
        The generator function to execute.
        opt_self: Object=
        The object to use as "this" when invoking the + initial generator.
        var_args: ...*
        Any arguments to pass to the initial generator.
        Returns
        A promise that will resolve to the + generator's final result.
        Throws
        TypeError
        If the given function is not a generator.
        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 + 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 @@ -35,10 +68,10 @@ 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 + 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 + 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 @@ -52,9 +85,9 @@ 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 + 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.

        Tests is a function is a generator.

        Parameters
        fn: !Function
        The function to test.
        Returns
        Whether the function is a generator.

        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. @@ -68,12 +101,12 @@ 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 + 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 + 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 + N-1.

        The default flow to use if no others are active.

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_webdriver_stacktrace.html b/docs/api/javascript/namespace_webdriver_stacktrace.html index f94d7b7f95b9b..53b773363346e 100644 --- a/docs/api/javascript/namespace_webdriver_stacktrace.html +++ b/docs/api/javascript/namespace_webdriver_stacktrace.html @@ -1,17 +1,18 @@ -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. +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

        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. + 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 + 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 creates 2 submatches on the (optional) context and function name, + matching identifiers like 'foo.Bar.prototype.baz', '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. @@ -26,8 +27,8 @@ 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 + 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. @@ -36,4 +37,4 @@ 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 + the only information in the frame).

        Regular expression for parsing one stack frame in V8.

        \ No newline at end of file diff --git a/docs/api/javascript/namespace_webdriver_testing.html b/docs/api/javascript/namespace_webdriver_testing.html index e077f7bedffd8..3615aa02db698 100644 --- a/docs/api/javascript/namespace_webdriver_testing.html +++ b/docs/api/javascript/namespace_webdriver_testing.html @@ -1 +1,2 @@ -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 +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.
        webdriver.testing.TestCase
        Constructs a test case that synchronizes each test case with the singleton + webdriver.promise.ControlFlow.
        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/docs/api/javascript/namespace_webdriver_testing_assert.html b/docs/api/javascript/namespace_webdriver_testing_assert.html index 91e04b6818ade..d33cd720b2d68 100644 --- a/docs/api/javascript/namespace_webdriver_testing_assert.html +++ b/docs/api/javascript/namespace_webdriver_testing_assert.html @@ -1,3 +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 + matcher constructor to use, or an object literal defining a matcher. \ No newline at end of file diff --git a/docs/api/javascript/namespace_webdriver_testing_asserts.html b/docs/api/javascript/namespace_webdriver_testing_asserts.html index 10501734f48c8..2c72ff85a959c 100644 --- a/docs/api/javascript/namespace_webdriver_testing_asserts.html +++ b/docs/api/javascript/namespace_webdriver_testing_asserts.html @@ -7,4 +7,4 @@ 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 + 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/docs/api/javascript/source/_base.js.src.html b/docs/api/javascript/source/_base.js.src.html index a8ca370d0e346..e344d7dd34a05 100644 --- a/docs/api/javascript/source/_base.js.src.html +++ b/docs/api/javascript/source/_base.js.src.html @@ -1 +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 +_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 * Maintains a unique context for Closure library-based code.
        79 * @param {boolean=} opt_configureForTesting Whether to configure a fake DOM
        80 * for Closure-testing code that (incorrectly) assumes a DOM is always
        81 * present.
        82 * @constructor
        83 */
        84function Context(opt_configureForTesting) {
        85 var closure = this.closure = vm.createContext({
        86 console: console,
        87 setTimeout: setTimeout,
        88 setInterval: setInterval,
        89 clearTimeout: clearTimeout,
        90 clearInterval: clearInterval,
        91 process: process,
        92 require: require,
        93 Buffer: Buffer,
        94 Error: Error,
        95 CLOSURE_BASE_PATH: path.dirname(CLOSURE_BASE_FILE_PATH) + '/',
        96 CLOSURE_IMPORT_SCRIPT: function(src) {
        97 loadScript(src);
        98 return true;
        99 },
        100 CLOSURE_NO_DEPS: !isDevMode(),
        101 goog: {}
        102 });
        103 closure.window = closure.top = closure;
        104
        105 if (opt_configureForTesting) {
        106 closure.document = {
        107 body: {},
        108 createElement: function() { return {}; },
        109 getElementsByTagName: function() { return []; }
        110 };
        111 closure.document.body.ownerDocument = closure.document;
        112 }
        113
        114 loadScript(CLOSURE_BASE_FILE_PATH);
        115 loadScript(DEPS_FILE_PATH);
        116
        117 /**
        118 * Synchronously loads a script into the protected Closure context.
        119 * @param {string} src Path to the file to load.
        120 */
        121 function loadScript(src) {
        122 src = path.normalize(src);
        123 var contents = fs.readFileSync(src, 'utf8');
        124 vm.runInContext(contents, closure, src);
        125 }
        126}
        127
        128
        129var context = new Context();
        130
        131
        132/**
        133 * Loads a symbol by name from the protected Closure context.
        134 * @param {string} symbol The symbol to load.
        135 * @return {?} The loaded symbol, or {@code null} if not found.
        136 * @throws {Error} If the symbol has not been defined.
        137 */
        138function closureRequire(symbol) {
        139 context.closure.goog.require(symbol);
        140 return context.closure.goog.getObjectByName(symbol);
        141}
        142
        143
        144// PUBLIC API
        145
        146
        147/**
        148 * Loads a symbol by name from the protected Closure context and exports its
        149 * public API to the provided object. This function relies on Closure code
        150 * conventions to define the public API of an object as those properties whose
        151 * name does not end with "_".
        152 * @param {string} symbol The symbol to load. This must resolve to an object.
        153 * @return {!Object} An object with the exported API.
        154 * @throws {Error} If the symbol has not been defined or does not resolve to
        155 * an object.
        156 */
        157exports.exportPublicApi = function(symbol) {
        158 var src = closureRequire(symbol);
        159 if (typeof src != 'object' || src === null) {
        160 throw Error('"' + symbol + '" must resolve to an object');
        161 }
        162
        163 var dest = {};
        164 Object.keys(src).forEach(function(key) {
        165 if (key[key.length - 1] != '_') {
        166 dest[key] = src[key];
        167 }
        168 });
        169
        170 return dest;
        171};
        172
        173
        174if (isDevMode()) {
        175 exports.closure = context.closure;
        176}
        177exports.Context = Context;
        178exports.isDevMode = isDevMode;
        179exports.require = closureRequire;
        \ No newline at end of file diff --git a/docs/api/javascript/source/builder.js.src.html b/docs/api/javascript/source/builder.js.src.html index 4ab27720b782e..744625588ae9b 100644 --- a/docs/api/javascript/source/builder.js.src.html +++ b/docs/api/javascript/source/builder.js.src.html @@ -1 +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 +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
        18// Use base.require to avoid circular references between index and this module.
        19var Browser = base.require('webdriver.Browser'),
        20 Capabilities = base.require('webdriver.Capabilities'),
        21 Capability = base.require('webdriver.Capability'),
        22 WebDriver = base.require('webdriver.WebDriver'),
        23 promise = base.require('webdriver.promise');
        24
        25
        26
        27/**
        28 * Creates new {@link webdriver.WebDriver WebDriver} instances. The environment
        29 * variables listed below may be used to override a builder's configuration,
        30 * allowing quick runtime changes.
        31 * <ul>
        32 * <li>{@code SELENIUM_REMOTE_URL}: defines the remote URL for all builder
        33 * instances. This environment variable should be set to a fully qualified
        34 * URL for a WebDriver server (e.g. http://localhost:4444/wd/hub).
        35 *
        36 * <li>{@code SELENIUM_BROWSER}: defines the target browser in the form
        37 * {@code browser[:version][:platform]}.
        38 * </ul>
        39 *
        40 * <p>Suppose you had mytest.js that created WebDriver with
        41 * {@code var driver = new webdriver.Builder().build();}.
        42 *
        43 * This test could be made to use Firefox on the local machine by running with
        44 * {@code SELENIUM_BROWSER=firefox node mytest.js}.
        45 *
        46 * <p>Alternatively, you could request Chrome 36 on Linux from a remote
        47 * server with {@code
        48 * SELENIUM_BROWSER=chrome:36:LINUX
        49 * SELENIUM_REMOTE_URL=http://www.example.com:4444/wd/hub
        50 * node mytest.js}.
        51 *
        52 * @constructor
        53 */
        54var Builder = function() {
        55
        56 /** @private {webdriver.promise.ControlFlow} */
        57 this.flow_ = null;
        58
        59 /** @private {string} */
        60 this.url_ = '';
        61
        62 /** @private {!webdriver.Capabilities} */
        63 this.capabilities_ = new Capabilities();
        64
        65 /** @private {chrome.Options} */
        66 this.chromeOptions_ = null;
        67
        68 /** @private {firefox.Options} */
        69 this.firefoxOptions_ = null;
        70};
        71
        72
        73/**
        74 * Sets the URL of a remote WebDriver server to use. Once a remote URL has been
        75 * specified, the builder direct all new clients to that server. If this method
        76 * is never called, the Builder will attempt to create all clients locally.
        77 *
        78 * <p>As an alternative to this method, you may also set the
        79 * {@code SELENIUM_REMOTE_URL} environment variable.
        80 *
        81 * @param {string} url The URL of a remote server to use.
        82 * @return {!Builder} A self reference.
        83 */
        84Builder.prototype.usingServer = function(url) {
        85 this.url_ = url;
        86 return url;
        87};
        88
        89
        90/**
        91 * @return {string} The URL of the WebDriver server this instance is configured
        92 * to use.
        93 */
        94Builder.prototype.getServerUrl = function() {
        95 return this.url_;
        96};
        97
        98
        99/**
        100 * Sets the desired capabilities when requesting a new session. This will
        101 * overwrite any previously set capabilities.
        102 * @param {!(Object|webdriver.Capabilities)} capabilities The desired
        103 * capabilities for a new session.
        104 * @return {!Builder} A self reference.
        105 */
        106Builder.prototype.withCapabilities = function(capabilities) {
        107 this.capabilities_ = new Capabilities(capabilities);
        108 return this;
        109};
        110
        111
        112/**
        113 * Returns the base set of capabilities this instance is currently configured
        114 * to use.
        115 * @return {!webdriver.Capabilities} The current capabilities for this builder.
        116 */
        117Builder.prototype.getCapabilities = function() {
        118 return this.capabilities_;
        119};
        120
        121
        122/**
        123 * Configures the target browser for clients created by this instance.
        124 * Any calls to {@link #withCapabilities} after this function will
        125 * overwrite these settings.
        126 *
        127 * <p>You may also define the target browser using the {@code SELENIUM_BROWSER}
        128 * environment variable. If set, this environment variable should be of the
        129 * form {@code browser[:[version][:platform]]}.
        130 *
        131 * @param {(string|webdriver.Browser)} name The name of the target browser;
        132 * common defaults are available on the {@link webdriver.Browser} enum.
        133 * @param {string=} opt_version A desired version; may be omitted if any
        134 * version should be used.
        135 * @param {string=} opt_platform The desired platform; may be omitted if any
        136 * version may be used.
        137 * @return {!Builder} A self reference.
        138 */
        139Builder.prototype.forBrowser = function(name, opt_version, opt_platform) {
        140 this.capabilities_.set(Capability.BROWSER_NAME, name);
        141 this.capabilities_.set(Capability.VERSION, opt_version || null);
        142 this.capabilities_.set(Capability.PLATFORM, opt_platform || null);
        143 return this;
        144};
        145
        146
        147/**
        148 * Sets the proxy configuration to use for WebDriver clients created by this
        149 * builder. Any calls to {@link #withCapabilities} after this function will
        150 * overwrite these settings.
        151 * @param {!webdriver.ProxyConfig} config The configuration to use.
        152 * @return {!Builder} A self reference.
        153 */
        154Builder.prototype.setProxy = function(config) {
        155 this.capabilities_.setProxy(config);
        156 return this;
        157};
        158
        159
        160/**
        161 * Sets the logging preferences for the created session. Preferences may be
        162 * changed by repeated calls, or by calling {@link #withCapabilities}.
        163 * @param {!(webdriver.logging.Preferences|Object.<string, string>)} prefs The
        164 * desired logging preferences.
        165 * @return {!Builder} A self reference.
        166 */
        167Builder.prototype.setLoggingPrefs = function(prefs) {
        168 this.capabilities_.setLoggingPrefs(prefs);
        169 return this;
        170};
        171
        172
        173/**
        174 * Sets whether native events should be used.
        175 * @param {boolean} enabled Whether to enable native events.
        176 * @return {!Builder} A self reference.
        177 */
        178Builder.prototype.setEnableNativeEvents = function(enabled) {
        179 this.capabilities_.setEnableNativeEvents(enabled);
        180 return this;
        181};
        182
        183
        184/**
        185 * Sets how elements should be scrolled into view for interaction.
        186 * @param {number} behavior The desired scroll behavior: either 0 to align with
        187 * the top of the viewport or 1 to align with the bottom.
        188 * @return {!Builder} A self reference.
        189 */
        190Builder.prototype.setScrollBehavior = function(behavior) {
        191 this.capabilities_.setScrollBehavior(behavior);
        192 return this;
        193};
        194
        195
        196/**
        197 * Sets the default action to take with an unexpected alert before returning
        198 * an error.
        199 * @param {string} beahvior The desired behavior; should be "accept", "dismiss",
        200 * or "ignore". Defaults to "dismiss".
        201 * @return {!Builder} A self reference.
        202 */
        203Builder.prototype.setAlertBehavior = function(behavior) {
        204 this.capabilities_.setAlertBehavior(behavior);
        205 return this;
        206};
        207
        208
        209/**
        210 * Sets Chrome-specific options for drivers created by this builder. Any
        211 * logging or proxy settings defined on the given options will take precedence
        212 * over those set through {@link #setLoggingPrefs} and {@link #setProxy},
        213 * respectively.
        214 *
        215 * @param {!chrome.Options} options The ChromeDriver options to use.
        216 * @return {!Builder} A self reference.
        217 */
        218Builder.prototype.setChromeOptions = function(options) {
        219 this.chromeOptions_ = options;
        220 return this;
        221};
        222
        223
        224/**
        225 * Sets Firefox-specific options for drivers created by this builder. Any
        226 * logging or proxy settings defined on the given options will take precedence
        227 * over those set through {@link #setLoggingPrefs} and {@link #setProxy},
        228 * respectively.
        229 *
        230 * @param {!firefox.Options} options The FirefoxDriver options to use.
        231 * @return {!Builder} A self reference.
        232 */
        233Builder.prototype.setFirefoxOptions = function(options) {
        234 this.firefoxOptions_ = options;
        235 return this;
        236};
        237
        238
        239/**
        240 * Sets the control flow that created drivers should execute actions in. If
        241 * the flow is never set, or is set to {@code null}, it will use the active
        242 * flow at the time {@link #build()} is called.
        243 * @param {webdriver.promise.ControlFlow} flow The control flow to use, or
        244 * {@code null} to
        245 * @return {!Builder} A self reference.
        246 */
        247Builder.prototype.setControlFlow = function(flow) {
        248 this.flow_ = flow;
        249 return this;
        250};
        251
        252
        253/**
        254 * Creates a new WebDriver client based on this builder's current
        255 * configuration.
        256 *
        257 * @return {!webdriver.WebDriver} A new WebDriver instance.
        258 * @throws {Error} If the current configuration is invalid.
        259 */
        260Builder.prototype.build = function() {
        261 // Create a copy for any changes we may need to make based on the current
        262 // environment.
        263 var capabilities = new Capabilities(this.capabilities_);
        264
        265 var browser = process.env.SELENIUM_BROWSER;
        266 if (browser) {
        267 browser = browser.split(/:/, 3);
        268 capabilities.set(Capability.BROWSER_NAME, browser[0]);
        269 capabilities.set(Capability.VERSION, browser[1] || null);
        270 capabilities.set(Capability.PLATFORM, browser[2] || null);
        271 }
        272
        273 browser = capabilities.get(Capability.BROWSER_NAME);
        274
        275 if (!browser) {
        276 throw Error(
        277 'Target browser not defined; did you forget to call forBrowser()?');
        278 }
        279
        280 // Apply browser specific overrides.
        281 if (browser === Browser.CHROME && this.chromeOptions_) {
        282 capabilities.merge(this.chromeOptions_.toCapabilities());
        283 }
        284
        285 if (browser === Browser.FIREFOX && this.firefoxOptions_) {
        286 capabilities.merge(this.firefoxOptions_.toCapabilities());
        287 }
        288
        289 // Check for a remote browser.
        290 var url = process.env.SELENIUM_REMOTE_URL || this.url_;
        291 if (url) {
        292 var executor = executors.createExecutor(url);
        293 return WebDriver.createSession(executor, capabilities, this.flow_);
        294 }
        295
        296 // Check for a native browser.
        297 switch (browser) {
        298 case Browser.CHROME:
        299 // Requiring 'chrome' above would create a cycle:
        300 // index -> builder -> chrome -> index
        301 var chrome = require('./chrome');
        302 return new chrome.Driver(capabilities, null, this.flow_);
        303
        304 case Browser.FIREFOX:
        305 // Requiring 'firefox' above would create a cycle:
        306 // index -> builder -> firefox -> index
        307 var firefox = require('./firefox');
        308 return new firefox.Driver(capabilities, this.flow_);
        309
        310 case Browser.PHANTOM_JS:
        311 // Requiring 'phantomjs' would create a cycle:
        312 // index -> builder -> phantomjs -> index
        313 var phantomjs = require('./phantomjs');
        314 return new phantomjs.Driver(capabilities, this.flow_);
        315
        316 default:
        317 throw new Error('Do not know how to build driver: ' + browser
        318 + '; did you forget to call usingServer(url)?');
        319 }
        320};
        321
        322
        323// PUBLIC API
        324
        325
        326exports.Builder = Builder;
        \ No newline at end of file diff --git a/docs/api/javascript/source/chrome.js.src.html b/docs/api/javascript/source/chrome.js.src.html index 910463f92543f..4cd3d284e6789 100644 --- a/docs/api/javascript/source/chrome.js.src.html +++ b/docs/api/javascript/source/chrome.js.src.html @@ -1 +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 +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.setLoggingPrefs(
        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.setLoggingPrefs = 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 {webdriver.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 * @param {webdriver.promise.ControlFlow=} opt_flow The control flow to use, or
        448 * {@code null} to use the currently active flow.
        449 * @return {!webdriver.WebDriver} A new WebDriver instance.
        450 * @deprecated Use {@link Driver new Driver()}.
        451 */
        452function createDriver(opt_options, opt_service, opt_flow) {
        453 return new Driver(opt_options, opt_service, opt_flow);
        454}
        455
        456
        457/**
        458 * Creates a new WebDriver client for Chrome.
        459 *
        460 * @param {(webdriver.Capabilities|Options)=} opt_config The configuration
        461 * options.
        462 * @param {remote.DriverService=} opt_service The session to use; will use
        463 * the {@link getDefaultService default service} by default.
        464 * @param {webdriver.promise.ControlFlow=} opt_flow The control flow to use, or
        465 * {@code null} to use the currently active flow.
        466 * @constructor
        467 * @extends {webdriver.WebDriver}
        468 */
        469var Driver = function(opt_config, opt_service, opt_flow) {
        470 var service = opt_service || getDefaultService();
        471 var executor = executors.createExecutor(service.start());
        472
        473 var capabilities =
        474 opt_config instanceof Options ? opt_config.toCapabilities() :
        475 (opt_config || webdriver.Capabilities.chrome());
        476
        477 var driver = webdriver.WebDriver.createSession(
        478 executor, capabilities, opt_flow);
        479
        480 webdriver.WebDriver.call(
        481 this, driver.getSession(), executor, driver.controlFlow());
        482};
        483util.inherits(Driver, webdriver.WebDriver);
        484
        485
        486// PUBLIC API
        487
        488
        489exports.Driver = Driver;
        490exports.Options = Options;
        491exports.ServiceBuilder = ServiceBuilder;
        492exports.createDriver = createDriver;
        493exports.getDefaultService = getDefaultService;
        494exports.setDefaultService = setDefaultService;
        \ No newline at end of file diff --git a/docs/api/javascript/source/docs/dossier.js.src.html b/docs/api/javascript/source/docs/dossier.js.src.html deleted file mode 100644 index 154e520a76ea2..0000000000000 --- a/docs/api/javascript/source/docs/dossier.js.src.html +++ /dev/null @@ -1 +0,0 @@ -dossier.js

        docs/dossier.js

        1(function(){var h,m=this;function aa(){}
        2function 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"==
        3b&&"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;
        4function ja(a,b,c){return a.call.apply(a.bind,arguments)}function ka(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}}function t(a,b,c){t=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?ja:ka;return t.apply(null,arguments)}
        5function la(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=c.slice();b.push.apply(b,arguments);return a.apply(this,b)}}var w=Date.now||function(){return+new Date};function x(a,b){function c(){}c.prototype=b.prototype;a.i=b.prototype;a.prototype=new c};var ma;function na(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")}function oa(a){if(!pa.test(a))return a;-1!=a.indexOf("&")&&(a=a.replace(qa,"&amp;"));-1!=a.indexOf("<")&&(a=a.replace(ra,"&lt;"));-1!=a.indexOf(">")&&(a=a.replace(sa,"&gt;"));-1!=a.indexOf('"')&&(a=a.replace(ta,"&quot;"));return a}var qa=/&/g,ra=/</g,sa=/>/g,ta=/\"/g,pa=/[&<>\"]/;function ua(a){return String(a).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g,"\\$1").replace(/\x08/g,"\\x08")};var z=Array.prototype,va=z.indexOf?function(a,b,c){return z.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(s(a))return s(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},A=z.forEach?function(a,b,c){z.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=s(a)?a.split(""):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},xa=z.filter?function(a,b,c){return z.filter.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=[],f=0,g=s(a)?
        6a.split(""):a,k=0;k<d;k++)if(k in g){var l=g[k];b.call(c,l,k,a)&&(e[f++]=l)}return e},ya=z.map?function(a,b,c){return z.map.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=Array(d),f=s(a)?a.split(""):a,g=0;g<d;g++)g in f&&(e[g]=b.call(c,f[g],g,a));return e};function za(a,b){var c;a:{c=a.length;for(var d=s(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a)){c=e;break a}c=-1}return 0>c?null:s(a)?a.charAt(c):a[c]}function Aa(a){return z.concat.apply(z,arguments)}
        7function Ba(a){var b=a.length;if(0<b){for(var c=Array(b),d=0;d<b;d++)c[d]=a[d];return c}return[]}var Ca=Ba;function Da(a,b,c){return 2>=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");
        8function 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={};
        9function 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<e;f++){var g=c[f]||"",k=d[f]||"",l=/(\d*)(\D*)/g,n=/(\d*)(\D*)/g;do{var p=l.exec(g)||["","",""],q=n.exec(k)||["","",""];if(0==p[0].length&&0==q[0].length)break;b=((0==p[1].length?0:parseInt(p[1],10))<(0==q[1].length?0:parseInt(q[1],10))?-1:(0==p[1].length?0:parseInt(p[1],10))>(0==q[1].length?0:parseInt(q[1],10))?1:0)||((0==p[2].length)<(0==q[2].length)?-1:
        10(0==p[2].length)>(0==q[2].length)?1:0)||(p[2]<q[2]?-1: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<d.length;g++)0<=va(f,d[g])||f.push(d[g]);a.className=c.join(" ");return c.length==e};function I(a,b){this.x=void 0!==a?a:0;this.y=void 0!==b?b:0}I.prototype.X=function(){return new I(this.x,this.y)};function $a(a,b){return new I(a.x-b.x,a.y-b.y)}I.prototype.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};function ab(a,b){this.width=a;this.height=b}ab.prototype.X=function(){return new ab(this.width,this.height)};ab.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};function bb(a,b){for(var c in a)b.call(void 0,a[c],c,a)}function cb(){var a=db,b;for(b in a)return!1;return!0}var eb="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" ");function fb(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var f=0;f<eb.length;f++)c=eb[f],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}};function J(a){return a?new gb(K(a)):ma||(ma=new gb)}function M(a){var b=document;return s(a)?b.getElementById(a):a}function hb(a,b){bb(b,function(b,d){"style"==d?a.style.cssText=b:"class"==d?a.className=b:"for"==d?a.htmlFor=b:d in ib?a.setAttribute(ib[d],b):0==d.lastIndexOf("aria-",0)||0==d.lastIndexOf("data-",0)?a.setAttribute(d,b):a[d]=b})}
        11var ib={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",valign:"vAlign",width:"width"};function jb(a){return F||"CSS1Compat"!=a.compatMode?a.body||a.documentElement:a.documentElement}function kb(a,b,c){return lb(document,arguments)}
        12function lb(a,b){var c=b[0],d=b[1];if(!Xa&&d&&(d.name||d.type)){c=["<",c];d.name&&c.push(' name="',oa(d.name),'"');if(d.type){c.push(' type="',oa(d.type),'"');var e={};fb(e,d);delete e.type;d=e}c.push(">");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<b.length&&mb(a,c,b);return c}
        13function mb(a,b,c){function d(c){c&&b.appendChild(s(c)?a.createTextNode(c):c)}for(var e=2;e<c.length;e++){var f=c[e];if(!ca(f)||fa(f)&&0<f.nodeType)d(f);else{var g;a:{if(f&&"number"==typeof f.length){if(fa(f)){g="function"==typeof f.item||"string"==typeof f.item;break a}if(ea(f)){g="function"==typeof f.item;break a}}g=!1}A(g?Ba(f):f,d)}}}function nb(a,b){b.parentNode&&b.parentNode.insertBefore(a,b.nextSibling)}function ob(a){return a&&a.parentNode?a.parentNode.removeChild(a):null}
        14function K(a){return 9==a.nodeType?a:a.ownerDocument||a.document}function gb(a){this.j=a||m.document||document}h=gb.prototype;h.Na=function(a,b,c){return lb(this.j,arguments)};h.createElement=function(a){return this.j.createElement(a)};h.createTextNode=function(a){return this.j.createTextNode(String(a))};function pb(a){return"CSS1Compat"==a.j.compatMode}
        15function qb(a){var b=a.j;a=jb(b);b=b.parentWindow||b.defaultView;return D&&G("10")&&b.pageYOffset!=a.scrollTop?new I(a.scrollLeft,a.scrollTop):new I(b.pageXOffset||a.scrollLeft,b.pageYOffset||a.scrollTop)}h.appendChild=function(a,b){a.appendChild(b)};function rb(a){for(var b;b=a.firstChild;)a.removeChild(b)}h.removeNode=ob;
        16h.contains=function(a,b){if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a};D&&G(8);var sb={},tb={};function ub(a,b){var c=J(),d=vb(a(b||wb,void 0,void 0));var e=c.j,c=e.createElement("div");D?(c.innerHTML="<br>"+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={};/*
        17
        18 Copyright 2008 Google Inc.
        19
        20 Licensed under the Apache License, Version 2.0 (the "License");
        21 you may not use this file except in compliance with the License.
        22 You may obtain a copy of the License at
        23
        24 http://www.apache.org/licenses/LICENSE-2.0
        25
        26 Unless required by applicable law or agreed to in writing, software
        27 distributed under the License is distributed on an "AS IS" BASIS,
        28 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        29 See the License for the specific language governing permissions and
        30 limitations under the License.
        31*/
        32function N(a){return a&&a.va&&a.va===sb?a.content:String(a).replace(xb,yb)}var zb={"\x00":"&#0;",'"':"&quot;","&":"&amp;","'":"&#39;","<":"&lt;",">":"&gt;","\t":"&#9;","\n":"&#10;","\x0B":"&#11;","\f":"&#12;","\r":"&#13;"," ":"&#32;","-":"&#45;","/":"&#47;","=":"&#61;","`":"&#96;","\u0085":"&#133;","\u00a0":"&#160;","\u2028":"&#8232;","\u2029":"&#8233;"};function yb(a){return zb[a]}var xb=/[\x00\x22\x26\x27\x3c\x3e]/g;function Ab(a){return'<div class="wrap-details inv '+N(a.visibility)+'"><div><details><summary><label for="show-'+N(a.visibility)+'">Show '+N(a.count)+" hidden item"+(1<a.count?"s":"")+"</label></summary></details></div></div>"}
        33function Bb(a){var b="";if(a.types.length){for(var b=b+"<ul>",c=a.types,d=c.length,e=0;e<d;e++)var f=c[e],b=b+((f.$b?"":'<li class="link"><a href="'+N(a.I)+N(f.href)+'">'+(f.Zb?"<i>"+N(f.name)+"</i>":N(f.name))+"</a>")+(a.ya&&f.types&&f.types.length?Bb({types:f.types,I:a.I,ya:a.ya}):""));b+="</ul>"}return b}
        34function Cb(a){var b,c=0<a.file.children.length;b=""+(a.parent?"":"<ul>");if(c){b+=a.file.name?"<li>"+N(a.file.name)+"/<ul>":"";for(var c=a.file.children,d=c.length,e=0;e<d;e++)b+=Cb({file:c[e],I:a.I,parent:a.file});b+=a.file.name?"</ul>":""}else a.file.name&&(b+='<li class="link"><a href="'+N(a.I)+N(a.file.href)+'">'+N(a.file.name)+"</a>");return b+=a.parent?"":"</ul>"};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;
        35function 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;
        36a.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};
        37h.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);-1<g?(a=f[g],c||(a.ea=!1)):(a=new Ob(b,this.src,a,!!d,e),a.ea=c,f.push(a));return a};Qb.prototype.remove=function(a,b,c,d){if(!(a in this.l))return!1;var e=this.l[a];b=Rb(e,b,c,d);return-1<b?(Pb(e[b]),z.splice.call(e,b,1),0==e.length&&(delete this.l[a],this.da--),!0):!1};
        38function Sb(a,b){var c=b.type;if(!(c in a.l))return!1;var d=a.l[c],e=va(d,b),f;(f=0<=e)&&z.splice.call(d,e,1);f&&(Pb(b),0==a.l[c].length&&(delete a.l[c],a.da--));return f}Qb.prototype.na=function(a){var b=0,c;for(c in this.l)if(!a||c==a){for(var d=this.l[c],e=0;e<d.length;e++)++b,Pb(d[e]);delete this.l[c];this.da--}return b};Qb.prototype.Y=function(a,b,c,d){a=this.l[a];var e=-1;a&&(e=Rb(a,b,c,d));return-1<e?a[e]:null};
        39function Rb(a,b,c,d){for(var e=0;e<a.length;++e){var f=a[e];if(!f.U&&f.K==b&&f.capture==!!c&&f.ga==d)return e}return-1};var Tb="closure_lm_"+(1E6*Math.random()|0),Ub={},Vb=0;function R(a,b,c,d,e){if(r(b)){for(var f=0;f<b.length;f++)R(a,b[f],c,d,e);return null}c=Wb(c);if(Mb(a))a=a.o(b,c,d,e);else{if(!b)throw Error("Invalid event type");var f=!!d,g=Xb(a);g||(a[Tb]=g=new Qb(a));c=g.add(b,c,!1,d,e);c.ma||(d=Yb(),c.ma=d,d.src=a,d.K=c,a.addEventListener?a.addEventListener(b,d,f):a.attachEvent(b in Ub?Ub[b]:Ub[b]="on"+b,d),Vb++);a=c}return a}
        40function Yb(){var a=Zb,b=Db?function(c){return a.call(b.src,b.K,c)}:function(c){c=a.call(b.src,b.K,c);if(!c)return c};return b}function $b(a,b,c,d,e){if(r(b))for(var f=0;f<b.length;f++)$b(a,b[f],c,d,e);else c=Wb(c),Mb(a)?a.s(b,c,d,e):a&&(a=Xb(a))&&(b=a.Y(b,c,!!d,e))&&ac(b)}
        41function ac(a){if(da(a)||!a||a.U)return!1;var b=a.src;if(Mb(b))return Sb(b.C,a);var c=a.type,d=a.ma;b.removeEventListener?b.removeEventListener(c,d,a.capture):b.detachEvent&&b.detachEvent(c in Ub?Ub[c]:Ub[c]="on"+c,d);Vb--;(c=Xb(b))?(Sb(c,a),0==c.da&&(c.src=null,b[Tb]=null)):Pb(a);return!0}function bc(a,b,c,d){var e=1;if(a=Xb(a))if(b=a.l[b])for(b=Ca(b),a=0;a<b.length;a++){var f=b[a];f&&f.capture==c&&!f.U&&(e&=!1!==cc(f,d))}return Boolean(e)}
        42function cc(a,b){var c=a.K,d=a.ga||a.src;a.ea&&ac(a);return c.call(d,b)}
        43function Zb(a,b){if(a.U)return!0;if(!Db){var c;if(!(c=b))a:{c=["window","event"];for(var d=m,e;e=c.shift();)if(null!=d[e])d=d[e];else{c=null;break a}c=d}e=c;c=new Q(e,this);d=!0;if(!(0>e.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<e.length;k++)c.currentTarget=
        44e[k],d&=bc(e[k],f,!1,c)}return d}return cc(a,new Q(b,this))}function Xb(a){a=a[Tb];return a instanceof Qb?a:null}var dc="__closure_events_fn_"+(1E9*Math.random()>>>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<a.className.length?" "+b:b)},hc=ec?function(a,b){A(b,function(b){gc(a,b)})}:function(a,b){var c={};A(fc(a),function(a){c[a]=!0});A(b,function(a){c[a]=!0});a.className="";for(var d in c)a.className+=0<a.className.length?
        45" "+d:d},ic=ec?function(a,b){a.classList.remove(b)}:function(a,b){S(a,b)&&(a.className=xa(fc(a),function(a){return a!=b}).join(" "))},jc=ec?function(a,b){A(b,function(b){ic(a,b)})}:function(a,b){a.className=xa(fc(a),function(a){return!(0<=va(b,a))}).join(" ")};function T(a,b,c,d){this.top=a;this.right=b;this.bottom=c;this.left=d}T.prototype.X=function(){return new T(this.top,this.right,this.bottom,this.left)};T.prototype.contains=function(a){return this&&a?a instanceof T?a.left>=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};
        46T.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};
        47kc.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]}
        48function 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}
        49function 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}
        50function 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=
        51Math.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}
        52function 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;
        53b!=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}
        54function 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")}
        55var 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)}
        56function 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};
        57function 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))}
        58var 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}
        59var 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;e<c.length&&d.length<b;e++){var f=c[e];String(f).match(a)&&d.push(f)}}return d}
        60function Hc(a,b,c){for(var d=[],e=0;e<c.length;e++){var f=c[e],g=a.toLowerCase(),k=String(f).toLowerCase(),l=0;if(-1!=k.indexOf(g))l=parseInt((k.indexOf(g)/4).toString(),10);else for(var n=g.split(""),p=-1,q=10,y=0,u;u=n[y];y++)u=k.indexOf(u),u>p?(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<b&&y<d.length;y++)a.push(d[y].Rb);return a};function X(){O.call(this);this.C=new Qb(this);this.ub=this}x(X,O);X.prototype[Lb]=!0;h=X.prototype;h.Fa=null;h.addEventListener=function(a,b,c,d){R(this,a,b,c,d)};h.removeEventListener=function(a,b,c,d){$b(this,a,b,c,d)};
        61h.dispatchEvent=function(a){var b,c=this.Fa;if(c)for(b=[];c;c=c.Fa)b.push(c);var c=this.ub,d=a.type||a;if(s(a))a=new P(a,c);else if(a instanceof P)a.target=a.target||c;else{var e=a;a=new P(d,c);fb(a,e)}var e=!0,f;if(b)for(var g=b.length-1;!a.G&&0<=g;g--)f=a.currentTarget=b[g],e=Ic(f,d,!0,a)&&e;a.G||(f=a.currentTarget=c,e=Ic(f,d,!0,a)&&e,a.G||(e=Ic(f,d,!1,a)&&e));if(b)for(g=0;!a.G&&g<b.length;g++)f=a.currentTarget=b[g],e=Ic(f,d,!1,a)&&e;return e};
        62h.e=function(){X.i.e.call(this);this.C&&this.C.na(void 0);this.Fa=null};h.o=function(a,b,c,d){return this.C.add(String(a),b,!1,c,d)};h.s=function(a,b,c,d){return this.C.remove(String(a),b,c,d)};function Ic(a,b,c,d){b=a.C.l[String(b)];if(!b)return!0;b=Ca(b);for(var e=!0,f=0;f<b.length;++f){var g=b[f];if(g&&!g.U&&g.capture==c){var k=g.K,l=g.ga||g.src;g.ea&&Sb(a.C,g);e=!1!==k.call(l,d)&&e}}return e&&!1!=d.nb}h.Y=function(a,b,c,d){return this.C.Y(String(a),b,c,d)};function Jc(a,b,c){X.call(this);this.R=a;this.aa=c;this.p=b;R(b,[Kc,Lc,Mc,Nc],this.handleEvent,!1,this);this.q=null;this.c=[];this.D=-1;this.k=0;this.J=this.g=null;this.Va={}}x(Jc,X);h=Jc.prototype;h.$a=10;h.wb=!0;h.Ma=!1;h.tb=!1;h.qb=!1;var Kc="hilite",Lc="select",Nc="dismiss",Mc="canceldismiss";h=Jc.prototype;
        63h.handleEvent=function(a){if(a.target==this.p)switch(a.type){case Kc:this.A(a.V);break;case Lc:a=a.V;var b=this.c[Oc(this,a)],c=!!b&&this.R.za&&this.R.za(b);a&&b&&!c&&this.D!=a&&this.A(a);c||Pc(this);break;case Mc:Qc(this);break;case Nc:Rc(this)}};function Sc(a){for(var b=a.k+a.c.length-1,c=a.D,d=0;d<a.c.length;d++){if(c>=a.k&&c<b)c++;else if(-1==c)c=a.k;else if(a.Ma&&c==b){a.A(-1);break}else if(a.tb&&c==b)c=a.k;else break;if(a.A(c))break}}
        64function Tc(a){for(var b=a.k+a.c.length-1,c=a.D,d=0;d<a.c.length;d++){if(c>a.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)};
        65function 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()));
        66f=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)};
        67function 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)};
        68h.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;f<a.length;++f)e.push({id:this.k+f,data:a[f]});f=null;this.g&&(f=this.Va[ga(this.g)]||this.g);this.p.vb=f;this.p.Ha(e,this.q,this.g);f=this.wb;c&&void 0!==c.Cb()&&(f=c.Cb());this.D=-1;(f||0<=d)&&0!=e.length&&this.q&&(0<=d?this.A(this.k+d):Sc(this));this.dispatchEvent("suggestionsupdate")};function Oc(a,b){var c=b-a.k;return 0>c||c>=a.c.length?-1:c}
        69h.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&&a<0.8*this.Q?this.f=this.W.setTimeout(this.ua,this.Q-a):(this.f&&(this.W.clearTimeout(this.f),this.f=null),this.dispatchEvent(ad),this.enabled&&(this.f=this.W.setTimeout(this.ua,this.Q),this.Ca=w()))}};h.start=function(){this.enabled=!0;this.f||(this.f=this.W.setTimeout(this.ua,this.Q),this.Ca=w())};
        70h.stop=function(){this.enabled=!1;this.f&&(this.W.clearTimeout(this.f),this.f=null)};h.e=function(){$c.i.e.call(this);this.stop();delete this.W};var ad="tick";var bd;function cd(a,b){b?a.setAttribute("role",b):a.removeAttribute("role")}function dd(a,b,c){ca(c)&&(c=c.join(" "));var d="aria-"+b;""===c||void 0==c?(bd||(bd={atomic:!1,autocomplete:"none",dropeffect:"none",haspopup:!1,live:"off",multiline:!1,multiselectable:!1,orientation:"vertical",readonly:!1,relevant:"additions text",required:!1,sort:"none",busy:!1,disabled:!1,hidden:!1,invalid:"false"}),c=bd,b in c?a.setAttribute(d,c[b]):a.removeAttribute(d)):a.setAttribute(d,c)}
        71function ed(a,b){var c="";b&&(c=b.id);dd(a,"activedescendant",c)};function Vc(a){var b;a:{var c=0,d=0;if(Xc(a))c=a.selectionStart,d=-1;else if(D){var e=Yc(a);b=e[0];e=e[1];if(b.inRange(e)){b.setEndPoint("EndToStart",e);if("textarea"==a.type){e.duplicate();c=a=b.text;for(d=!1;!d;)0==b.compareEndPoints("StartToEnd",b)?d=!0:(b.moveEnd("character",-1),b.text==a?c+="\r\n":d=!0);b=[c.length,-1];break a}c=b.text.length;d=-1}}b=[c,d]}return b[0]}
        72function Yc(a){var b=a.ownerDocument||a.document,c=b.selection.createRange();"textarea"==a.type?(b=b.body.createTextRange(),b.moveToElementText(a)):b=a.createTextRange();return[b,c]}function Zc(a,b){"textarea"==a.type&&(b=a.value.substring(0,b).replace(/(\r\n|\r|\n)/g,"\n").length);return b}function Xc(a){try{return"number"==typeof a.selectionStart}catch(b){return!1}};function fd(a){O.call(this);this.Z=a;this.ka={}}x(fd,O);var gd=[];h=fd.prototype;h.o=function(a,b,c,d,e){r(b)||(gd[0]=b,b=gd);for(var f=0;f<b.length;f++){var g=R(a,b[f],c||this.handleEvent,d||!1,e||this.Z||this);if(!g)break;this.ka[g.key]=g}return this};h.s=function(a,b,c,d,e){if(r(b))for(var f=0;f<b.length;f++)this.s(a,b[f],c,d,e);else c=c||this.handleEvent,e=e||this.Z||this,c=Wb(c),d=!!d,b=Mb(a)?a.Y(b,c,d,e):a?(a=Xb(a))?a.Y(b,c,d,e):null:null,b&&(ac(b),delete this.ka[b.key]);return this};
        73h.na=function(){bb(this.ka,ac);this.ka={}};h.e=function(){fd.i.e.call(this);this.na()};h.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented");};function hd(a,b,c,d,e){if(!(D||F&&G("525")))return!0;if(B&&e)return id(a);if(e&&!d)return!1;da(b)&&(b=jd(b));if(!c&&(17==b||18==b||B&&91==b))return!1;if(F&&d&&c)switch(a){case 220:case 219:case 221:case 192:case 186:case 189:case 187:case 188:case 190:case 191:case 192:case 222:return!1}if(D&&d&&b==a)return!1;switch(a){case 13:return!(D&&D&&9<=H);case 27:return!F}return id(a)}
        74function id(a){if(48<=a&&57>=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}
        75function 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;
        76var 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;
        77h.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};
        78h.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)};
        79function 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?new $c(d):null;this.h=new fd(this);this.qa=new fd(this);this.$=new ld;this.Xa=-1}x(xd,O);var yd=(vd||wd)&&!G("533.17.9");h=xd.prototype;h.Wb=!0;h.Bb=!0;h.sb=!1;h.Qb=!0;h.Pb=!0;h.ra=null;h.a=null;h.Ba="";h.H=!1;h.Ja=!1;h.Tb=!0;
        80h.ta=function(a){for(var b=0;b<arguments.length;b++){var c=arguments[b];fa(c)&&1==c.nodeType&&dd(c,"haspopup",!0);this.h.o(c,"focus",this.Ra);this.h.o(c,"blur",this.Db);if(!this.a&&(this.qa.o(c,"keydown",this.Kb),fa(c)&&1==c.nodeType)){var d;a:{var e=K(c);try{d=e&&e.activeElement;break a}catch(f){}d=null}d==c&&zd(this,c)}}};h.e=function(){xd.i.e.call(this);null!=this.ra&&window.clearTimeout(this.ra);this.h.B();delete this.h;this.qa.B();this.$.B();Hb(this.f)};
        81function Ad(a,b){switch(b.keyCode){case 40:if(a.d.p.t){a.sb?Tc(a.d):Sc(a.d);b.preventDefault();return}if(!a.S){a.update(!0);b.preventDefault();return}break;case 38:if(a.d.p.t){a.sb?Sc(a.d):Tc(a.d);b.preventDefault();return}break;case 9:if(a.d.p.t&&!b.shiftKey){if(a.update(),Pc(a.d)&&a.Lb){b.preventDefault();return}}else a.d.u();break;case 13:if(a.d.p.t){if(a.update(),Pc(a.d)){b.preventDefault();b.stopPropagation();return}}else a.d.u();break;case 27:if(a.d.p.t){a.d.u();b.preventDefault();b.stopPropagation();
        82return}break;case 229:if(!a.H){a.H||(a.h.o(a.a,"keyup",a.fb),a.h.o(a.a,"keypress",a.eb),a.H=!0);return}break;default:a.f&&!a.Tb&&(a.f.stop(),a.f.start())}Bd(a,b)}function Bd(a,b){var c=a.S&&b.charCode&&-1!=a.ba.indexOf(String.fromCharCode(b.charCode));a.Qb&&c&&a.update();a.Pb&&c&&Pc(a.d)&&b.preventDefault()}h.Fb=function(){return!1};h.Ra=function(a){zd(this,a.target||null)};
        83function zd(a,b){a.qa.na();a.d&&Qc(a.d);b!=a.a&&(a.a=b,a.f&&(a.f.start(),a.h.o(a.f,ad,a.ib)),a.Ba=a.a.value,md(a.$,a.a),a.h.o(a.$,"key",a.gb),a.h.o(a.a,"mousedown",a.hb),D&&a.h.o(a.a,"keypress",a.cb))}h.Db=function(){yd?this.ra=window.setTimeout(t(this.kb,this),0):this.kb()};
        84h.kb=function(){this.a&&(this.h.s(this.$,"key",this.gb),this.$.detach(),this.h.s(this.a,"keyup",this.Fb),this.h.s(this.a,"mousedown",this.hb),D&&this.h.s(this.a,"keypress",this.cb),this.H&&Cd(this),this.a=null,this.f&&(this.f.stop(),this.h.s(this.f,ad,this.ib)),this.d&&Rc(this.d))};h.ib=function(){this.update()};h.Kb=function(a){this.Ra(a)};h.gb=function(a){this.Xa=a.keyCode;this.d&&Ad(this,a)};h.eb=function(){this.H&&229!=this.Xa&&Cd(this)};
        85h.fb=function(a){this.H&&(13==a.keyCode||77==a.keyCode&&a.ctrlKey)&&Cd(this)};h.hb=function(){};function Cd(a){a.H&&(a.H=!1,a.h.s(a.a,"keypress",a.eb),a.h.s(a.a,"keyup",a.fb))}h.cb=function(a){Bd(this,a)};
        86h.update=function(a){if(this.a&&(a||this.a.value!=this.Ba)){if(a||!this.Ja){var b;a=Vc(this.a);b=this.a.value;a=Wc(this,b)[Uc(this,b,a)];b=this.rb?String(a).replace(this.rb,""):a;if(this.d&&(this.d.g=this.a,a=this.d,a.q!=b)){a.q=b;var c=a.R;b=a.q;var d=a.$a,e=t(a.Ib,a);if(c.Ub){var c=c.c,f=Gc(b,d,c);0==f.length&&(f=Hc(b,d,c));d=f}else d=Gc(b,d,c.c);e(b,d);Qc(a)}}this.Ba=this.a.value}this.Ja=!1};
        87function Uc(a,b,c){a=Wc(a,b);if(c==b.length)return a.length-1;for(var d=b=0,e=0;d<a.length&&e<=c;d++)e+=a[d].length,b=d;return b}function Wc(a,b){if(!a.S)return[b];for(var c=String(b).split(""),d=[],e=[],f=0,g=!1;f<c.length;f++)a.Za&&-1!=a.Za.indexOf(c[f])?(a.Bb&&!g&&(d.push(e.join("")),e.length=0),e.push(c[f]),g=!g):g||-1==a.ba.indexOf(c[f])?e.push(c[f]):(e.push(c[f]),d.push(e.join("")),e.length=0);d.push(e.join(""));return d};function Dd(){X.call(this);this.r=Ed;this.Pa=this.startTime=null}x(Dd,X);var Ed=0;Dd.prototype.L=function(){this.v("begin")};Dd.prototype.T=function(){this.v("end")};Dd.prototype.v=function(a){this.dispatchEvent(a)};function Fd(a,b,c){O.call(this);this.Da=a;this.Q=b||0;this.Z=c;this.xb=t(this.zb,this)}x(Fd,O);h=Fd.prototype;h.P=0;h.e=function(){Fd.i.e.call(this);this.stop();delete this.Da;delete this.Z};h.start=function(a){this.stop();var b=this.xb;a=void 0!==a?a:this.Q;if(!ea(b))if(b&&"function"==typeof b.handleEvent)b=t(b.handleEvent,b);else throw Error("Invalid listener argument");this.P=2147483647<a?-1:m.setTimeout(b,a||0)};h.stop=function(){0!=this.P&&m.clearTimeout(this.P);this.P=0};
        88h.zb=function(){this.P=0;this.Da&&this.Da.call(this.Z)};var db={},Gd=null;function Hd(a){a=ga(a);delete db[a];cb()&&Gd&&Gd.stop()}function Id(){Gd||(Gd=new Fd(function(){Jd()},20));var a=Gd;0!=a.P||a.start()}function Jd(){var a=w();bb(db,function(b){Kd(b,a)});cb()||Id()};function Ld(a,b,c,d){Dd.call(this);if(!r(a)||!r(b))throw Error("Start and end parameters must be arrays");if(a.length!=b.length)throw Error("Start and end points must be the same length");this.ca=a;this.Ab=b;this.duration=c;this.Ka=d;this.coords=[]}x(Ld,Dd);h=Ld.prototype;h.n=0;
        89h.play=function(a){if(a||this.r==Ed)this.n=0,this.coords=this.ca;else if(1==this.r)return!1;Hd(this);this.startTime=a=w();-1==this.r&&(this.startTime-=this.duration*this.n);this.Pa=this.startTime+this.duration;this.n||this.L();this.v("play");-1==this.r&&this.v("resume");this.r=1;var b=ga(this);b in db||(db[b]=this);Id();Kd(this,a);return!0};h.stop=function(a){Hd(this);this.r=Ed;a&&(this.n=1);Md(this,this.n);this.v("stop");this.T()};h.e=function(){this.r==Ed||this.stop(!1);this.v("destroy");Ld.i.e.call(this)};
        90function Kd(a,b){a.n=(b-a.startTime)/(a.Pa-a.startTime);1<=a.n&&(a.n=1);Md(a,a.n);1==a.n?(a.r=Ed,Hd(a),a.v("finish"),a.T()):1==a.r&&a.Ea()}function Md(a,b){ea(a.Ka)&&(b=a.Ka(b));a.coords=Array(a.ca.length);for(var c=0;c<a.ca.length;c++)a.coords[c]=(a.Ab[c]-a.ca[c])*b+a.ca[c]}h.Ea=function(){this.v("animate")};h.v=function(a){this.dispatchEvent(new Nd(a,this))};
        91function Nd(a,b){P.call(this,a);this.coords=b.coords;this.x=b.coords[0];this.y=b.coords[1];this.z=b.coords[2];this.duration=b.duration;this.n=b.n;this.state=b.r}x(Nd,P);function Y(a,b,c,d,e){Ld.call(this,b,c,d,e);this.element=a}x(Y,Ld);Y.prototype.pa=aa;Y.prototype.Ea=function(){this.pa();Y.i.Ea.call(this)};Y.prototype.T=function(){this.pa();Y.i.T.call(this)};Y.prototype.L=function(){this.pa();Y.i.L.call(this)};function Od(a,b,c,d,e){da(b)&&(b=[b]);da(c)&&(c=[c]);Y.call(this,a,b,c,d,e);if(1!=b.length||1!=c.length)throw Error("Start and end points must be 1D");}x(Od,Y);
        92Od.prototype.pa=function(){var a=this.coords[0],b=this.element.style;"opacity"in b?b.opacity=a:"MozOpacity"in b?b.MozOpacity=a:"filter"in b&&(b.filter=""===a?"":"alpha(opacity="+100*a+")")};Od.prototype.show=function(){this.element.style.display=""};function Pd(a,b,c){Od.call(this,a,1,0,b,c)}x(Pd,Od);Pd.prototype.L=function(){this.show();Pd.i.L.call(this)};Pd.prototype.T=function(){this.element.style.display="none";Pd.i.T.call(this)};function Qd(a,b,c){Od.call(this,a,0,1,b,c)}x(Qd,Od);
        93Qd.prototype.L=function(){this.show();Qd.i.L.call(this)};function Z(){}Z.wa=function(){return Z.Wa?Z.Wa:Z.Wa=new Z};Z.prototype.ab=0;Z.wa();function Rd(a,b,c,d){X.call(this);this.Ga=a||document.body;this.w=J(this.Ga);this.Mb=!a;this.b=null;this.q="";this.c=[];this.M=[];this.pb=this.ha=-1;this.t=!1;this.className="ac-renderer";this.Ia="ac-row";this.Ya="active";this.La="ac-active";this.Hb="ac-highlighted";this.fa=b||null;this.Vb=null!=d?d:!0;this.Jb=!0;this.xa=!1;this.Nb=!!c;this.oa=!1;this.la=0}x(Rd,X);h=Rd.prototype;h.Ha=function(a,b,c){this.q=b;this.c=a;this.ha=-1;this.pb=w();this.g=c;this.M=[];Sd(this)};
        94h.u=function(){this.g&&ed(this.g,null);this.t&&(this.t=!1,this.g&&dd(this.g,"haspopup",!1),0<this.la?(Hb(this.N),this.N=new Pd(this.b,this.la),this.N.play()):sc(this.b,!1))};h.show=function(){this.t||(this.t=!0,this.g&&(cd(this.g,"combobox"),dd(this.g,"autocomplete","list"),dd(this.g,"haspopup",!0)),0<this.la?(Hb(this.N),this.N=new Qd(this.b,this.la),this.N.play()):sc(this.b,!0))};
        95function Td(a,b){var c=0<=b&&b<a.c.length?a.c[b]:void 0,d=0<=b&&b<a.M.length?a.M[b]:void 0;if(a.dispatchEvent({type:"rowhilite",cc:d,V:c?c.data:null})&&(0<=a.ha&&jc(a.M[a.ha],[a.La,a.Ya]),a.ha=b,d)){hc(d,[a.La,a.Ya]);a.g&&ed(a.g,d);var c=a.b,e=W(d),f=W(c),g=zc(c),k=e.x-f.x-g.left,e=e.y-f.y-g.top,f=c.clientHeight-d.offsetHeight,g=c.scrollLeft,l=c.scrollTop,g=g+Math.min(k,Math.max(k-(c.clientWidth-d.offsetWidth),0)),l=l+Math.min(e,Math.max(e-f,0)),d=new I(g,l);c.scrollLeft=d.x;c.scrollTop=d.y}}
        96h.A=function(a){if(-1==a)Td(this,-1);else for(var b=0;b<this.c.length;b++)if(this.c[b].id==a){Td(this,b);break}};function Ud(a){if(!a.b){var b=a.w.Na("div",{style:"display:none"});a.b=b;hc(b,na(a.className).split(" "));cd(b,"listbox");b.id=":"+(Z.wa().ab++).toString(36);a.w.appendChild(a.Ga,b);R(b,"click",a.Qa,!1,a);R(b,"mousedown",a.Sa,!1,a);R(b,"mouseover",a.Ta,!1,a)}}
        97function Sd(a){Ud(a);a.oa&&(a.b.style.visibility="hidden");a.Xb&&(a.b.style.minWidth=a.Xb.clientWidth+"px");a.M.length=0;rb(a.b);if(!a.fa||!a.fa.ac){var b=null;A(a.c,function(a){var d=this.q,e=this.w.Na("div",{className:this.Ia,id:":"+(Z.wa().ab++).toString(36)});cd(e,"option");this.fa&&this.fa.bc||(e.innerHTML=oa(a.data.toString()));d&&this.Vb&&Vd(this,e,d);gc(e,this.Ia);this.M.push(e);a=e;this.oa?this.b.insertBefore(a,b):this.w.appendChild(this.b,a);b=a},a)}0==a.c.length?a.u():(a.show(),Wd(a),uc(a.b))}
        98function Wd(a){if(a.g&&a.Mb){var b,c=a.Nb?3:1;a.oa&&(c^=1);b=c;var d=a.vb||a.g,c=a.b,e=b^1,f,g;if(f=c.offsetParent){var k="HTML"==f.tagName||"BODY"==f.tagName;k&&"static"==V(f,"position")||(g=W(f),k||(k=(k=oc(f))&&E?-f.scrollLeft:!k||D&&G("8")||"visible"==V(f,"overflowX")?f.scrollLeft:f.scrollWidth-f.clientWidth-f.scrollLeft,g=$a(g,new I(k,f.scrollTop))))}f=g||new I;g=W(d);k=qc(d);g=new kc(g.x,g.y,k.width,k.height);if(k=nc(d)){var l=new kc(k.left,k.top,k.right-k.left,k.bottom-k.top),k=Math.max(g.left,
        99l.left),n=Math.min(g.left+g.width,l.left+l.width);if(k<=n){var p=Math.max(g.top,l.top),l=Math.min(g.top+g.height,l.top+l.height);p<=l&&(g.left=k,g.top=p,g.width=n-k,g.height=l-p)}}k=J(d);p=J(c);if(k.j!=p.j){var n=k.j.body,p=p.j.parentWindow||p.j.defaultView,l=new I(0,0),q=K(n)?K(n).parentWindow||K(n).defaultView:window,y=n;do{var u;if(q==p)u=W(y);else{u=y;var L=void 0;if(u.getBoundingClientRect)L=lc(u),L=new I(L.left,L.top);else var L=qb(J(u)),v=W(u),L=new I(v.x-L.x,v.y-L.y);v=void 0;if(E&&!G(12)){v=
        100void 0;v=void 0;D?v="-ms-transform":F?v="-webkit-transform":C?v="-o-transform":E&&(v="-moz-transform");var wa=void 0;v&&(wa=V(u,v));wa||(wa=V(u,"transform"));v=wa?(u=wa.match(Ec))?new I(parseFloat(u[1]),parseFloat(u[2])):new I(0,0):new I(0,0);v=new I(L.x+v.x,L.y+v.y)}else v=L;u=v}l.x+=u.x;l.y+=u.y}while(q&&q!=p&&(y=q.frameElement)&&(q=q.parent));n=$a(l,W(n));D&&!pb(k)&&(n=$a(n,qb(k)));g.left+=n.x;g.top+=n.y}b=(b&4&&oc(d)?b^2:b)&-5;b=new I(b&2?g.left+g.width:g.left,b&1?g.top+g.height:g.top);b=$a(b,
        101f);if(d=nc(c))d.top-=f.y,d.right-=f.x,d.bottom-=f.y,d.left-=f.x;f=b.X();g=(e&4&&oc(c)?e^2:e)&-5;b=qc(c);e=b.X();0!=g&&(g&2&&(f.x-=e.width+0),g&1&&(f.y-=e.height+0));d?(g=f,k=65,n=0,65==(k&65)&&(g.x<d.left||g.x>=d.right)&&(k&=-2),132==(k&132)&&(g.y<d.top||g.y>=d.bottom)&&(k&=-5),g.x<d.left&&k&1&&(g.x=d.left,n|=1),g.x<d.left&&g.x+e.width>d.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.x<d.left?
        10216:0)|(g.x+e.width>d.right?32:0)),g.y<d.top&&k&4&&(g.y=d.top,n|=2),g.y<=d.top&&g.y+e.height<d.bottom&&k&32&&(e.height=Math.max(e.height-(d.top-g.y),0),g.y=d.top,n|=8),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.y<d.top?64:0)|(g.y+e.height>d.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=
        103pc(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),
        104parseFloat(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)};
        105function Vd(a,b,c){if(3==b.nodeType){var d=null;r(c)&&1<c.length&&!a.xa&&(d=Da(c,1));c=Xd(a,c);if(0!=c.length){var e=b.nodeValue,f=a.Jb?RegExp("\\b(?:"+c+")","gi"):RegExp(c,"gi");c=[];for(var g=0,k=f.exec(e),l=0;k;)l++,c.push(e.substring(g,k.index)),c.push(e.substring(k.index,f.lastIndex)),g=f.lastIndex,k=f.exec(e);c.push(e.substring(g));if(1<c.length){d=a.xa?l:1;for(e=0;e<d;e++)f=2*e,b.nodeValue=c[f],g=a.w.createElement("b"),g.className=a.Hb,a.w.appendChild(g,a.w.createTextNode(c[f+1])),g=b.parentNode.insertBefore(g,
        106b.nextSibling),b.parentNode.insertBefore(a.w.createTextNode(""),g.nextSibling),b=g.nextSibling;a=Da(c,2*d);b.nodeValue=a.join("")}else d&&Vd(a,b,d)}}else for(b=b.firstChild;b;)d=b.nextSibling,Vd(a,b,c),b=d}
        107function Xd(a,b){var c="";if(!b)return c;r(b)&&(b=xa(b,function(a){return!/^[\s\xa0]*$/.test(null==a?"":String(a))}));a.xa?r(b)?c=ya(b,ua).join("|"):(c=b.replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,""),c=ua(c),c=c.replace(/ /g,"|")):r(b)?c=0<b.length?ua(b[0]):"":/^\W/.test(b)||(c=ua(b));return c}function Yd(a,b){for(;b&&b!=a.b&&!S(b,a.Ia);)b=b.parentNode;return b?va(a.M,b):-1}h.Qa=function(a){var b=Yd(this,a.target);0<=b&&this.dispatchEvent({type:Lc,V:this.c[b].id});a.stopPropagation()};
        108h.Sa=function(a){a.stopPropagation();a.preventDefault()};h.Ta=function(a){a=Yd(this,a.target);0<=a&&!(300>w()-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};/*
        109 Copyright 2013 Jason Leyba
        110
        111 Licensed under the Apache License, Version 2.0 (the "License");
        112 you may not use this file except in compliance with the License.
        113 You may obtain a copy of the License at
        114
        115 http://www.apache.org/licenses/LICENSE-2.0
        116
        117 Unless required by applicable law or agreed to in writing, software
        118 distributed under the License is distributed on an "AS IS" BASIS,
        119 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        120 See the License for the specific language governing permissions and
        121 limitations under the License.
        122*/
        123function $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;
        124var 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}();
        125function 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;
        126R(a,"update",b)}
        127function 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");
        128d.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=[]}
        129function 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}
        130function 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}
        131function 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))}
        132function ke(a){return window.localStorage?!!window.localStorage.getItem(a):!1}var ne="public",oe="protected",pe="private";function qe(a){return"dossier.visibility."+a}
        133function 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;e<k;++e){var l=c.shift();if(l.tagName===Ya)break;a.push(l);S(l,"public")?(d++,g.mb++):
        134S(l,"protected")?(f++,g.lb++):S(l,"private")&&(y++,g.jb++)}return a}if(a){var c=Ba(a.querySelectorAll(".wrap-details, h3")),d=0,f=0,y=0;do A(b(),function(a){S(a,"public")&&d?(nb(e("public",d),a),d=0):S(a,"protected")&&f?(nb(e("protected",f),a),f=0):S(a,"private")&&y&&(nb(e("private",y),a),y=0)});while(c.length)}}function e(a,b){return ub(Ab,{visibility:a,count:b})}if(document.getElementById("show-public")){var f=document.getElementsByTagName("main")[0],g={mb:0,lb:0,jb:0};a();b("show-public",ne);b("show-protected",
        135oe);b("show-private",pe);d(document.getElementById("typedefs"));d(document.getElementById("instance-methods"));d(document.getElementById("instance-properties"));d(document.getElementById("static-functions"));d(document.getElementById("static-properties"));d(document.getElementById("compiler-constants"));sc(document.getElementById("visibility-controls"),g.mb||g.lb||g.jb)}};;init();})();
        \ No newline at end of file diff --git a/docs/api/javascript/source/docs/types.js.src.html b/docs/api/javascript/source/docs/types.js.src.html deleted file mode 100644 index c65097b416547..0000000000000 --- a/docs/api/javascript/source/docs/types.js.src.html +++ /dev/null @@ -1 +0,0 @@ -types.js

        docs/types.js

        1var 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/docs/api/javascript/source/error.js.src.html b/docs/api/javascript/source/error.js.src.html index a8aa5b0083395..aeb0bff4fb486 100644 --- a/docs/api/javascript/source/error.js.src.html +++ b/docs/api/javascript/source/error.js.src.html @@ -1 +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 +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/docs/api/javascript/source/executors.js.src.html b/docs/api/javascript/source/executors.js.src.html index b44c5ad4eaab8..0c892dc9b7655 100644 --- a/docs/api/javascript/source/executors.js.src.html +++ b/docs/api/javascript/source/executors.js.src.html @@ -1 +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 +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/docs/api/javascript/source/firefox/binary.js.src.html b/docs/api/javascript/source/firefox/binary.js.src.html new file mode 100644 index 0000000000000..b8230521e84d3 --- /dev/null +++ b/docs/api/javascript/source/firefox/binary.js.src.html @@ -0,0 +1 @@ +binary.js

        firefox/binary.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 child = require('child_process'),
        19 fs = require('fs'),
        20 path = require('path'),
        21 util = require('util');
        22
        23var promise = require('..').promise,
        24 _base = require('../_base'),
        25 io = require('../io'),
        26 exec = require('../io/exec');
        27
        28
        29
        30/** @const */
        31var NO_FOCUS_LIB_X86 = _base.isDevMode() ?
        32 path.join(__dirname, '../../../../cpp/prebuilt/i386/libnoblur.so') :
        33 path.join(__dirname, '../lib/firefox/i386/libnoblur.so') ;
        34
        35/** @const */
        36var NO_FOCUS_LIB_AMD64 = _base.isDevMode() ?
        37 path.join(__dirname, '../../../../cpp/prebuilt/amd64/libnoblur64.so') :
        38 path.join(__dirname, '../lib/firefox/amd64/libnoblur64.so') ;
        39
        40var X_IGNORE_NO_FOCUS_LIB = 'x_ignore_nofocus.so';
        41
        42var foundBinary = null;
        43
        44
        45/**
        46 * Checks the default Windows Firefox locations in Program Files.
        47 * @return {!promise.Promise.<?string>} A promise for the located executable.
        48 * The promise will resolve to {@code null} if Fireox was not found.
        49 */
        50function defaultWindowsLocation() {
        51 var files = [
        52 process.env['PROGRAMFILES'] || 'C:\\Program Files',
        53 process.env['PROGRAMFILES(X86)'] || 'C:\\Program Files (x86)'
        54 ].map(function(prefix) {
        55 return path.join(prefix, 'Mozilla Firefox\\firefox.exe');
        56 });
        57 return io.exists(files[0]).then(function(exists) {
        58 return exists ? files[0] : io.exists(files[1]).then(function(exists) {
        59 return exists ? files[1] : null;
        60 });
        61 });
        62}
        63
        64
        65/**
        66 * Locates the Firefox binary for the current system.
        67 * @return {!promise.Promise.<string>} A promise for the located binary. The
        68 * promise will be rejected if Firefox cannot be located.
        69 */
        70function findFirefox() {
        71 if (foundBinary) {
        72 return foundBinary;
        73 }
        74
        75 if (process.platform === 'darwin') {
        76 var osxExe = '/Applications/Firefox.app/Contents/MacOS/firefox-bin';
        77 foundBinary = io.exists(osxExe).then(function(exists) {
        78 return exists ? osxExe : null;
        79 });
        80 } else if (process.platform === 'win32') {
        81 foundBinary = defaultWindowsLocation();
        82 } else {
        83 foundBinary = promise.fulfilled(io.findInPath('firefox'));
        84 }
        85
        86 return foundBinary = foundBinary.then(function(found) {
        87 if (found) {
        88 return found;
        89 }
        90 throw Error('Could not locate Firefox on the current system');
        91 });
        92}
        93
        94
        95/**
        96 * Copies the no focus libs into the given profile directory.
        97 * @param {string} profileDir Path to the profile directory to install into.
        98 * @return {!promise.Promise.<string>} The LD_LIBRARY_PATH prefix string to use
        99 * for the installed libs.
        100 */
        101function installNoFocusLibs(profileDir) {
        102 var x86 = path.join(profileDir, 'x86');
        103 var amd64 = path.join(profileDir, 'amd64');
        104
        105 return mkdir(x86)
        106 .then(copyLib.bind(null, NO_FOCUS_LIB_X86, x86))
        107 .then(mkdir.bind(null, amd64))
        108 .then(copyLib.bind(null, NO_FOCUS_LIB_AMD64, amd64))
        109 .then(function() {
        110 return x86 + ':' + amd64;
        111 });
        112
        113 function mkdir(dir) {
        114 return io.exists(dir).then(function(exists) {
        115 if (!exists) {
        116 return promise.checkedNodeCall(fs.mkdir, dir);
        117 }
        118 });
        119 }
        120
        121 function copyLib(src, dir) {
        122 return io.copy(src, path.join(dir, X_IGNORE_NO_FOCUS_LIB));
        123 }
        124}
        125
        126
        127/**
        128 * Silently runs Firefox to install a profile directory (which is assumed to be
        129 * defined in the given environment variables).
        130 * @param {string} firefox Path to the Firefox executable.
        131 * @param {!Object.<string, string>} env The environment variables to use.
        132 * @return {!promise.Promise} A promise for when the profile has been installed.
        133 */
        134function installProfile(firefox, env) {
        135 var installed = promise.defer();
        136 child.exec(firefox + ' -silent', {env: env, timeout: 180 * 1000},
        137 function(err) {
        138 if (err) {
        139 installed.reject(new Error(
        140 'Failed to install Firefox profile: ' + err));
        141 return;
        142 }
        143 installed.fulfill();
        144 });
        145 return installed.promise;
        146}
        147
        148
        149/**
        150 * Manages a Firefox subprocess configured for use with WebDriver.
        151 * @param {string=} opt_exe Path to the Firefox binary to use. If not
        152 * specified, will attempt to locate Firefox on the current system.
        153 * @constructor
        154 */
        155var Binary = function(opt_exe) {
        156 /** @private {(string|undefined)} */
        157 this.exe_ = opt_exe;
        158
        159 /** @private {!Array.<string>} */
        160 this.args_ = [];
        161
        162 /** @private {!Object.<string, string>} */
        163 this.env_ = {};
        164 Object.keys(process.env).forEach(function(key) {
        165 this.env_[key] = process.env[key];
        166 }.bind(this));
        167 this.env_['MOZ_CRASHREPORTER_DISABLE'] = '1';
        168 this.env_['MOZ_NO_REMOTE'] = '1';
        169 this.env_['NO_EM_RESTART'] = '1';
        170
        171 /** @private {promise.Promise.<!exec.Command>} */
        172 this.command_ = null;
        173};
        174
        175
        176/**
        177 * Add arguments to the command line used to start Firefox.
        178 * @param {...(string|!Array.<string>)} var_args Either the arguments to add as
        179 * varargs, or the arguments as an array.
        180 */
        181Binary.prototype.addArguments = function(var_args) {
        182 for (var i = 0; i < arguments.length; i++) {
        183 if (util.isArray(arguments[i])) {
        184 this.args_ = this.args_.concat(arguments[i]);
        185 } else {
        186 this.args_.push(arguments[i]);
        187 }
        188 }
        189};
        190
        191
        192/**
        193 * Launches Firefox and eturns a promise that will be fulfilled when the process
        194 * terminates.
        195 * @param {string} profile Path to the profile directory to use.
        196 * @return {!promise.Promise.<!exec.Result>} A promise for the process result.
        197 * @throws {Error} If this instance has already been started.
        198 */
        199Binary.prototype.launch = function(profile) {
        200 if (this.command_) {
        201 throw Error('Firefox is already running');
        202 }
        203
        204 var env = {};
        205 Object.keys(this.env_).forEach(function(key) {
        206 env[key] = this.env_[key];
        207 }.bind(this));
        208 env['XRE_PROFILE_PATH'] = profile;
        209
        210 var args = ['-foreground'].concat(this.args_);
        211
        212 var self = this;
        213
        214 this.command_ = promise.when(this.exe_ || findFirefox(), function(firefox) {
        215 if (process.platform === 'win32' || process.platform === 'darwin') {
        216 return firefox;
        217 }
        218 return installNoFocusLibs(profile).then(function(ldLibraryPath) {
        219 env['LD_LIBRARY_PATH'] = ldLibraryPath + ':' + env['LD_LIBRARY_PATH'];
        220 env['LD_PRELOAD'] = X_IGNORE_NO_FOCUS_LIB;
        221 return firefox;
        222 });
        223 }).then(function(firefox) {
        224 var install = exec(firefox, {args: ['-silent'], env: env});
        225 return install.result().then(function(result) {
        226 if (result.code !== 0) {
        227 throw Error(
        228 'Failed to install profile; firefox terminated with ' + result);
        229 }
        230
        231 return exec(firefox, {args: args, env: env});
        232 });
        233 });
        234
        235 return this.command_.then(function() {
        236 // Don't return the actual command handle, just a promise to signal it has
        237 // been started.
        238 });
        239};
        240
        241
        242/**
        243 * Kills the managed Firefox process.
        244 * @return {!promise.Promise} A promise for when the process has terminated.
        245 */
        246Binary.prototype.kill = function() {
        247 if (!this.command_) {
        248 return promise.defer(); // Not running.
        249 }
        250 return this.command_.then(function(command) {
        251 command.kill();
        252 return command.result();
        253 });
        254};
        255
        256
        257// PUBLIC API
        258
        259
        260exports.Binary = Binary;
        261
        \ No newline at end of file diff --git a/docs/api/javascript/source/firefox/extension.js.src.html b/docs/api/javascript/source/firefox/extension.js.src.html new file mode 100644 index 0000000000000..c2bc909a3e2eb --- /dev/null +++ b/docs/api/javascript/source/firefox/extension.js.src.html @@ -0,0 +1 @@ +extension.js

        firefox/extension.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/** @fileoverview Utilities for working with Firefox extensions. */
        17
        18'use strict';
        19
        20var AdmZip = require('adm-zip'),
        21 fs = require('fs'),
        22 path = require('path'),
        23 util = require('util'),
        24 xml = require('xml2js');
        25
        26var promise = require('..').promise,
        27 checkedCall = promise.checkedNodeCall,
        28 io = require('../io');
        29
        30
        31/**
        32 * Thrown when there an add-on is malformed.
        33 * @param {string} msg The error message.
        34 * @constructor
        35 * @extends {Error}
        36 */
        37function AddonFormatError(msg) {
        38 Error.call(this);
        39
        40 Error.captureStackTrace(this, AddonFormatError);
        41
        42 /** @override */
        43 this.name = AddonFormatError.name;
        44
        45 /** @override */
        46 this.message = msg;
        47}
        48util.inherits(AddonFormatError, Error);
        49
        50
        51
        52/**
        53 * Installs an extension to the given directory.
        54 * @param {string} extension Path to the extension to install, as either a xpi
        55 * file or a directory.
        56 * @param {string} dir Path to the directory to install the extension in.
        57 * @return {!promise.Promise.<string>} A promise for the add-on ID once
        58 * installed.
        59 */
        60function install(extension, dir) {
        61 return getDetails(extension).then(function(details) {
        62 function returnId() { return details.id; }
        63
        64 var dst = path.join(dir, details.id);
        65 if (extension.slice(-4) === '.xpi') {
        66 if (!details.unpack) {
        67 return io.copy(extension, dst + '.xpi').then(returnId);
        68 } else {
        69 return checkedCall(fs.readFile, extension).then(function(buff) {
        70 var zip = new AdmZip(buff);
        71 // TODO: find an async library for inflating a zip archive.
        72 new AdmZip(buff).extractAllTo(dst, true);
        73 }).then(returnId);
        74 }
        75 } else {
        76 return io.copyDir(extension, dst).then(returnId);
        77 }
        78 });
        79}
        80
        81
        82/**
        83 * Describes a Firefox add-on.
        84 * @typedef {{id: string, name: string, version: string, unpack: boolean}}
        85 */
        86var AddonDetails;
        87
        88
        89/**
        90 * Extracts the details needed to install an add-on.
        91 * @param {string} addonPath Path to the extension directory.
        92 * @return {!promise.Promise.<!AddonDetails>} A promise for the add-on details.
        93 */
        94function getDetails(addonPath) {
        95 return readManifest(addonPath).then(function(doc) {
        96 var em = getNamespaceId(doc, 'http://www.mozilla.org/2004/em-rdf#');
        97 var rdf = getNamespaceId(
        98 doc, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
        99
        100 var description = doc[rdf + 'RDF'][rdf + 'Description'][0];
        101 var details = {
        102 id: getNodeText(description, em + 'id'),
        103 name: getNodeText(description, em + 'name'),
        104 version: getNodeText(description, em + 'version'),
        105 unpack: getNodeText(description, em + 'unpack') || false
        106 };
        107
        108 if (typeof details.unpack === 'string') {
        109 details.unpack = details.unpack.toLowerCase() === 'true';
        110 }
        111
        112 if (!details.id) {
        113 throw new AddonFormatError('Could not find add-on ID for ' + addonPath);
        114 }
        115
        116 return details;
        117 });
        118
        119 function getNodeText(node, name) {
        120 return node[name] && node[name][0] || '';
        121 }
        122
        123 function getNamespaceId(doc, url) {
        124 var keys = Object.keys(doc);
        125 if (keys.length !== 1) {
        126 throw new AddonFormatError('Malformed manifest for add-on ' + addonPath);
        127 }
        128
        129 var namespaces = doc[keys[0]].$;
        130 var id = '';
        131 Object.keys(namespaces).some(function(ns) {
        132 if (namespaces[ns] !== url) {
        133 return false;
        134 }
        135
        136 if (ns.indexOf(':') != -1) {
        137 id = ns.split(':')[1] + ':';
        138 }
        139 return true;
        140 });
        141 return id;
        142 }
        143}
        144
        145
        146/**
        147 * Reads the manifest for a Firefox add-on.
        148 * @param {string} addonPath Path to a Firefox add-on as a xpi or an extension.
        149 * @return {!promise.Promise.<!Object>} A promise for the parsed manifest.
        150 */
        151function readManifest(addonPath) {
        152 var manifest;
        153
        154 if (addonPath.slice(-4) === '.xpi') {
        155 manifest = checkedCall(fs.readFile, addonPath).then(function(buff) {
        156 var zip = new AdmZip(buff);
        157 if (!zip.getEntry('install.rdf')) {
        158 throw new AddonFormatError(
        159 'Could not find install.rdf in ' + addonPath);
        160 }
        161 var done = promise.defer();
        162 zip.readAsTextAsync('install.rdf', done.fulfill);
        163 return done.promise;
        164 });
        165 } else {
        166 manifest = checkedCall(fs.stat, addonPath).then(function(stats) {
        167 if (!stats.isDirectory()) {
        168 throw Error(
        169 'Add-on path is niether a xpi nor a directory: ' + addonPath);
        170 }
        171 return checkedCall(fs.readFile, path.join(addonPath, 'install.rdf'));
        172 });
        173 }
        174
        175 return manifest.then(function(content) {
        176 return checkedCall(xml.parseString, content);
        177 });
        178}
        179
        180
        181// PUBLIC API
        182
        183
        184exports.install = install;
        \ No newline at end of file diff --git a/docs/api/javascript/source/firefox/index.js.src.html b/docs/api/javascript/source/firefox/index.js.src.html new file mode 100644 index 0000000000000..5a2037bca20a5 --- /dev/null +++ b/docs/api/javascript/source/firefox/index.js.src.html @@ -0,0 +1 @@ +index.js

        firefox/index.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 url = require('url'),
        19 util = require('util');
        20
        21var Binary = require('./binary').Binary,
        22 Profile = require('./profile').Profile,
        23 decodeProfile = require('./profile').decode,
        24 webdriver = require('..'),
        25 executors = require('../executors'),
        26 httpUtil = require('../http/util'),
        27 net = require('../net'),
        28 portprober = require('../net/portprober');
        29
        30
        31/**
        32 * Configuration options for the FirefoxDriver.
        33 * @constructor
        34 */
        35var Options = function() {
        36 /** @private {Profile} */
        37 this.profile_ = null;
        38
        39 /** @private {Binary} */
        40 this.binary_ = null;
        41
        42 /** @private {webdriver.logging.Preferences} */
        43 this.logPrefs_ = null;
        44
        45 /** @private {webdriver.ProxyConfig} */
        46 this.proxy_ = null;
        47};
        48
        49
        50/**
        51 * Sets the profile to use. The profile may be specified as a
        52 * {@link Profile} object or as the path to an existing Firefox profile to use
        53 * as a template.
        54 *
        55 * @param {(string|!Profile)} profile The profile to use.
        56 * @return {!Options} A self reference.
        57 */
        58Options.prototype.setProfile = function(profile) {
        59 if (typeof profile === 'string') {
        60 profile = new Profile(profile);
        61 }
        62 this.profile_ = profile;
        63 return this;
        64};
        65
        66
        67/**
        68 * Sets the binary to use. The binary may be specified as the path to a Firefox
        69 * executable, or as a {@link Binary} object.
        70 *
        71 * @param {(string|!Binary)} binary The binary to use.
        72 * @return {!Options} A self reference.
        73 */
        74Options.prototype.setBinary = function(binary) {
        75 if (typeof binary === 'string') {
        76 binary = new Binary(binary);
        77 }
        78 this.binary_ = binary;
        79 return this;
        80};
        81
        82
        83/**
        84 * Sets the logging preferences for the new session.
        85 * @param {webdriver.logging.Preferences} prefs The logging preferences.
        86 * @return {!Options} A self reference.
        87 */
        88Options.prototype.setLoggingPreferences = function(prefs) {
        89 this.logPrefs_ = prefs;
        90 return this;
        91};
        92
        93
        94/**
        95 * Sets the proxy to use.
        96 *
        97 * @param {webdriver.ProxyConfig} proxy The proxy configuration to use.
        98 * @return {!Options} A self reference.
        99 */
        100Options.prototype.setProxy = function(proxy) {
        101 this.proxy_ = proxy;
        102 return this;
        103};
        104
        105
        106/**
        107 * Converts these options to a {@link webdriver.Capabilities} instance.
        108 *
        109 * @return {!webdriver.Capabilities} A new capabilities object.
        110 */
        111Options.prototype.toCapabilities = function(opt_remote) {
        112 var caps = webdriver.Capabilities.firefox();
        113 if (this.logPrefs_) {
        114 caps.set(webdriver.Capability.LOGGING_PREFS, this.logPrefs_);
        115 }
        116 if (this.proxy_) {
        117 caps.set(webdriver.Capability.PROXY, this.proxy_);
        118 }
        119 if (this.binary_) {
        120 caps.set('firefox_binary', this.binary_);
        121 }
        122 if (this.profile_) {
        123 caps.set('firefox_profile', this.profile_);
        124 }
        125 return caps;
        126};
        127
        128
        129/**
        130 * A WebDriver client for Firefox.
        131 *
        132 * @param {(Options|webdriver.Capabilities|Object)=} opt_config The
        133 * configuration options for this driver, specified as either an
        134 * {@link Options} or {@link webdriver.Capabilities}, or as a raw hash
        135 * object.
        136 * @param {webdriver.promise.ControlFlow=} opt_flow The flow to
        137 * schedule commands through. Defaults to the active flow object.
        138 * @constructor
        139 * @extends {webdriver.WebDriver}
        140 */
        141var Driver = function(opt_config, opt_flow) {
        142 var caps;
        143 if (opt_config instanceof Options) {
        144 caps = opt_config.toCapabilities();
        145 } else {
        146 caps = new webdriver.Capabilities(opt_config);
        147 }
        148
        149 var binary = caps.get('firefox_binary') || new Binary();
        150 if (typeof binary === 'string') {
        151 binary = new Binary(binary);
        152 }
        153
        154 var profile = caps.get('firefox_profile') || new Profile();
        155
        156 caps.set('firefox_binary', null);
        157 caps.set('firefox_profile', null);
        158
        159 var serverUrl = portprober.findFreePort().then(function(port) {
        160 var prepareProfile;
        161 if (typeof profile === 'string') {
        162 prepareProfile = decodeProfile(profile).then(function(dir) {
        163 var profile = new Profile(dir);
        164 profile.setPreference('webdriver_firefox_port', port);
        165 return profile.writeToDisk();
        166 });
        167 } else {
        168 profile.setPreference('webdriver_firefox_port', port);
        169 prepareProfile = profile.writeToDisk();
        170 }
        171
        172 return prepareProfile.then(function(dir) {
        173 return binary.launch(dir);
        174 }).then(function() {
        175 var serverUrl = url.format({
        176 protocol: 'http',
        177 hostname: net.getLoopbackAddress(),
        178 port: port,
        179 pathname: '/hub'
        180 });
        181
        182 return httpUtil.waitForServer(serverUrl, 45 * 1000).then(function() {
        183 return serverUrl;
        184 });
        185 });
        186 });
        187
        188 var executor = executors.createExecutor(serverUrl);
        189 var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow);
        190
        191 webdriver.WebDriver.call(this, driver.getSession(), executor, opt_flow);
        192};
        193util.inherits(Driver, webdriver.WebDriver);
        194
        195
        196// PUBLIC API
        197
        198
        199exports.Binary = Binary;
        200exports.Driver = Driver;
        201exports.Options = Options;
        202exports.Profile = Profile;
        \ No newline at end of file diff --git a/docs/api/javascript/source/firefox/profile.js.src.html b/docs/api/javascript/source/firefox/profile.js.src.html new file mode 100644 index 0000000000000..bca8f4a0d74a2 --- /dev/null +++ b/docs/api/javascript/source/firefox/profile.js.src.html @@ -0,0 +1 @@ +profile.js

        firefox/profile.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 AdmZip = require('adm-zip'),
        19 fs = require('fs'),
        20 path = require('path'),
        21 vm = require('vm');
        22
        23var promise = require('..').promise,
        24 _base = require('../_base'),
        25 io = require('../io'),
        26 extension = require('./extension');
        27
        28
        29/** @const */
        30var WEBDRIVER_PREFERENCES_PATH = _base.isDevMode()
        31 ? path.join(__dirname, '../../../firefox-driver/webdriver.json')
        32 : path.join(__dirname, '../lib/firefox/webdriver.json');
        33
        34/** @const */
        35var WEBDRIVER_EXTENSION_PATH = _base.isDevMode()
        36 ? path.join(__dirname,
        37 '../../../../build/javascript/firefox-driver/webdriver.xpi')
        38 : path.join(__dirname, '../lib/firefox/webdriver.xpi');
        39
        40/** @const */
        41var WEBDRIVER_EXTENSION_NAME = 'fxdriver@googlecode.com';
        42
        43
        44
        45/** @type {Object} */
        46var defaultPreferences = null;
        47
        48/**
        49 * Synchronously loads the default preferences used for the FirefoxDriver.
        50 * @return {!Object} The default preferences JSON object.
        51 */
        52function getDefaultPreferences() {
        53 if (!defaultPreferences) {
        54 var contents = fs.readFileSync(WEBDRIVER_PREFERENCES_PATH, 'utf8');
        55 defaultPreferences = JSON.parse(contents);
        56 }
        57 return defaultPreferences;
        58}
        59
        60
        61/**
        62 * Parses a user.js file in a Firefox profile directory.
        63 * @param {string} f Path to the file to parse.
        64 * @return {!promise.Promise.<!Object>} A promise for the parsed preferences as
        65 * a JSON object. If the file does not exist, an empty object will be
        66 * returned.
        67 */
        68function loadUserPrefs(f) {
        69 var done = promise.defer();
        70 fs.readFile(f, function(err, contents) {
        71 if (err && err.code === 'ENOENT') {
        72 done.fulfill({});
        73 return;
        74 }
        75
        76 if (err) {
        77 done.reject(err);
        78 return;
        79 }
        80
        81 var prefs = {};
        82 var context = vm.createContext({
        83 'user_pref': function(key, value) {
        84 prefs[key] = value;
        85 }
        86 });
        87
        88 vm.runInContext(contents, context, f);
        89 done.fulfill(prefs);
        90 });
        91 return done.promise;
        92}
        93
        94
        95/**
        96 * Copies the properties of one object into another.
        97 * @param {!Object} a The destination object.
        98 * @param {!Object} b The source object to apply as a mixin.
        99 */
        100function mixin(a, b) {
        101 Object.keys(b).forEach(function(key) {
        102 a[key] = b[key];
        103 });
        104}
        105
        106
        107/**
        108 * @param {!Object} defaults The default preferences to write. Will be
        109 * overridden by user.js preferences in the template directory and the
        110 * frozen preferences required by WebDriver.
        111 * @param {string} dir Path to the directory write the file to.
        112 * @return {!promise.Promise.<string>} A promise for the profile directory,
        113 * to be fulfilled when user preferences have been written.
        114 */
        115function writeUserPrefs(prefs, dir) {
        116 var userPrefs = path.join(dir, 'user.js');
        117 return loadUserPrefs(userPrefs).then(function(overrides) {
        118 mixin(prefs, overrides);
        119 mixin(prefs, getDefaultPreferences()['frozen']);
        120
        121 var contents = Object.keys(prefs).map(function(key) {
        122 return 'user_pref(' + JSON.stringify(key) + ', ' +
        123 JSON.stringify(prefs[key]) + ');';
        124 }).join('\n');
        125
        126 var done = promise.defer();
        127 fs.writeFile(userPrefs, contents, function(err) {
        128 err && done.reject(err) || done.fulfill(dir);
        129 });
        130 return done.promise;
        131 });
        132};
        133
        134
        135/**
        136 * Installs a group of extensions in the given profile directory. If the
        137 * WebDriver extension is not included in this set, the default version
        138 * bundled with this package will be installed.
        139 * @param {!Array.<string>} extensions The extensions to install, as a
        140 * path to an unpacked extension directory or a path to a xpi file.
        141 * @param {string} dir The profile directory to install to.
        142 * @param {boolean=} opt_excludeWebDriverExt Whether to skip installation of
        143 * the default WebDriver extension.
        144 * @return {!promise.Promise.<string>} A promise for the main profile directory
        145 * once all extensions have been installed.
        146 */
        147function installExtensions(extensions, dir, opt_excludeWebDriverExt) {
        148 var hasWebDriver = !!opt_excludeWebDriverExt;
        149 var next = 0;
        150 var extensionDir = path.join(dir, 'extensions');
        151 var done = promise.defer();
        152
        153 return io.exists(extensionDir).then(function(exists) {
        154 if (!exists) {
        155 return promise.checkedNodeCall(fs.mkdir, extensionDir);
        156 }
        157 }).then(function() {
        158 installNext();
        159 return done.promise;
        160 });
        161
        162 function installNext() {
        163 if (!done.isPending()) {
        164 return;
        165 }
        166
        167 if (next >= extensions.length) {
        168 if (hasWebDriver) {
        169 done.fulfill(dir);
        170 } else {
        171 install(WEBDRIVER_EXTENSION_PATH);
        172 }
        173 } else {
        174 install(extensions[next++]);
        175 }
        176 }
        177
        178 function install(ext) {
        179 extension.install(ext, extensionDir).then(function(id) {
        180 hasWebDriver = hasWebDriver || (id === WEBDRIVER_EXTENSION_NAME);
        181 installNext();
        182 }, done.reject);
        183 }
        184}
        185
        186
        187/**
        188 * Decodes a base64 encoded profile.
        189 * @param {string} data The base64 encoded string.
        190 * @return {!promise.Promise.<string>} A promise for the path to the decoded
        191 * profile directory.
        192 */
        193function decode(data) {
        194 return io.tmpFile().then(function(file) {
        195 var buf = new Buffer(data, 'base64');
        196 return promise.checkedNodeCall(fs.writeFile, file, buf).then(function() {
        197 return io.tmpDir();
        198 }).then(function(dir) {
        199 var zip = new AdmZip(file);
        200 zip.extractAllTo(dir); // Sync only? Why?? :-(
        201 return dir;
        202 });
        203 });
        204}
        205
        206
        207
        208/**
        209 * Models a Firefox proifle directory for use with the FirefoxDriver. The
        210 * {@code Proifle} directory uses an in-memory model until {@link #writeToDisk}
        211 * is called.
        212 * @param {string=} opt_dir Path to an existing Firefox profile directory to
        213 * use a template for this profile. If not specified, a blank profile will
        214 * be used.
        215 * @constructor
        216 */
        217var Profile = function(opt_dir) {
        218 /** @private {!Object} */
        219 this.preferences_ = {};
        220
        221 mixin(this.preferences_, getDefaultPreferences()['mutable']);
        222 mixin(this.preferences_, getDefaultPreferences()['frozen']);
        223
        224 /** @private {boolean} */
        225 this.nativeEventsEnabled_ = true;
        226
        227 /** @private {(string|undefined)} */
        228 this.template_ = opt_dir;
        229
        230 /** @private {number} */
        231 this.port_ = 0;
        232
        233 /** @private {!Array.<string>} */
        234 this.extensions_ = [];
        235};
        236
        237
        238/**
        239 * Registers an extension to be included with this profile.
        240 * @param {string} extension Path to the extension to include, as either an
        241 * unpacked extension directory or the path to a xpi file.
        242 */
        243Profile.prototype.addExtension = function(extension) {
        244 this.extensions_.push(extension);
        245};
        246
        247
        248/**
        249 * Sets a desired preference for this profile.
        250 * @param {string} key The preference key.
        251 * @param {(string|number|boolean)} value The preference value.
        252 * @throws {Error} If attempting to set a frozen preference.
        253 */
        254Profile.prototype.setPreference = function(key, value) {
        255 var frozen = getDefaultPreferences()['frozen'];
        256 if (frozen.hasOwnProperty(key) && frozen[key] !== value) {
        257 throw Error('You may not set ' + key + '=' + JSON.stringify(value)
        258 + '; value is frozen for proper WebDriver functionality ('
        259 + key + '=' + JSON.stringify(frozen[key]) + ')');
        260 }
        261 this.preferences_[key] = value;
        262};
        263
        264
        265/**
        266 * Returns the currently configured value of a profile preference. This does
        267 * not include any defaults defined in the profile's template directory user.js
        268 * file (if a template were specified on construction).
        269 * @param {string} key The desired preference.
        270 * @return {(string|number|boolean|undefined)} The current value of the
        271 * requested preference.
        272 */
        273Profile.prototype.getPreference = function(key) {
        274 return this.preferences_[key];
        275};
        276
        277
        278/**
        279 * @return {number} The port this profile is currently configured to use, or
        280 * 0 if the port will be selected at random when the profile is written
        281 * to disk.
        282 */
        283Profile.prototype.getPort = function() {
        284 return this.port_;
        285};
        286
        287
        288/**
        289 * Sets the port to use for the WebDriver extension loaded by this profile.
        290 * @param {number} port The desired port, or 0 to use any free port.
        291 */
        292Profile.prototype.setPort = function(port) {
        293 this.port_ = port;
        294};
        295
        296
        297/**
        298 * @return {boolean} Whether the FirefoxDriver is configured to automatically
        299 * accept untrusted SSL certificates.
        300 */
        301Profile.prototype.acceptUntrustedCerts = function() {
        302 return !!this.preferences_['webdriver_accept_untrusted_certs'];
        303};
        304
        305
        306/**
        307 * Sets whether the FirefoxDriver should automatically accept untrusted SSL
        308 * certificates.
        309 * @param {boolean} value .
        310 */
        311Profile.prototype.setAcceptUntrustedCerts = function(value) {
        312 this.preferences_['webdriver_accept_untrusted_certs'] = !!value;
        313};
        314
        315
        316/**
        317 * Sets whether to assume untrusted certificates come from untrusted issuers.
        318 * @param {boolean} value .
        319 */
        320Profile.prototype.setAssumeUntrustedCertIssuer = function(value) {
        321 this.preferences_['webdriver_assume_untrusted_issuer'] = !!value;
        322};
        323
        324
        325/**
        326 * @return {boolean} Whether to assume untrusted certs come from untrusted
        327 * issuers.
        328 */
        329Profile.prototype.assumeUntrustedCertIssuer = function() {
        330 return !!this.preferences_['webdriver_assume_untrusted_issuer'];
        331};
        332
        333
        334/**
        335 * Sets whether to use native events with this profile.
        336 * @param {boolean} enabled .
        337 */
        338Profile.prototype.setNativeEventsEnabled = function(enabled) {
        339 this.nativeEventsEnabled_ = enabled;
        340};
        341
        342
        343/**
        344 * Returns whether native events are enabled in this profile.
        345 * @return {boolean} .
        346 */
        347Profile.prototype.nativeEventsEnabled = function() {
        348 return this.nativeEventsEnabled_;
        349};
        350
        351
        352/**
        353 * Writes this profile to disk.
        354 * @param {boolean=} opt_excludeWebDriverExt Whether to exclude the WebDriver
        355 * extension from the generated profile. Used to reduce the size of an
        356 * {@link #encode() encoded profile} since the server will always install
        357 * the extension itself.
        358 * @return {!promise.Promise.<string>} A promise for the path to the new
        359 * profile directory.
        360 */
        361Profile.prototype.writeToDisk = function(opt_excludeWebDriverExt) {
        362 var profileDir = io.tmpDir();
        363 if (this.template_) {
        364 profileDir = profileDir.then(function(dir) {
        365 return io.copyDir(
        366 this.template_, dir, /(parent\.lock|lock|\.parentlock)/);
        367 }.bind(this));
        368 }
        369
        370 // Freeze preferences for async operations.
        371 var prefs = {};
        372 mixin(prefs, this.preferences_);
        373
        374 // Freeze extensions for async operations.
        375 var extensions = this.extensions_.concat();
        376
        377 return profileDir.then(function(dir) {
        378 return writeUserPrefs(prefs, dir);
        379 }).then(function(dir) {
        380 return installExtensions(extensions, dir, !!opt_excludeWebDriverExt);
        381 });
        382};
        383
        384
        385/**
        386 * Encodes this profile as a zipped, base64 encoded directory.
        387 * @return {!promise.Promise.<string>} A promise for the encoded profile.
        388 */
        389Profile.prototype.encode = function() {
        390 return this.writeToDisk(true).then(function(dir) {
        391 var zip = new AdmZip();
        392 zip.addLocalFolder(dir, '');
        393 return io.tmpFile().then(function(file) {
        394 zip.writeZip(file); // Sync! Why oh why :-(
        395 return promise.checkedNodeCall(fs.readFile, file);
        396 });
        397 }).then(function(data) {
        398 return new Buffer(data).toString('base64');
        399 });
        400};
        401
        402
        403// PUBLIC API
        404
        405
        406exports.Profile = Profile;
        407exports.decode = decode;
        408exports.loadUserPrefs = loadUserPrefs;
        \ No newline at end of file diff --git a/docs/api/javascript/source/http/index.js.src.html b/docs/api/javascript/source/http/index.js.src.html index 7e08abed313fc..1e60a93915df4 100644 --- a/docs/api/javascript/source/http/index.js.src.html +++ b/docs/api/javascript/source/http/index.js.src.html @@ -1 +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 +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 * @param {http.Agent=} opt_agent The agent to use for each request.
        32 * Defaults to {@code http.globalAgent}.
        33 * @constructor
        34 * @implements {webdriver.http.Client}
        35 */
        36var HttpClient = function(serverUrl, opt_agent) {
        37 var parsedUrl = url.parse(serverUrl);
        38 if (!parsedUrl.hostname) {
        39 throw new Error('Invalid server URL: ' + serverUrl);
        40 }
        41
        42 /** @private {http.Agent} */
        43 this.agent_ = opt_agent;
        44
        45 /**
        46 * Base options for each request.
        47 * @private {!Object}
        48 */
        49 this.options_ = {
        50 host: parsedUrl.hostname,
        51 path: parsedUrl.pathname,
        52 port: parsedUrl.port
        53 };
        54};
        55
        56
        57/** @override */
        58HttpClient.prototype.send = function(httpRequest, callback) {
        59 var data;
        60 httpRequest.headers['Content-Length'] = 0;
        61 if (httpRequest.method == 'POST' || httpRequest.method == 'PUT') {
        62 data = JSON.stringify(httpRequest.data);
        63 httpRequest.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');
        64 httpRequest.headers['Content-Type'] = 'application/json;charset=UTF-8';
        65 }
        66
        67 var path = this.options_.path;
        68 if (path[path.length - 1] === '/' && httpRequest.path[0] === '/') {
        69 path += httpRequest.path.substring(1);
        70 } else {
        71 path += httpRequest.path;
        72 }
        73
        74 var options = {
        75 method: httpRequest.method,
        76 host: this.options_.host,
        77 port: this.options_.port,
        78 path: path,
        79 headers: httpRequest.headers
        80 };
        81 if (this.agent_) {
        82 options.agent = this.agent_;
        83 }
        84 sendRequest(options, callback, data);
        85};
        86
        87
        88/**
        89 * Sends a single HTTP request.
        90 * @param {!Object} options The request options.
        91 * @param {function(Error, !webdriver.http.Response=)} callback The function to
        92 * invoke with the server's response.
        93 * @param {string=} opt_data The data to send with the request.
        94 */
        95var sendRequest = function(options, callback, opt_data) {
        96 var request = http.request(options, function(response) {
        97 if (response.statusCode == 302 || response.statusCode == 303) {
        98 try {
        99 var location = url.parse(response.headers['location']);
        100 } catch (ex) {
        101 callback(Error(
        102 'Failed to parse "Location" header for server redirect: ' +
        103 ex.message + '\nResponse was: \n' +
        104 new HttpResponse(response.statusCode, response.headers, '')));
        105 return;
        106 }
        107
        108 if (!location.hostname) {
        109 location.hostname = options.host;
        110 location.port = options.port;
        111 }
        112
        113 request.abort();
        114 sendRequest({
        115 method: 'GET',
        116 host: location.hostname,
        117 path: location.pathname + (location.search || ''),
        118 port: location.port,
        119 headers: {
        120 'Accept': 'application/json; charset=utf-8'
        121 }
        122 }, callback);
        123 return;
        124 }
        125
        126 var body = [];
        127 response.on('data', body.push.bind(body));
        128 response.on('end', function() {
        129 var resp = new HttpResponse(response.statusCode,
        130 response.headers, body.join('').replace(/\0/g, ''));
        131 callback(null, resp);
        132 });
        133 });
        134
        135 request.on('error', function(e) {
        136 if (e.code === 'ECONNRESET') {
        137 setTimeout(function() {
        138 sendRequest(options, callback, opt_data);
        139 }, 15);
        140 } else {
        141 var message = e.message;
        142 if (e.code) {
        143 message = e.code + ' ' + message;
        144 }
        145 callback(new Error(message));
        146 }
        147 });
        148
        149 if (opt_data) {
        150 request.write(opt_data);
        151 }
        152
        153 request.end();
        154};
        155
        156
        157// PUBLIC API
        158
        159/** @type {webdriver.http.Executor.} */
        160exports.Executor = base.require('webdriver.http.Executor');
        161
        162/** @type {webdriver.http.Request.} */
        163exports.Request = base.require('webdriver.http.Request');
        164
        165/** @type {webdriver.http.Response.} */
        166exports.Response = base.require('webdriver.http.Response');
        167
        168exports.HttpClient = HttpClient;
        \ No newline at end of file diff --git a/docs/api/javascript/source/http/util.js.src.html b/docs/api/javascript/source/http/util.js.src.html index f4b49152155ba..908cc313f7dc7 100644 --- a/docs/api/javascript/source/http/util.js.src.html +++ b/docs/api/javascript/source/http/util.js.src.html @@ -1 +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 +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/docs/api/javascript/source/index.js.src.html b/docs/api/javascript/source/index.js.src.html index b4cc5c65788c2..fea47afa1ae20 100644 --- a/docs/api/javascript/source/index.js.src.html +++ b/docs/api/javascript/source/index.js.src.html @@ -1 +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 +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/** @type {function(new: webdriver.WebElementPromise)} */
        68exports.WebElementPromise = base.require('webdriver.WebElementPromise');
        69
        70
        71// Export the remainder of our API through getters to keep things cleaner
        72// when this module is used in a REPL environment.
        73
        74
        75/** @type {webdriver.Browser.} */
        76(exports.__defineGetter__('Browser', function() {
        77 return base.require('webdriver.Browser');
        78}));
        79
        80
        81/** @type {webdriver.Button.} */
        82(exports.__defineGetter__('Button', function() {
        83 return base.require('webdriver.Button');
        84}));
        85
        86
        87/** @type {webdriver.Capability.} */
        88(exports.__defineGetter__('Capability', function() {
        89 return base.require('webdriver.Capability');
        90}));
        91
        92
        93/** @type {webdriver.CommandName.} */
        94(exports.__defineGetter__('CommandName', function() {
        95 return base.require('webdriver.CommandName');
        96}));
        97
        98
        99/** @type {webdriver.Key.} */
        100(exports.__defineGetter__('Key', function() {
        101 return base.require('webdriver.Key');
        102}));
        103
        104
        105/** @type {error.} */
        106(exports.__defineGetter__('error', function() {
        107 return error;
        108}));
        109
        110
        111/** @type {error.} */
        112(exports.__defineGetter__('error', function() {
        113 return error;
        114}));
        115
        116
        117/** @type {webdriver.logging.} */
        118(exports.__defineGetter__('logging', function() {
        119 return base.exportPublicApi('webdriver.logging');
        120}));
        121
        122
        123/** @type {webdriver.promise.} */
        124(exports.__defineGetter__('promise', function() {
        125 return base.exportPublicApi('webdriver.promise');
        126}));
        127
        128
        129/** @type {webdriver.stacktrace.} */
        130(exports.__defineGetter__('stacktrace', function() {
        131 return base.exportPublicApi('webdriver.stacktrace');
        132}));
        \ No newline at end of file diff --git a/docs/api/javascript/source/io/exec.js.src.html b/docs/api/javascript/source/io/exec.js.src.html new file mode 100644 index 0000000000000..3e08cb036f339 --- /dev/null +++ b/docs/api/javascript/source/io/exec.js.src.html @@ -0,0 +1 @@ +exec.js

        io/exec.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 childProcess = require('child_process');
        19
        20var promise = require('..').promise;
        21
        22
        23/**
        24 * A hash with configuration options for an executed command.
        25 * <ul>
        26 * <li>
        27 * <li>{@code args} - Command line arguments.
        28 * <li>{@code env} - Command environment; will inherit from the current process
        29 * if missing.
        30 * <li>{@code stdio} - IO configuration for the spawned server process. For
        31 * more information, refer to the documentation of
        32 * {@code child_process.spawn}.
        33 * </ul>
        34 *
        35 * @typedef {{
        36 * args: (!Array.<string>|undefined),
        37 * env: (!Object.<string, string>|undefined),
        38 * stdio: (string|!Array.<string|number|!Stream|null|undefined>|undefined)
        39 * }}
        40 */
        41var Options;
        42
        43
        44/**
        45 * Describes a command's termination conditions.
        46 * @param {?number} code The exit code, or {@code null} if the command did not
        47 * exit normally.
        48 * @param {?string} signal The signal used to kill the command, or
        49 * {@code null}.
        50 * @constructor
        51 */
        52var Result = function(code, signal) {
        53 /** @type {?number} */
        54 this.code = code;
        55
        56 /** @type {?string} */
        57 this.signal = signal;
        58};
        59
        60
        61/** @override */
        62Result.prototype.toString = function() {
        63 return 'Result(code=' + this.code + ', signal=' + this.signal + ')';
        64};
        65
        66
        67
        68/**
        69 * Represents a command running in a sub-process.
        70 * @param {!promise.Promise.<!Result>} result The command result.
        71 * @constructor
        72 */
        73var Command = function(result, onKill) {
        74 /** @return {boolean} Whether this command is still running. */
        75 this.isRunning = function() {
        76 return result.isPending();
        77 };
        78
        79 /**
        80 * @return {!promise.Promise.<!Result>} A promise for the result of this
        81 * command.
        82 */
        83 this.result = function() {
        84 return result;
        85 };
        86
        87 /**
        88 * Sends a signal to the underlying process.
        89 * @param {string=} opt_signal The signal to send; defaults to
        90 * {@code SIGTERM}.
        91 */
        92 this.kill = function(opt_signal) {
        93 onKill(opt_signal || 'SIGTERM');
        94 };
        95};
        96
        97
        98// PUBLIC API
        99
        100
        101/**
        102 * Spawns a child process. The returned {@link Command} may be used to wait
        103 * for the process result or to send signals to the process.
        104 *
        105 * @param {string} command The executable to spawn.
        106 * @param {Options=} opt_options The command options.
        107 * @return {!Command} The launched command.
        108 */
        109module.exports = function(command, opt_options) {
        110 var options = opt_options || {};
        111
        112 var proc = childProcess.spawn(command, options.args || [], {
        113 env: options.env || process.env,
        114 stdio: options.stdio || 'ignore'
        115 }).once('exit', onExit);
        116
        117 // This process should not wait on the spawned child, however, we do
        118 // want to ensure the child is killed when this process exits.
        119 proc.unref();
        120 process.once('exit', killCommand);
        121
        122 var result = promise.defer();
        123 var cmd = new Command(result.promise, function(signal) {
        124 if (!result.isPending() || !proc) {
        125 return; // No longer running.
        126 }
        127 proc.kill(signal);
        128 });
        129 return cmd;
        130
        131 function onExit(code, signal) {
        132 proc = null;
        133 process.removeListener('exit', killCommand);
        134 result.fulfill(new Result(code, signal));
        135 }
        136
        137 function killCommand() {
        138 process.removeListener('exit', killCommand);
        139 proc && proc.kill('SIGTERM');
        140 }
        141};
        \ No newline at end of file diff --git a/docs/api/javascript/source/io/index.js.src.html b/docs/api/javascript/source/io/index.js.src.html index 0a18b2b2c1cc0..4f563e8485c05 100644 --- a/docs/api/javascript/source/io/index.js.src.html +++ b/docs/api/javascript/source/io/index.js.src.html @@ -1 +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 +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 tmp = require('tmp');
        19
        20var promise = require('..').promise;
        21
        22
        23var PATH_SEPARATOR = process.platform === 'win32' ? ';' : ':';
        24
        25
        26// PUBLIC API
        27
        28
        29
        30/**
        31 * Copies one file to another.
        32 * @param {string} src The source file.
        33 * @param {string} dst The destination file.
        34 * @return {!promise.Promise.<string>} A promise for the copied file's path.
        35 */
        36exports.copy = function(src, dst) {
        37 var copied = promise.defer();
        38
        39 var rs = fs.createReadStream(src);
        40 rs.on('error', copied.reject);
        41 rs.on('end', function() {
        42 copied.fulfill(dst);
        43 });
        44
        45 var ws = fs.createWriteStream(dst);
        46 ws.on('error', copied.reject);
        47
        48 rs.pipe(ws);
        49
        50 return copied.promise;
        51};
        52
        53
        54/**
        55 * Recursively copies the contents of one directory to another.
        56 * @param {string} src The source directory to copy.
        57 * @param {string} dst The directory to copy into.
        58 * @param {(RegEx|function(string): boolean)=} opt_exclude An exclusion filter
        59 * as either a regex or predicate function. All files matching this filter
        60 * will not be copied.
        61 * @return {!promise.Promise.<string>} A promise for the destination
        62 * directory's path once all files have been copied.
        63 */
        64exports.copyDir = function(src, dst, opt_exclude) {
        65 var predicate = opt_exclude;
        66 if (opt_exclude && typeof opt_exclude !== 'function') {
        67 predicate = function(p) {
        68 return !opt_exclude.test(p);
        69 };
        70 }
        71
        72 // TODO(jleyba): Make this function completely async.
        73 if (!fs.existsSync(dst)) {
        74 fs.mkdirSync(dst);
        75 }
        76
        77 var files = fs.readdirSync(src);
        78 files = files.map(function(file) {
        79 return path.join(src, file);
        80 });
        81
        82 if (predicate) {
        83 files = files.filter(predicate);
        84 }
        85
        86 var results = [];
        87 files.forEach(function(file) {
        88 var stats = fs.statSync(file);
        89 var target = path.join(dst, path.basename(file));
        90
        91 if (stats.isDirectory()) {
        92 if (!fs.existsSync(target)) {
        93 fs.mkdirSync(target, stats.mode);
        94 }
        95 results.push(exports.copyDir(file, target, predicate));
        96 } else {
        97 results.push(exports.copy(file, target));
        98 }
        99 });
        100
        101 return promise.all(results).then(function() {
        102 return dst;
        103 });
        104};
        105
        106
        107/**
        108 * Tests if a file path exists.
        109 * @param {string} path The path to test.
        110 * @return {!promise.Promise.<boolean>} A promise for whether the file exists.
        111 */
        112exports.exists = function(path) {
        113 var result = promise.defer();
        114 fs.exists(path, result.fulfill);
        115 return result.promise;
        116};
        117
        118
        119/**
        120 * @return {!promise.Promise.<string>} A promise for the path to a temporary
        121 * directory.
        122 * @see https://www.npmjs.org/package/tmp
        123 */
        124exports.tmpDir = function() {
        125 return promise.checkedNodeCall(tmp.dir);
        126};
        127
        128
        129/**
        130 * @return {!promise.Promise.<string>} A promise for the path to a temporary
        131 * file.
        132 * @see https://www.npmjs.org/package/tmp
        133 */
        134exports.tmpFile = function() {
        135 return promise.checkedNodeCall(tmp.file);
        136};
        137
        138
        139/**
        140 * Searches the {@code PATH} environment variable for the given file.
        141 * @param {string} file The file to locate on the PATH.
        142 * @param {boolean=} opt_checkCwd Whether to always start with the search with
        143 * the current working directory, regardless of whether it is explicitly
        144 * listed on the PATH.
        145 * @return {?string} Path to the located file, or {@code null} if it could
        146 * not be found.
        147 */
        148exports.findInPath = function(file, opt_checkCwd) {
        149 if (opt_checkCwd) {
        150 var tmp = path.join(process.cwd(), file);
        151 if (fs.existsSync(tmp)) {
        152 return tmp;
        153 }
        154 }
        155
        156 var dirs = process.env['PATH'].split(PATH_SEPARATOR);
        157 var found = null;
        158 dirs.forEach(function(dir) {
        159 var tmp = path.join(dir, file);
        160 if (!found && fs.existsSync(tmp)) {
        161 found = tmp;
        162 }
        163 });
        164 return found;
        165};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/atoms/error.js.src.html b/docs/api/javascript/source/lib/atoms/error.js.src.html index b9696c30bc969..c9d443ed81bcf 100644 --- a/docs/api/javascript/source/lib/atoms/error.js.src.html +++ b/docs/api/javascript/source/lib/atoms/error.js.src.html @@ -1 +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 +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 /** @deprecated */
        50 MODAL_DIALOG_OPENED: 26,
        51 UNEXPECTED_ALERT_OPEN: 26,
        52 NO_SUCH_ALERT: 27,
        53 /** @deprecated */
        54 NO_MODAL_DIALOG_OPEN: 27,
        55 SCRIPT_TIMEOUT: 28,
        56 INVALID_ELEMENT_COORDINATES: 29,
        57 IME_NOT_AVAILABLE: 30,
        58 IME_ENGINE_ACTIVATION_FAILED: 31,
        59 INVALID_SELECTOR_ERROR: 32,
        60 SESSION_NOT_CREATED: 33,
        61 MOVE_TARGET_OUT_OF_BOUNDS: 34,
        62 SQL_DATABASE_ERROR: 35,
        63 INVALID_XPATH_SELECTOR: 51,
        64 INVALID_XPATH_SELECTOR_RETURN_TYPE: 52,
        65 // The following error codes are derived straight from HTTP return codes.
        66 METHOD_NOT_ALLOWED: 405
        67};
        68
        69
        70
        71/**
        72 * Error extension that includes error status codes from the WebDriver wire
        73 * protocol:
        74 * http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes
        75 *
        76 * @param {!bot.ErrorCode} code The error's status code.
        77 * @param {string=} opt_message Optional error message.
        78 * @constructor
        79 * @extends {Error}
        80 */
        81bot.Error = function(code, opt_message) {
        82
        83 /**
        84 * This error's status code.
        85 * @type {!bot.ErrorCode}
        86 */
        87 this.code = code;
        88
        89 /** @type {string} */
        90 this.state =
        91 bot.Error.CODE_TO_STATE_[code] || bot.Error.State.UNKNOWN_ERROR;
        92
        93 /** @override */
        94 this.message = opt_message || '';
        95
        96 var name = this.state.replace(/((?:^|\s+)[a-z])/g, function(str) {
        97 // IE<9 does not support String#trim(). Also, IE does not include 0xa0
        98 // (the non-breaking-space) in the \s character class, so we have to
        99 // explicitly include it.
        100 return str.toUpperCase().replace(/^[\s\xa0]+/g, '');
        101 });
        102
        103 var l = name.length - 'Error'.length;
        104 if (l < 0 || name.indexOf('Error', l) != l) {
        105 name += 'Error';
        106 }
        107
        108 /** @override */
        109 this.name = name;
        110
        111 // Generate a stacktrace for our custom error; ensure the error has our
        112 // custom name and message so the stack prints correctly in all browsers.
        113 var template = new Error(this.message);
        114 template.name = this.name;
        115
        116 /** @override */
        117 this.stack = template.stack || '';
        118};
        119goog.inherits(bot.Error, Error);
        120
        121
        122/**
        123 * Status strings enumerated in the W3C WebDriver working draft.
        124 * @enum {string}
        125 * @see http://www.w3.org/TR/webdriver/#status-codes
        126 */
        127bot.Error.State = {
        128 ELEMENT_NOT_SELECTABLE: 'element not selectable',
        129 ELEMENT_NOT_VISIBLE: 'element not visible',
        130 IME_ENGINE_ACTIVATION_FAILED: 'ime engine activation failed',
        131 IME_NOT_AVAILABLE: 'ime not available',
        132 INVALID_COOKIE_DOMAIN: 'invalid cookie domain',
        133 INVALID_ELEMENT_COORDINATES: 'invalid element coordinates',
        134 INVALID_ELEMENT_STATE: 'invalid element state',
        135 INVALID_SELECTOR: 'invalid selector',
        136 JAVASCRIPT_ERROR: 'javascript error',
        137 MOVE_TARGET_OUT_OF_BOUNDS: 'move target out of bounds',
        138 NO_SUCH_ALERT: 'no such alert',
        139 NO_SUCH_DOM: 'no such dom',
        140 NO_SUCH_ELEMENT: 'no such element',
        141 NO_SUCH_FRAME: 'no such frame',
        142 NO_SUCH_WINDOW: 'no such window',
        143 SCRIPT_TIMEOUT: 'script timeout',
        144 SESSION_NOT_CREATED: 'session not created',
        145 STALE_ELEMENT_REFERENCE: 'stale element reference',
        146 SUCCESS: 'success',
        147 TIMEOUT: 'timeout',
        148 UNABLE_TO_SET_COOKIE: 'unable to set cookie',
        149 UNEXPECTED_ALERT_OPEN: 'unexpected alert open',
        150 UNKNOWN_COMMAND: 'unknown command',
        151 UNKNOWN_ERROR: 'unknown error',
        152 UNSUPPORTED_OPERATION: 'unsupported operation'
        153};
        154
        155
        156/**
        157 * A map of error codes to state string.
        158 * @private {!Object.<bot.ErrorCode, bot.Error.State>}
        159 */
        160bot.Error.CODE_TO_STATE_ = {};
        161goog.scope(function() {
        162 var map = bot.Error.CODE_TO_STATE_;
        163 var code = bot.ErrorCode;
        164 var state = bot.Error.State;
        165
        166 map[code.ELEMENT_NOT_SELECTABLE] = state.ELEMENT_NOT_SELECTABLE;
        167 map[code.ELEMENT_NOT_VISIBLE] = state.ELEMENT_NOT_VISIBLE;
        168 map[code.IME_ENGINE_ACTIVATION_FAILED] = state.IME_ENGINE_ACTIVATION_FAILED;
        169 map[code.IME_NOT_AVAILABLE] = state.IME_NOT_AVAILABLE;
        170 map[code.INVALID_COOKIE_DOMAIN] = state.INVALID_COOKIE_DOMAIN;
        171 map[code.INVALID_ELEMENT_COORDINATES] = state.INVALID_ELEMENT_COORDINATES;
        172 map[code.INVALID_ELEMENT_STATE] = state.INVALID_ELEMENT_STATE;
        173 map[code.INVALID_SELECTOR_ERROR] = state.INVALID_SELECTOR;
        174 map[code.INVALID_XPATH_SELECTOR] = state.INVALID_SELECTOR;
        175 map[code.INVALID_XPATH_SELECTOR_RETURN_TYPE] = state.INVALID_SELECTOR;
        176 map[code.JAVASCRIPT_ERROR] = state.JAVASCRIPT_ERROR;
        177 map[code.METHOD_NOT_ALLOWED] = state.UNSUPPORTED_OPERATION;
        178 map[code.MOVE_TARGET_OUT_OF_BOUNDS] = state.MOVE_TARGET_OUT_OF_BOUNDS;
        179 map[code.NO_MODAL_DIALOG_OPEN] = state.NO_SUCH_ALERT;
        180 map[code.NO_SUCH_ALERT] = state.NO_SUCH_ALERT;
        181 map[code.NO_SUCH_ELEMENT] = state.NO_SUCH_ELEMENT;
        182 map[code.NO_SUCH_FRAME] = state.NO_SUCH_FRAME;
        183 map[code.NO_SUCH_WINDOW] = state.NO_SUCH_WINDOW;
        184 map[code.SCRIPT_TIMEOUT] = state.SCRIPT_TIMEOUT;
        185 map[code.SESSION_NOT_CREATED] = state.SESSION_NOT_CREATED;
        186 map[code.STALE_ELEMENT_REFERENCE] = state.STALE_ELEMENT_REFERENCE;
        187 map[code.SUCCESS] = state.SUCCESS;
        188 map[code.TIMEOUT] = state.TIMEOUT;
        189 map[code.UNABLE_TO_SET_COOKIE] = state.UNABLE_TO_SET_COOKIE;
        190 map[code.MODAL_DIALOG_OPENED] = state.UNEXPECTED_ALERT_OPEN;
        191 map[code.UNEXPECTED_ALERT_OPEN] = state.UNEXPECTED_ALERT_OPEN
        192 map[code.UNKNOWN_ERROR] = state.UNKNOWN_ERROR;
        193 map[code.UNSUPPORTED_OPERATION] = state.UNKNOWN_COMMAND;
        194}); // goog.scope
        195
        196
        197/**
        198 * Flag used for duck-typing when this code is embedded in a Firefox extension.
        199 * This is required since an Error thrown in one component and then reported
        200 * to another will fail instanceof checks in the second component.
        201 * @type {boolean}
        202 */
        203bot.Error.prototype.isAutomationError = true;
        204
        205
        206if (goog.DEBUG) {
        207 /** @return {string} The string representation of this error. */
        208 bot.Error.prototype.toString = function() {
        209 return this.name + ': ' + this.message;
        210 };
        211}
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/atoms/json.js.src.html b/docs/api/javascript/source/lib/atoms/json.js.src.html index a585c2f532c9f..d69afe4001a62 100644 --- a/docs/api/javascript/source/lib/atoms/json.js.src.html +++ b/docs/api/javascript/source/lib/atoms/json.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/atoms/response.js.src.html b/docs/api/javascript/source/lib/atoms/response.js.src.html index 4a2bb7c35d9d9..231d73a1409f5 100644 --- a/docs/api/javascript/source/lib/atoms/response.js.src.html +++ b/docs/api/javascript/source/lib/atoms/response.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/atoms/userAgent.js.src.html b/docs/api/javascript/source/lib/atoms/userAgent.js.src.html index 9eed02c1b75af..451a8766e75f5 100644 --- a/docs/api/javascript/source/lib/atoms/userAgent.js.src.html +++ b/docs/api/javascript/source/lib/atoms/userAgent.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/array/array.js.src.html b/docs/api/javascript/source/lib/goog/array/array.js.src.html index 78af612cbff3a..5dc3b2699b3ac 100644 --- a/docs/api/javascript/source/lib/goog/array/array.js.src.html +++ b/docs/api/javascript/source/lib/goog/array/array.js.src.html @@ -1 +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 +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 * Removes all values that satisfy the given condition.
        749 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array
        750 * like object over which to iterate.
        751 * @param {?function(this:S, T, number, ?) : boolean} f The function to call
        752 * for every element. This function
        753 * takes 3 arguments (the element, the index and the array) and should
        754 * return a boolean.
        755 * @param {S=} opt_obj An optional "this" context for the function.
        756 * @return {number} The number of items removed
        757 * @template T,S
        758 */
        759goog.array.removeAllIf = function(arr, f, opt_obj) {
        760 var removedCount = 0;
        761 goog.array.forEachRight(arr, function(val, index) {
        762 if (f.call(opt_obj, val, index, arr)) {
        763 if (goog.array.removeAt(arr, index)) {
        764 removedCount++;
        765 }
        766 }
        767 });
        768 return removedCount;
        769};
        770
        771
        772/**
        773 * Returns a new array that is the result of joining the arguments. If arrays
        774 * are passed then their items are added, however, if non-arrays are passed they
        775 * will be added to the return array as is.
        776 *
        777 * Note that ArrayLike objects will be added as is, rather than having their
        778 * items added.
        779 *
        780 * goog.array.concat([1, 2], [3, 4]) -> [1, 2, 3, 4]
        781 * goog.array.concat(0, [1, 2]) -> [0, 1, 2]
        782 * goog.array.concat([1, 2], null) -> [1, 2, null]
        783 *
        784 * There is bug in all current versions of IE (6, 7 and 8) where arrays created
        785 * in an iframe become corrupted soon (not immediately) after the iframe is
        786 * destroyed. This is common if loading data via goog.net.IframeIo, for example.
        787 * This corruption only affects the concat method which will start throwing
        788 * Catastrophic Errors (#-2147418113).
        789 *
        790 * See http://endoflow.com/scratch/corrupted-arrays.html for a test case.
        791 *
        792 * Internally goog.array should use this, so that all methods will continue to
        793 * work on these broken array objects.
        794 *
        795 * @param {...*} var_args Items to concatenate. Arrays will have each item
        796 * added, while primitives and objects will be added as is.
        797 * @return {!Array} The new resultant array.
        798 */
        799goog.array.concat = function(var_args) {
        800 return goog.array.ARRAY_PROTOTYPE_.concat.apply(
        801 goog.array.ARRAY_PROTOTYPE_, arguments);
        802};
        803
        804
        805/**
        806 * Returns a new array that contains the contents of all the arrays passed.
        807 * @param {...!Array.<T>} var_args
        808 * @return {!Array.<T>}
        809 * @template T
        810 */
        811goog.array.join = function(var_args) {
        812 return goog.array.ARRAY_PROTOTYPE_.concat.apply(
        813 goog.array.ARRAY_PROTOTYPE_, arguments);
        814};
        815
        816
        817/**
        818 * Converts an object to an array.
        819 * @param {Array.<T>|goog.array.ArrayLike} object The object to convert to an
        820 * array.
        821 * @return {!Array.<T>} The object converted into an array. If object has a
        822 * length property, every property indexed with a non-negative number
        823 * less than length will be included in the result. If object does not
        824 * have a length property, an empty array will be returned.
        825 * @template T
        826 */
        827goog.array.toArray = function(object) {
        828 var length = object.length;
        829
        830 // If length is not a number the following it false. This case is kept for
        831 // backwards compatibility since there are callers that pass objects that are
        832 // not array like.
        833 if (length > 0) {
        834 var rv = new Array(length);
        835 for (var i = 0; i < length; i++) {
        836 rv[i] = object[i];
        837 }
        838 return rv;
        839 }
        840 return [];
        841};
        842
        843
        844/**
        845 * Does a shallow copy of an array.
        846 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array-like object to
        847 * clone.
        848 * @return {!Array.<T>} Clone of the input array.
        849 * @template T
        850 */
        851goog.array.clone = goog.array.toArray;
        852
        853
        854/**
        855 * Extends an array with another array, element, or "array like" object.
        856 * This function operates 'in-place', it does not create a new Array.
        857 *
        858 * Example:
        859 * var a = [];
        860 * goog.array.extend(a, [0, 1]);
        861 * a; // [0, 1]
        862 * goog.array.extend(a, 2);
        863 * a; // [0, 1, 2]
        864 *
        865 * @param {Array.<VALUE>} arr1 The array to modify.
        866 * @param {...(Array.<VALUE>|VALUE)} var_args The elements or arrays of elements
        867 * to add to arr1.
        868 * @template VALUE
        869 */
        870goog.array.extend = function(arr1, var_args) {
        871 for (var i = 1; i < arguments.length; i++) {
        872 var arr2 = arguments[i];
        873 // If we have an Array or an Arguments object we can just call push
        874 // directly.
        875 var isArrayLike;
        876 if (goog.isArray(arr2) ||
        877 // Detect Arguments. ES5 says that the [[Class]] of an Arguments object
        878 // is "Arguments" but only V8 and JSC/Safari gets this right. We instead
        879 // detect Arguments by checking for array like and presence of "callee".
        880 (isArrayLike = goog.isArrayLike(arr2)) &&
        881 // The getter for callee throws an exception in strict mode
        882 // according to section 10.6 in ES5 so check for presence instead.
        883 Object.prototype.hasOwnProperty.call(arr2, 'callee')) {
        884 arr1.push.apply(arr1, arr2);
        885 } else if (isArrayLike) {
        886 // Otherwise loop over arr2 to prevent copying the object.
        887 var len1 = arr1.length;
        888 var len2 = arr2.length;
        889 for (var j = 0; j < len2; j++) {
        890 arr1[len1 + j] = arr2[j];
        891 }
        892 } else {
        893 arr1.push(arr2);
        894 }
        895 }
        896};
        897
        898
        899/**
        900 * Adds or removes elements from an array. This is a generic version of Array
        901 * splice. This means that it might work on other objects similar to arrays,
        902 * such as the arguments object.
        903 *
        904 * @param {Array.<T>|goog.array.ArrayLike} arr The array to modify.
        905 * @param {number|undefined} index The index at which to start changing the
        906 * array. If not defined, treated as 0.
        907 * @param {number} howMany How many elements to remove (0 means no removal. A
        908 * value below 0 is treated as zero and so is any other non number. Numbers
        909 * are floored).
        910 * @param {...T} var_args Optional, additional elements to insert into the
        911 * array.
        912 * @return {!Array.<T>} the removed elements.
        913 * @template T
        914 */
        915goog.array.splice = function(arr, index, howMany, var_args) {
        916 goog.asserts.assert(arr.length != null);
        917
        918 return goog.array.ARRAY_PROTOTYPE_.splice.apply(
        919 arr, goog.array.slice(arguments, 1));
        920};
        921
        922
        923/**
        924 * Returns a new array from a segment of an array. This is a generic version of
        925 * Array slice. This means that it might work on other objects similar to
        926 * arrays, such as the arguments object.
        927 *
        928 * @param {Array.<T>|goog.array.ArrayLike} arr The array from
        929 * which to copy a segment.
        930 * @param {number} start The index of the first element to copy.
        931 * @param {number=} opt_end The index after the last element to copy.
        932 * @return {!Array.<T>} A new array containing the specified segment of the
        933 * original array.
        934 * @template T
        935 */
        936goog.array.slice = function(arr, start, opt_end) {
        937 goog.asserts.assert(arr.length != null);
        938
        939 // passing 1 arg to slice is not the same as passing 2 where the second is
        940 // null or undefined (in that case the second argument is treated as 0).
        941 // we could use slice on the arguments object and then use apply instead of
        942 // testing the length
        943 if (arguments.length <= 2) {
        944 return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start);
        945 } else {
        946 return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start, opt_end);
        947 }
        948};
        949
        950
        951/**
        952 * Removes all duplicates from an array (retaining only the first
        953 * occurrence of each array element). This function modifies the
        954 * array in place and doesn't change the order of the non-duplicate items.
        955 *
        956 * For objects, duplicates are identified as having the same unique ID as
        957 * defined by {@link goog.getUid}.
        958 *
        959 * Alternatively you can specify a custom hash function that returns a unique
        960 * value for each item in the array it should consider unique.
        961 *
        962 * Runtime: N,
        963 * Worstcase space: 2N (no dupes)
        964 *
        965 * @param {Array.<T>|goog.array.ArrayLike} arr The array from which to remove
        966 * duplicates.
        967 * @param {Array=} opt_rv An optional array in which to return the results,
        968 * instead of performing the removal inplace. If specified, the original
        969 * array will remain unchanged.
        970 * @param {function(T):string=} opt_hashFn An optional function to use to
        971 * apply to every item in the array. This function should return a unique
        972 * value for each item in the array it should consider unique.
        973 * @template T
        974 */
        975goog.array.removeDuplicates = function(arr, opt_rv, opt_hashFn) {
        976 var returnArray = opt_rv || arr;
        977 var defaultHashFn = function(item) {
        978 // Prefix each type with a single character representing the type to
        979 // prevent conflicting keys (e.g. true and 'true').
        980 return goog.isObject(current) ? 'o' + goog.getUid(current) :
        981 (typeof current).charAt(0) + current;
        982 };
        983 var hashFn = opt_hashFn || defaultHashFn;
        984
        985 var seen = {}, cursorInsert = 0, cursorRead = 0;
        986 while (cursorRead < arr.length) {
        987 var current = arr[cursorRead++];
        988 var key = hashFn(current);
        989 if (!Object.prototype.hasOwnProperty.call(seen, key)) {
        990 seen[key] = true;
        991 returnArray[cursorInsert++] = current;
        992 }
        993 }
        994 returnArray.length = cursorInsert;
        995};
        996
        997
        998/**
        999 * Searches the specified array for the specified target using the binary
        1000 * search algorithm. If no opt_compareFn is specified, elements are compared
        1001 * using <code>goog.array.defaultCompare</code>, which compares the elements
        1002 * using the built in < and > operators. This will produce the expected
        1003 * behavior for homogeneous arrays of String(s) and Number(s). The array
        1004 * specified <b>must</b> be sorted in ascending order (as defined by the
        1005 * comparison function). If the array is not sorted, results are undefined.
        1006 * If the array contains multiple instances of the specified target value, any
        1007 * of these instances may be found.
        1008 *
        1009 * Runtime: O(log n)
        1010 *
        1011 * @param {Array.<VALUE>|goog.array.ArrayLike} arr The array to be searched.
        1012 * @param {TARGET} target The sought value.
        1013 * @param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison
        1014 * function by which the array is ordered. Should take 2 arguments to
        1015 * compare, and return a negative number, zero, or a positive number
        1016 * depending on whether the first argument is less than, equal to, or
        1017 * greater than the second.
        1018 * @return {number} Lowest index of the target value if found, otherwise
        1019 * (-(insertion point) - 1). The insertion point is where the value should
        1020 * be inserted into arr to preserve the sorted property. Return value >= 0
        1021 * iff target is found.
        1022 * @template TARGET, VALUE
        1023 */
        1024goog.array.binarySearch = function(arr, target, opt_compareFn) {
        1025 return goog.array.binarySearch_(arr,
        1026 opt_compareFn || goog.array.defaultCompare, false /* isEvaluator */,
        1027 target);
        1028};
        1029
        1030
        1031/**
        1032 * Selects an index in the specified array using the binary search algorithm.
        1033 * The evaluator receives an element and determines whether the desired index
        1034 * is before, at, or after it. The evaluator must be consistent (formally,
        1035 * goog.array.map(goog.array.map(arr, evaluator, opt_obj), goog.math.sign)
        1036 * must be monotonically non-increasing).
        1037 *
        1038 * Runtime: O(log n)
        1039 *
        1040 * @param {Array.<VALUE>|goog.array.ArrayLike} arr The array to be searched.
        1041 * @param {function(this:THIS, VALUE, number, ?): number} evaluator
        1042 * Evaluator function that receives 3 arguments (the element, the index and
        1043 * the array). Should return a negative number, zero, or a positive number
        1044 * depending on whether the desired index is before, at, or after the
        1045 * element passed to it.
        1046 * @param {THIS=} opt_obj The object to be used as the value of 'this'
        1047 * within evaluator.
        1048 * @return {number} Index of the leftmost element matched by the evaluator, if
        1049 * such exists; otherwise (-(insertion point) - 1). The insertion point is
        1050 * the index of the first element for which the evaluator returns negative,
        1051 * or arr.length if no such element exists. The return value is non-negative
        1052 * iff a match is found.
        1053 * @template THIS, VALUE
        1054 */
        1055goog.array.binarySelect = function(arr, evaluator, opt_obj) {
        1056 return goog.array.binarySearch_(arr, evaluator, true /* isEvaluator */,
        1057 undefined /* opt_target */, opt_obj);
        1058};
        1059
        1060
        1061/**
        1062 * Implementation of a binary search algorithm which knows how to use both
        1063 * comparison functions and evaluators. If an evaluator is provided, will call
        1064 * the evaluator with the given optional data object, conforming to the
        1065 * interface defined in binarySelect. Otherwise, if a comparison function is
        1066 * provided, will call the comparison function against the given data object.
        1067 *
        1068 * This implementation purposefully does not use goog.bind or goog.partial for
        1069 * performance reasons.
        1070 *
        1071 * Runtime: O(log n)
        1072 *
        1073 * @param {Array.<VALUE>|goog.array.ArrayLike} arr The array to be searched.
        1074 * @param {function(TARGET, VALUE): number|
        1075 * function(this:THIS, VALUE, number, ?): number} compareFn Either an
        1076 * evaluator or a comparison function, as defined by binarySearch
        1077 * and binarySelect above.
        1078 * @param {boolean} isEvaluator Whether the function is an evaluator or a
        1079 * comparison function.
        1080 * @param {TARGET=} opt_target If the function is a comparison function, then
        1081 * this is the target to binary search for.
        1082 * @param {THIS=} opt_selfObj If the function is an evaluator, this is an
        1083 * optional this object for the evaluator.
        1084 * @return {number} Lowest index of the target value if found, otherwise
        1085 * (-(insertion point) - 1). The insertion point is where the value should
        1086 * be inserted into arr to preserve the sorted property. Return value >= 0
        1087 * iff target is found.
        1088 * @template THIS, VALUE, TARGET
        1089 * @private
        1090 */
        1091goog.array.binarySearch_ = function(arr, compareFn, isEvaluator, opt_target,
        1092 opt_selfObj) {
        1093 var left = 0; // inclusive
        1094 var right = arr.length; // exclusive
        1095 var found;
        1096 while (left < right) {
        1097 var middle = (left + right) >> 1;
        1098 var compareResult;
        1099 if (isEvaluator) {
        1100 compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);
        1101 } else {
        1102 compareResult = compareFn(opt_target, arr[middle]);
        1103 }
        1104 if (compareResult > 0) {
        1105 left = middle + 1;
        1106 } else {
        1107 right = middle;
        1108 // We are looking for the lowest index so we can't return immediately.
        1109 found = !compareResult;
        1110 }
        1111 }
        1112 // left is the index if found, or the insertion point otherwise.
        1113 // ~left is a shorthand for -left - 1.
        1114 return found ? left : ~left;
        1115};
        1116
        1117
        1118/**
        1119 * Sorts the specified array into ascending order. If no opt_compareFn is
        1120 * specified, elements are compared using
        1121 * <code>goog.array.defaultCompare</code>, which compares the elements using
        1122 * the built in < and > operators. This will produce the expected behavior
        1123 * for homogeneous arrays of String(s) and Number(s), unlike the native sort,
        1124 * but will give unpredictable results for heterogenous lists of strings and
        1125 * numbers with different numbers of digits.
        1126 *
        1127 * This sort is not guaranteed to be stable.
        1128 *
        1129 * Runtime: Same as <code>Array.prototype.sort</code>
        1130 *
        1131 * @param {Array.<T>} arr The array to be sorted.
        1132 * @param {?function(T,T):number=} opt_compareFn Optional comparison
        1133 * function by which the
        1134 * array is to be ordered. Should take 2 arguments to compare, and return a
        1135 * negative number, zero, or a positive number depending on whether the
        1136 * first argument is less than, equal to, or greater than the second.
        1137 * @template T
        1138 */
        1139goog.array.sort = function(arr, opt_compareFn) {
        1140 // TODO(arv): Update type annotation since null is not accepted.
        1141 arr.sort(opt_compareFn || goog.array.defaultCompare);
        1142};
        1143
        1144
        1145/**
        1146 * Sorts the specified array into ascending order in a stable way. If no
        1147 * opt_compareFn is specified, elements are compared using
        1148 * <code>goog.array.defaultCompare</code>, which compares the elements using
        1149 * the built in < and > operators. This will produce the expected behavior
        1150 * for homogeneous arrays of String(s) and Number(s).
        1151 *
        1152 * Runtime: Same as <code>Array.prototype.sort</code>, plus an additional
        1153 * O(n) overhead of copying the array twice.
        1154 *
        1155 * @param {Array.<T>} arr The array to be sorted.
        1156 * @param {?function(T, T): number=} opt_compareFn Optional comparison function
        1157 * by which the array is to be ordered. Should take 2 arguments to compare,
        1158 * and return a negative number, zero, or a positive number depending on
        1159 * whether the first argument is less than, equal to, or greater than the
        1160 * second.
        1161 * @template T
        1162 */
        1163goog.array.stableSort = function(arr, opt_compareFn) {
        1164 for (var i = 0; i < arr.length; i++) {
        1165 arr[i] = {index: i, value: arr[i]};
        1166 }
        1167 var valueCompareFn = opt_compareFn || goog.array.defaultCompare;
        1168 function stableCompareFn(obj1, obj2) {
        1169 return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;
        1170 };
        1171 goog.array.sort(arr, stableCompareFn);
        1172 for (var i = 0; i < arr.length; i++) {
        1173 arr[i] = arr[i].value;
        1174 }
        1175};
        1176
        1177
        1178/**
        1179 * Sorts an array of objects by the specified object key and compare
        1180 * function. If no compare function is provided, the key values are
        1181 * compared in ascending order using <code>goog.array.defaultCompare</code>.
        1182 * This won't work for keys that get renamed by the compiler. So use
        1183 * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.
        1184 * @param {Array.<Object>} arr An array of objects to sort.
        1185 * @param {string} key The object key to sort by.
        1186 * @param {Function=} opt_compareFn The function to use to compare key
        1187 * values.
        1188 */
        1189goog.array.sortObjectsByKey = function(arr, key, opt_compareFn) {
        1190 var compare = opt_compareFn || goog.array.defaultCompare;
        1191 goog.array.sort(arr, function(a, b) {
        1192 return compare(a[key], b[key]);
        1193 });
        1194};
        1195
        1196
        1197/**
        1198 * Tells if the array is sorted.
        1199 * @param {!Array.<T>} arr The array.
        1200 * @param {?function(T,T):number=} opt_compareFn Function to compare the
        1201 * array elements.
        1202 * Should take 2 arguments to compare, and return a negative number, zero,
        1203 * or a positive number depending on whether the first argument is less
        1204 * than, equal to, or greater than the second.
        1205 * @param {boolean=} opt_strict If true no equal elements are allowed.
        1206 * @return {boolean} Whether the array is sorted.
        1207 * @template T
        1208 */
        1209goog.array.isSorted = function(arr, opt_compareFn, opt_strict) {
        1210 var compare = opt_compareFn || goog.array.defaultCompare;
        1211 for (var i = 1; i < arr.length; i++) {
        1212 var compareResult = compare(arr[i - 1], arr[i]);
        1213 if (compareResult > 0 || compareResult == 0 && opt_strict) {
        1214 return false;
        1215 }
        1216 }
        1217 return true;
        1218};
        1219
        1220
        1221/**
        1222 * Compares two arrays for equality. Two arrays are considered equal if they
        1223 * have the same length and their corresponding elements are equal according to
        1224 * the comparison function.
        1225 *
        1226 * @param {goog.array.ArrayLike} arr1 The first array to compare.
        1227 * @param {goog.array.ArrayLike} arr2 The second array to compare.
        1228 * @param {Function=} opt_equalsFn Optional comparison function.
        1229 * Should take 2 arguments to compare, and return true if the arguments
        1230 * are equal. Defaults to {@link goog.array.defaultCompareEquality} which
        1231 * compares the elements using the built-in '===' operator.
        1232 * @return {boolean} Whether the two arrays are equal.
        1233 */
        1234goog.array.equals = function(arr1, arr2, opt_equalsFn) {
        1235 if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||
        1236 arr1.length != arr2.length) {
        1237 return false;
        1238 }
        1239 var l = arr1.length;
        1240 var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality;
        1241 for (var i = 0; i < l; i++) {
        1242 if (!equalsFn(arr1[i], arr2[i])) {
        1243 return false;
        1244 }
        1245 }
        1246 return true;
        1247};
        1248
        1249
        1250/**
        1251 * 3-way array compare function.
        1252 * @param {!Array.<VALUE>|!goog.array.ArrayLike} arr1 The first array to
        1253 * compare.
        1254 * @param {!Array.<VALUE>|!goog.array.ArrayLike} arr2 The second array to
        1255 * compare.
        1256 * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison
        1257 * function by which the array is to be ordered. Should take 2 arguments to
        1258 * compare, and return a negative number, zero, or a positive number
        1259 * depending on whether the first argument is less than, equal to, or
        1260 * greater than the second.
        1261 * @return {number} Negative number, zero, or a positive number depending on
        1262 * whether the first argument is less than, equal to, or greater than the
        1263 * second.
        1264 * @template VALUE
        1265 */
        1266goog.array.compare3 = function(arr1, arr2, opt_compareFn) {
        1267 var compare = opt_compareFn || goog.array.defaultCompare;
        1268 var l = Math.min(arr1.length, arr2.length);
        1269 for (var i = 0; i < l; i++) {
        1270 var result = compare(arr1[i], arr2[i]);
        1271 if (result != 0) {
        1272 return result;
        1273 }
        1274 }
        1275 return goog.array.defaultCompare(arr1.length, arr2.length);
        1276};
        1277
        1278
        1279/**
        1280 * Compares its two arguments for order, using the built in < and >
        1281 * operators.
        1282 * @param {VALUE} a The first object to be compared.
        1283 * @param {VALUE} b The second object to be compared.
        1284 * @return {number} A negative number, zero, or a positive number as the first
        1285 * argument is less than, equal to, or greater than the second.
        1286 * @template VALUE
        1287 */
        1288goog.array.defaultCompare = function(a, b) {
        1289 return a > b ? 1 : a < b ? -1 : 0;
        1290};
        1291
        1292
        1293/**
        1294 * Compares its two arguments for equality, using the built in === operator.
        1295 * @param {*} a The first object to compare.
        1296 * @param {*} b The second object to compare.
        1297 * @return {boolean} True if the two arguments are equal, false otherwise.
        1298 */
        1299goog.array.defaultCompareEquality = function(a, b) {
        1300 return a === b;
        1301};
        1302
        1303
        1304/**
        1305 * Inserts a value into a sorted array. The array is not modified if the
        1306 * value is already present.
        1307 * @param {Array.<VALUE>|goog.array.ArrayLike} array The array to modify.
        1308 * @param {VALUE} value The object to insert.
        1309 * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison
        1310 * function by which the array is ordered. Should take 2 arguments to
        1311 * compare, and return a negative number, zero, or a positive number
        1312 * depending on whether the first argument is less than, equal to, or
        1313 * greater than the second.
        1314 * @return {boolean} True if an element was inserted.
        1315 * @template VALUE
        1316 */
        1317goog.array.binaryInsert = function(array, value, opt_compareFn) {
        1318 var index = goog.array.binarySearch(array, value, opt_compareFn);
        1319 if (index < 0) {
        1320 goog.array.insertAt(array, value, -(index + 1));
        1321 return true;
        1322 }
        1323 return false;
        1324};
        1325
        1326
        1327/**
        1328 * Removes a value from a sorted array.
        1329 * @param {!Array.<VALUE>|!goog.array.ArrayLike} array The array to modify.
        1330 * @param {VALUE} value The object to remove.
        1331 * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison
        1332 * function by which the array is ordered. Should take 2 arguments to
        1333 * compare, and return a negative number, zero, or a positive number
        1334 * depending on whether the first argument is less than, equal to, or
        1335 * greater than the second.
        1336 * @return {boolean} True if an element was removed.
        1337 * @template VALUE
        1338 */
        1339goog.array.binaryRemove = function(array, value, opt_compareFn) {
        1340 var index = goog.array.binarySearch(array, value, opt_compareFn);
        1341 return (index >= 0) ? goog.array.removeAt(array, index) : false;
        1342};
        1343
        1344
        1345/**
        1346 * Splits an array into disjoint buckets according to a splitting function.
        1347 * @param {Array.<T>} array The array.
        1348 * @param {function(this:S, T,number,Array.<T>):?} sorter Function to call for
        1349 * every element. This takes 3 arguments (the element, the index and the
        1350 * array) and must return a valid object key (a string, number, etc), or
        1351 * undefined, if that object should not be placed in a bucket.
        1352 * @param {S=} opt_obj The object to be used as the value of 'this' within
        1353 * sorter.
        1354 * @return {!Object} An object, with keys being all of the unique return values
        1355 * of sorter, and values being arrays containing the items for
        1356 * which the splitter returned that key.
        1357 * @template T,S
        1358 */
        1359goog.array.bucket = function(array, sorter, opt_obj) {
        1360 var buckets = {};
        1361
        1362 for (var i = 0; i < array.length; i++) {
        1363 var value = array[i];
        1364 var key = sorter.call(opt_obj, value, i, array);
        1365 if (goog.isDef(key)) {
        1366 // Push the value to the right bucket, creating it if necessary.
        1367 var bucket = buckets[key] || (buckets[key] = []);
        1368 bucket.push(value);
        1369 }
        1370 }
        1371
        1372 return buckets;
        1373};
        1374
        1375
        1376/**
        1377 * Creates a new object built from the provided array and the key-generation
        1378 * function.
        1379 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array like object over
        1380 * which to iterate whose elements will be the values in the new object.
        1381 * @param {?function(this:S, T, number, ?) : string} keyFunc The function to
        1382 * call for every element. This function takes 3 arguments (the element, the
        1383 * index and the array) and should return a string that will be used as the
        1384 * key for the element in the new object. If the function returns the same
        1385 * key for more than one element, the value for that key is
        1386 * implementation-defined.
        1387 * @param {S=} opt_obj The object to be used as the value of 'this'
        1388 * within keyFunc.
        1389 * @return {!Object.<T>} The new object.
        1390 * @template T,S
        1391 */
        1392goog.array.toObject = function(arr, keyFunc, opt_obj) {
        1393 var ret = {};
        1394 goog.array.forEach(arr, function(element, index) {
        1395 ret[keyFunc.call(opt_obj, element, index, arr)] = element;
        1396 });
        1397 return ret;
        1398};
        1399
        1400
        1401/**
        1402 * Creates a range of numbers in an arithmetic progression.
        1403 *
        1404 * Range takes 1, 2, or 3 arguments:
        1405 * <pre>
        1406 * range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]
        1407 * range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]
        1408 * range(-2, -5, -1) produces [-2, -3, -4]
        1409 * range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.
        1410 * </pre>
        1411 *
        1412 * @param {number} startOrEnd The starting value of the range if an end argument
        1413 * is provided. Otherwise, the start value is 0, and this is the end value.
        1414 * @param {number=} opt_end The optional end value of the range.
        1415 * @param {number=} opt_step The step size between range values. Defaults to 1
        1416 * if opt_step is undefined or 0.
        1417 * @return {!Array.<number>} An array of numbers for the requested range. May be
        1418 * an empty array if adding the step would not converge toward the end
        1419 * value.
        1420 */
        1421goog.array.range = function(startOrEnd, opt_end, opt_step) {
        1422 var array = [];
        1423 var start = 0;
        1424 var end = startOrEnd;
        1425 var step = opt_step || 1;
        1426 if (opt_end !== undefined) {
        1427 start = startOrEnd;
        1428 end = opt_end;
        1429 }
        1430
        1431 if (step * (end - start) < 0) {
        1432 // Sign mismatch: start + step will never reach the end value.
        1433 return [];
        1434 }
        1435
        1436 if (step > 0) {
        1437 for (var i = start; i < end; i += step) {
        1438 array.push(i);
        1439 }
        1440 } else {
        1441 for (var i = start; i > end; i += step) {
        1442 array.push(i);
        1443 }
        1444 }
        1445 return array;
        1446};
        1447
        1448
        1449/**
        1450 * Returns an array consisting of the given value repeated N times.
        1451 *
        1452 * @param {VALUE} value The value to repeat.
        1453 * @param {number} n The repeat count.
        1454 * @return {!Array.<VALUE>} An array with the repeated value.
        1455 * @template VALUE
        1456 */
        1457goog.array.repeat = function(value, n) {
        1458 var array = [];
        1459 for (var i = 0; i < n; i++) {
        1460 array[i] = value;
        1461 }
        1462 return array;
        1463};
        1464
        1465
        1466/**
        1467 * Returns an array consisting of every argument with all arrays
        1468 * expanded in-place recursively.
        1469 *
        1470 * @param {...*} var_args The values to flatten.
        1471 * @return {!Array} An array containing the flattened values.
        1472 */
        1473goog.array.flatten = function(var_args) {
        1474 var result = [];
        1475 for (var i = 0; i < arguments.length; i++) {
        1476 var element = arguments[i];
        1477 if (goog.isArray(element)) {
        1478 result.push.apply(result, goog.array.flatten.apply(null, element));
        1479 } else {
        1480 result.push(element);
        1481 }
        1482 }
        1483 return result;
        1484};
        1485
        1486
        1487/**
        1488 * Rotates an array in-place. After calling this method, the element at
        1489 * index i will be the element previously at index (i - n) %
        1490 * array.length, for all values of i between 0 and array.length - 1,
        1491 * inclusive.
        1492 *
        1493 * For example, suppose list comprises [t, a, n, k, s]. After invoking
        1494 * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].
        1495 *
        1496 * @param {!Array.<T>} array The array to rotate.
        1497 * @param {number} n The amount to rotate.
        1498 * @return {!Array.<T>} The array.
        1499 * @template T
        1500 */
        1501goog.array.rotate = function(array, n) {
        1502 goog.asserts.assert(array.length != null);
        1503
        1504 if (array.length) {
        1505 n %= array.length;
        1506 if (n > 0) {
        1507 goog.array.ARRAY_PROTOTYPE_.unshift.apply(array, array.splice(-n, n));
        1508 } else if (n < 0) {
        1509 goog.array.ARRAY_PROTOTYPE_.push.apply(array, array.splice(0, -n));
        1510 }
        1511 }
        1512 return array;
        1513};
        1514
        1515
        1516/**
        1517 * Moves one item of an array to a new position keeping the order of the rest
        1518 * of the items. Example use case: keeping a list of JavaScript objects
        1519 * synchronized with the corresponding list of DOM elements after one of the
        1520 * elements has been dragged to a new position.
        1521 * @param {!(Array|Arguments|{length:number})} arr The array to modify.
        1522 * @param {number} fromIndex Index of the item to move between 0 and
        1523 * {@code arr.length - 1}.
        1524 * @param {number} toIndex Target index between 0 and {@code arr.length - 1}.
        1525 */
        1526goog.array.moveItem = function(arr, fromIndex, toIndex) {
        1527 goog.asserts.assert(fromIndex >= 0 && fromIndex < arr.length);
        1528 goog.asserts.assert(toIndex >= 0 && toIndex < arr.length);
        1529 // Remove 1 item at fromIndex.
        1530 var removedItems = goog.array.ARRAY_PROTOTYPE_.splice.call(arr, fromIndex, 1);
        1531 // Insert the removed item at toIndex.
        1532 goog.array.ARRAY_PROTOTYPE_.splice.call(arr, toIndex, 0, removedItems[0]);
        1533 // We don't use goog.array.insertAt and goog.array.removeAt, because they're
        1534 // significantly slower than splice.
        1535};
        1536
        1537
        1538/**
        1539 * Creates a new array for which the element at position i is an array of the
        1540 * ith element of the provided arrays. The returned array will only be as long
        1541 * as the shortest array provided; additional values are ignored. For example,
        1542 * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]].
        1543 *
        1544 * This is similar to the zip() function in Python. See {@link
        1545 * http://docs.python.org/library/functions.html#zip}
        1546 *
        1547 * @param {...!goog.array.ArrayLike} var_args Arrays to be combined.
        1548 * @return {!Array.<!Array>} A new array of arrays created from provided arrays.
        1549 */
        1550goog.array.zip = function(var_args) {
        1551 if (!arguments.length) {
        1552 return [];
        1553 }
        1554 var result = [];
        1555 for (var i = 0; true; i++) {
        1556 var value = [];
        1557 for (var j = 0; j < arguments.length; j++) {
        1558 var arr = arguments[j];
        1559 // If i is larger than the array length, this is the shortest array.
        1560 if (i >= arr.length) {
        1561 return result;
        1562 }
        1563 value.push(arr[i]);
        1564 }
        1565 result.push(value);
        1566 }
        1567};
        1568
        1569
        1570/**
        1571 * Shuffles the values in the specified array using the Fisher-Yates in-place
        1572 * shuffle (also known as the Knuth Shuffle). By default, calls Math.random()
        1573 * and so resets the state of that random number generator. Similarly, may reset
        1574 * the state of the any other specified random number generator.
        1575 *
        1576 * Runtime: O(n)
        1577 *
        1578 * @param {!Array} arr The array to be shuffled.
        1579 * @param {function():number=} opt_randFn Optional random function to use for
        1580 * shuffling.
        1581 * Takes no arguments, and returns a random number on the interval [0, 1).
        1582 * Defaults to Math.random() using JavaScript's built-in Math library.
        1583 */
        1584goog.array.shuffle = function(arr, opt_randFn) {
        1585 var randFn = opt_randFn || Math.random;
        1586
        1587 for (var i = arr.length - 1; i > 0; i--) {
        1588 // Choose a random array index in [0, i] (inclusive with i).
        1589 var j = Math.floor(randFn() * (i + 1));
        1590
        1591 var tmp = arr[i];
        1592 arr[i] = arr[j];
        1593 arr[j] = tmp;
        1594 }
        1595};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/asserts/asserts.js.src.html b/docs/api/javascript/source/lib/goog/asserts/asserts.js.src.html index 32fc68ed50fbe..23b87ed28643a 100644 --- a/docs/api/javascript/source/lib/goog/asserts/asserts.js.src.html +++ b/docs/api/javascript/source/lib/goog/asserts/asserts.js.src.html @@ -1 +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 +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 * The default error handler.
        82 * @param {!goog.asserts.AssertionError} e The exception to be handled.
        83 */
        84goog.asserts.DEFAULT_ERROR_HANDLER = function(e) { throw e; };
        85
        86
        87/**
        88 * The handler responsible for throwing or logging assertion errors.
        89 * @private {function(!goog.asserts.AssertionError)}
        90 */
        91goog.asserts.errorHandler_ = goog.asserts.DEFAULT_ERROR_HANDLER;
        92
        93
        94/**
        95 * Throws an exception with the given message and "Assertion failed" prefixed
        96 * onto it.
        97 * @param {string} defaultMessage The message to use if givenMessage is empty.
        98 * @param {Array.<*>} defaultArgs The substitution arguments for defaultMessage.
        99 * @param {string|undefined} givenMessage Message supplied by the caller.
        100 * @param {Array.<*>} givenArgs The substitution arguments for givenMessage.
        101 * @throws {goog.asserts.AssertionError} When the value is not a number.
        102 * @private
        103 */
        104goog.asserts.doAssertFailure_ =
        105 function(defaultMessage, defaultArgs, givenMessage, givenArgs) {
        106 var message = 'Assertion failed';
        107 if (givenMessage) {
        108 message += ': ' + givenMessage;
        109 var args = givenArgs;
        110 } else if (defaultMessage) {
        111 message += ': ' + defaultMessage;
        112 args = defaultArgs;
        113 }
        114 // The '' + works around an Opera 10 bug in the unit tests. Without it,
        115 // a stack trace is added to var message above. With this, a stack trace is
        116 // not added until this line (it causes the extra garbage to be added after
        117 // the assertion message instead of in the middle of it).
        118 var e = new goog.asserts.AssertionError('' + message, args || []);
        119 goog.asserts.errorHandler_(e);
        120};
        121
        122
        123/**
        124 * Sets a custom error handler that can be used to customize the behavior of
        125 * assertion failures, for example by turning all assertion failures into log
        126 * messages.
        127 * @param {function(goog.asserts.AssertionError)} errorHandler
        128 */
        129goog.asserts.setErrorHandler = function(errorHandler) {
        130 if (goog.asserts.ENABLE_ASSERTS) {
        131 goog.asserts.errorHandler_ = errorHandler;
        132 }
        133};
        134
        135
        136/**
        137 * Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is
        138 * true.
        139 * @template T
        140 * @param {T} condition The condition to check.
        141 * @param {string=} opt_message Error message in case of failure.
        142 * @param {...*} var_args The items to substitute into the failure message.
        143 * @return {T} The value of the condition.
        144 * @throws {goog.asserts.AssertionError} When the condition evaluates to false.
        145 */
        146goog.asserts.assert = function(condition, opt_message, var_args) {
        147 if (goog.asserts.ENABLE_ASSERTS && !condition) {
        148 goog.asserts.doAssertFailure_('', null, opt_message,
        149 Array.prototype.slice.call(arguments, 2));
        150 }
        151 return condition;
        152};
        153
        154
        155/**
        156 * Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case
        157 * when we want to add a check in the unreachable area like switch-case
        158 * statement:
        159 *
        160 * <pre>
        161 * switch(type) {
        162 * case FOO: doSomething(); break;
        163 * case BAR: doSomethingElse(); break;
        164 * default: goog.assert.fail('Unrecognized type: ' + type);
        165 * // We have only 2 types - "default:" section is unreachable code.
        166 * }
        167 * </pre>
        168 *
        169 * @param {string=} opt_message Error message in case of failure.
        170 * @param {...*} var_args The items to substitute into the failure message.
        171 * @throws {goog.asserts.AssertionError} Failure.
        172 */
        173goog.asserts.fail = function(opt_message, var_args) {
        174 if (goog.asserts.ENABLE_ASSERTS) {
        175 goog.asserts.errorHandler_(new goog.asserts.AssertionError(
        176 'Failure' + (opt_message ? ': ' + opt_message : ''),
        177 Array.prototype.slice.call(arguments, 1)));
        178 }
        179};
        180
        181
        182/**
        183 * Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true.
        184 * @param {*} value The value to check.
        185 * @param {string=} opt_message Error message in case of failure.
        186 * @param {...*} var_args The items to substitute into the failure message.
        187 * @return {number} The value, guaranteed to be a number when asserts enabled.
        188 * @throws {goog.asserts.AssertionError} When the value is not a number.
        189 */
        190goog.asserts.assertNumber = function(value, opt_message, var_args) {
        191 if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) {
        192 goog.asserts.doAssertFailure_('Expected number but got %s: %s.',
        193 [goog.typeOf(value), value], opt_message,
        194 Array.prototype.slice.call(arguments, 2));
        195 }
        196 return /** @type {number} */ (value);
        197};
        198
        199
        200/**
        201 * Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true.
        202 * @param {*} value The value to check.
        203 * @param {string=} opt_message Error message in case of failure.
        204 * @param {...*} var_args The items to substitute into the failure message.
        205 * @return {string} The value, guaranteed to be a string when asserts enabled.
        206 * @throws {goog.asserts.AssertionError} When the value is not a string.
        207 */
        208goog.asserts.assertString = function(value, opt_message, var_args) {
        209 if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) {
        210 goog.asserts.doAssertFailure_('Expected string but got %s: %s.',
        211 [goog.typeOf(value), value], opt_message,
        212 Array.prototype.slice.call(arguments, 2));
        213 }
        214 return /** @type {string} */ (value);
        215};
        216
        217
        218/**
        219 * Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true.
        220 * @param {*} value The value to check.
        221 * @param {string=} opt_message Error message in case of failure.
        222 * @param {...*} var_args The items to substitute into the failure message.
        223 * @return {!Function} The value, guaranteed to be a function when asserts
        224 * enabled.
        225 * @throws {goog.asserts.AssertionError} When the value is not a function.
        226 */
        227goog.asserts.assertFunction = function(value, opt_message, var_args) {
        228 if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) {
        229 goog.asserts.doAssertFailure_('Expected function but got %s: %s.',
        230 [goog.typeOf(value), value], opt_message,
        231 Array.prototype.slice.call(arguments, 2));
        232 }
        233 return /** @type {!Function} */ (value);
        234};
        235
        236
        237/**
        238 * Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true.
        239 * @param {*} value The value to check.
        240 * @param {string=} opt_message Error message in case of failure.
        241 * @param {...*} var_args The items to substitute into the failure message.
        242 * @return {!Object} The value, guaranteed to be a non-null object.
        243 * @throws {goog.asserts.AssertionError} When the value is not an object.
        244 */
        245goog.asserts.assertObject = function(value, opt_message, var_args) {
        246 if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) {
        247 goog.asserts.doAssertFailure_('Expected object but got %s: %s.',
        248 [goog.typeOf(value), value],
        249 opt_message, Array.prototype.slice.call(arguments, 2));
        250 }
        251 return /** @type {!Object} */ (value);
        252};
        253
        254
        255/**
        256 * Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true.
        257 * @param {*} value The value to check.
        258 * @param {string=} opt_message Error message in case of failure.
        259 * @param {...*} var_args The items to substitute into the failure message.
        260 * @return {!Array} The value, guaranteed to be a non-null array.
        261 * @throws {goog.asserts.AssertionError} When the value is not an array.
        262 */
        263goog.asserts.assertArray = function(value, opt_message, var_args) {
        264 if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) {
        265 goog.asserts.doAssertFailure_('Expected array but got %s: %s.',
        266 [goog.typeOf(value), value], opt_message,
        267 Array.prototype.slice.call(arguments, 2));
        268 }
        269 return /** @type {!Array} */ (value);
        270};
        271
        272
        273/**
        274 * Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true.
        275 * @param {*} value The value to check.
        276 * @param {string=} opt_message Error message in case of failure.
        277 * @param {...*} var_args The items to substitute into the failure message.
        278 * @return {boolean} The value, guaranteed to be a boolean when asserts are
        279 * enabled.
        280 * @throws {goog.asserts.AssertionError} When the value is not a boolean.
        281 */
        282goog.asserts.assertBoolean = function(value, opt_message, var_args) {
        283 if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) {
        284 goog.asserts.doAssertFailure_('Expected boolean but got %s: %s.',
        285 [goog.typeOf(value), value], opt_message,
        286 Array.prototype.slice.call(arguments, 2));
        287 }
        288 return /** @type {boolean} */ (value);
        289};
        290
        291
        292/**
        293 * Checks if the value is a DOM Element if goog.asserts.ENABLE_ASSERTS is true.
        294 * @param {*} value The value to check.
        295 * @param {string=} opt_message Error message in case of failure.
        296 * @param {...*} var_args The items to substitute into the failure message.
        297 * @return {!Element} The value, likely to be a DOM Element when asserts are
        298 * enabled.
        299 * @throws {goog.asserts.AssertionError} When the value is not a boolean.
        300 */
        301goog.asserts.assertElement = function(value, opt_message, var_args) {
        302 if (goog.asserts.ENABLE_ASSERTS && (!goog.isObject(value) ||
        303 value.nodeType != goog.dom.NodeType.ELEMENT)) {
        304 goog.asserts.doAssertFailure_('Expected Element but got %s: %s.',
        305 [goog.typeOf(value), value], opt_message,
        306 Array.prototype.slice.call(arguments, 2));
        307 }
        308 return /** @type {!Element} */ (value);
        309};
        310
        311
        312/**
        313 * Checks if the value is an instance of the user-defined type if
        314 * goog.asserts.ENABLE_ASSERTS is true.
        315 *
        316 * The compiler may tighten the type returned by this function.
        317 *
        318 * @param {*} value The value to check.
        319 * @param {function(new: T, ...)} type A user-defined constructor.
        320 * @param {string=} opt_message Error message in case of failure.
        321 * @param {...*} var_args The items to substitute into the failure message.
        322 * @throws {goog.asserts.AssertionError} When the value is not an instance of
        323 * type.
        324 * @return {!T}
        325 * @template T
        326 */
        327goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) {
        328 if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) {
        329 goog.asserts.doAssertFailure_('instanceof check failed.', null,
        330 opt_message, Array.prototype.slice.call(arguments, 3));
        331 }
        332 return value;
        333};
        334
        335
        336/**
        337 * Checks that no enumerable keys are present in Object.prototype. Such keys
        338 * would break most code that use {@code for (var ... in ...)} loops.
        339 */
        340goog.asserts.assertObjectPrototypeIsIntact = function() {
        341 for (var key in Object.prototype) {
        342 goog.asserts.fail(key + ' should not be enumerable in Object.prototype.');
        343 }
        344};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/async/nexttick.js.src.html b/docs/api/javascript/source/lib/goog/async/nexttick.js.src.html new file mode 100644 index 0000000000000..1923c53d04706 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/async/nexttick.js.src.html @@ -0,0 +1 @@ +nexttick.js

        lib/goog/async/nexttick.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 Provides a function to schedule running a function as soon
        17 * as possible after the current JS execution stops and yields to the event
        18 * loop.
        19 *
        20 */
        21
        22goog.provide('goog.async.nextTick');
        23goog.provide('goog.async.throwException');
        24
        25goog.require('goog.debug.entryPointRegistry');
        26goog.require('goog.functions');
        27goog.require('goog.labs.userAgent.browser');
        28
        29
        30/**
        31 * Throw an item without interrupting the current execution context. For
        32 * example, if processing a group of items in a loop, sometimes it is useful
        33 * to report an error while still allowing the rest of the batch to be
        34 * processed.
        35 * @param {*} exception
        36 */
        37goog.async.throwException = function(exception) {
        38 // Each throw needs to be in its own context.
        39 goog.global.setTimeout(function() { throw exception; }, 0);
        40};
        41
        42
        43/**
        44 * Fires the provided callbacks as soon as possible after the current JS
        45 * execution context. setTimeout(…, 0) takes at least 4ms when called from
        46 * within another setTimeout(…, 0) for legacy reasons.
        47 *
        48 * This will not schedule the callback as a microtask (i.e. a task that can
        49 * preempt user input or networking callbacks). It is meant to emulate what
        50 * setTimeout(_, 0) would do if it were not throttled. If you desire microtask
        51 * behavior, use {@see goog.Promise} instead.
        52 *
        53 * @param {function(this:SCOPE)} callback Callback function to fire as soon as
        54 * possible.
        55 * @param {SCOPE=} opt_context Object in whose scope to call the listener.
        56 * @template SCOPE
        57 */
        58goog.async.nextTick = function(callback, opt_context) {
        59 var cb = callback;
        60 if (opt_context) {
        61 cb = goog.bind(callback, opt_context);
        62 }
        63 cb = goog.async.nextTick.wrapCallback_(cb);
        64 // window.setImmediate was introduced and currently only supported by IE10+,
        65 // but due to a bug in the implementation it is not guaranteed that
        66 // setImmediate is faster than setTimeout nor that setImmediate N is before
        67 // setImmediate N+1. That is why we do not use the native version if
        68 // available. We do, however, call setImmediate if it is a normal function
        69 // because that indicates that it has been replaced by goog.testing.MockClock
        70 // which we do want to support.
        71 // See
        72 // http://connect.microsoft.com/IE/feedback/details/801823/setimmediate-and-messagechannel-are-broken-in-ie10
        73 if (goog.isFunction(goog.global.setImmediate) && (!goog.global.Window ||
        74 goog.global.Window.prototype.setImmediate != goog.global.setImmediate)) {
        75 goog.global.setImmediate(cb);
        76 return;
        77 }
        78 // Look for and cache the custom fallback version of setImmediate.
        79 if (!goog.async.nextTick.setImmediate_) {
        80 goog.async.nextTick.setImmediate_ =
        81 goog.async.nextTick.getSetImmediateEmulator_();
        82 }
        83 goog.async.nextTick.setImmediate_(cb);
        84};
        85
        86
        87/**
        88 * Cache for the setImmediate implementation.
        89 * @type {function(function())}
        90 * @private
        91 */
        92goog.async.nextTick.setImmediate_;
        93
        94
        95/**
        96 * Determines the best possible implementation to run a function as soon as
        97 * the JS event loop is idle.
        98 * @return {function(function())} The "setImmediate" implementation.
        99 * @private
        100 */
        101goog.async.nextTick.getSetImmediateEmulator_ = function() {
        102 // Create a private message channel and use it to postMessage empty messages
        103 // to ourselves.
        104 var Channel = goog.global['MessageChannel'];
        105 // If MessageChannel is not available and we are in a browser, implement
        106 // an iframe based polyfill in browsers that have postMessage and
        107 // document.addEventListener. The latter excludes IE8 because it has a
        108 // synchronous postMessage implementation.
        109 if (typeof Channel === 'undefined' && typeof window !== 'undefined' &&
        110 window.postMessage && window.addEventListener) {
        111 /** @constructor */
        112 Channel = function() {
        113 // Make an empty, invisible iframe.
        114 var iframe = document.createElement('iframe');
        115 iframe.style.display = 'none';
        116 iframe.src = '';
        117 document.documentElement.appendChild(iframe);
        118 var win = iframe.contentWindow;
        119 var doc = win.document;
        120 doc.open();
        121 doc.write('');
        122 doc.close();
        123 // Do not post anything sensitive over this channel, as the workaround for
        124 // pages with file: origin could allow that information to be modified or
        125 // intercepted.
        126 var message = 'callImmediate' + Math.random();
        127 // The same origin policy rejects attempts to postMessage from file: urls
        128 // unless the origin is '*'.
        129 // TODO(b/16335441): Use '*' origin for data: and other similar protocols.
        130 var origin = win.location.protocol == 'file:' ?
        131 '*' : win.location.protocol + '//' + win.location.host;
        132 var onmessage = goog.bind(function(e) {
        133 // Validate origin and message to make sure that this message was
        134 // intended for us.
        135 if (e.origin != origin && e.data != message) {
        136 return;
        137 }
        138 this['port1'].onmessage();
        139 }, this);
        140 win.addEventListener('message', onmessage, false);
        141 this['port1'] = {};
        142 this['port2'] = {
        143 postMessage: function() {
        144 win.postMessage(message, origin);
        145 }
        146 };
        147 };
        148 }
        149 if (typeof Channel !== 'undefined' &&
        150 // Exclude all of IE due to
        151 // http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/
        152 // which allows starving postMessage with a busy setTimeout loop.
        153 // This currently affects IE10 and IE11 which would otherwise be able
        154 // to use the postMessage based fallbacks.
        155 !goog.labs.userAgent.browser.isIE()) {
        156 var channel = new Channel();
        157 // Use a fifo linked list to call callbacks in the right order.
        158 var head = {};
        159 var tail = head;
        160 channel['port1'].onmessage = function() {
        161 head = head.next;
        162 var cb = head.cb;
        163 head.cb = null;
        164 cb();
        165 };
        166 return function(cb) {
        167 tail.next = {
        168 cb: cb
        169 };
        170 tail = tail.next;
        171 channel['port2'].postMessage(0);
        172 };
        173 }
        174 // Implementation for IE6+: Script elements fire an asynchronous
        175 // onreadystatechange event when inserted into the DOM.
        176 if (typeof document !== 'undefined' && 'onreadystatechange' in
        177 document.createElement('script')) {
        178 return function(cb) {
        179 var script = document.createElement('script');
        180 script.onreadystatechange = function() {
        181 // Clean up and call the callback.
        182 script.onreadystatechange = null;
        183 script.parentNode.removeChild(script);
        184 script = null;
        185 cb();
        186 cb = null;
        187 };
        188 document.documentElement.appendChild(script);
        189 };
        190 }
        191 // Fall back to setTimeout with 0. In browsers this creates a delay of 5ms
        192 // or more.
        193 return function(cb) {
        194 goog.global.setTimeout(cb, 0);
        195 };
        196};
        197
        198
        199/**
        200 * Helper function that is overrided to protect callbacks with entry point
        201 * monitor if the application monitors entry points.
        202 * @param {function()} callback Callback function to fire as soon as possible.
        203 * @return {function()} The wrapped callback.
        204 * @private
        205 */
        206goog.async.nextTick.wrapCallback_ = goog.functions.identity;
        207
        208
        209// Register the callback function as an entry point, so that it can be
        210// monitored for exception handling, etc. This has to be done in this file
        211// since it requires special code to handle all browsers.
        212goog.debug.entryPointRegistry.register(
        213 /**
        214 * @param {function(!Function): !Function} transformer The transforming
        215 * function.
        216 */
        217 function(transformer) {
        218 goog.async.nextTick.wrapCallback_ = transformer;
        219 });
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/async/run.js.src.html b/docs/api/javascript/source/lib/goog/async/run.js.src.html new file mode 100644 index 0000000000000..c74a4e87a1494 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/async/run.js.src.html @@ -0,0 +1 @@ +run.js

        lib/goog/async/run.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.async.run');
        16
        17goog.require('goog.async.nextTick');
        18goog.require('goog.async.throwException');
        19goog.require('goog.testing.watchers');
        20
        21
        22/**
        23 * Fires the provided callback just before the current callstack unwinds, or as
        24 * soon as possible after the current JS execution context.
        25 * @param {function(this:THIS)} callback
        26 * @param {THIS=} opt_context Object to use as the "this value" when calling
        27 * the provided function.
        28 * @template THIS
        29 */
        30goog.async.run = function(callback, opt_context) {
        31 if (!goog.async.run.schedule_) {
        32 goog.async.run.initializeRunner_();
        33 }
        34 if (!goog.async.run.workQueueScheduled_) {
        35 // Nothing is currently scheduled, schedule it now.
        36 goog.async.run.schedule_();
        37 goog.async.run.workQueueScheduled_ = true;
        38 }
        39
        40 goog.async.run.workQueue_.push(
        41 new goog.async.run.WorkItem_(callback, opt_context));
        42};
        43
        44
        45/**
        46 * Initializes the function to use to process the work queue.
        47 * @private
        48 */
        49goog.async.run.initializeRunner_ = function() {
        50 // If native Promises are available in the browser, just schedule the callback
        51 // on a fulfilled promise, which is specified to be async, but as fast as
        52 // possible.
        53 if (goog.global.Promise && goog.global.Promise.resolve) {
        54 var promise = goog.global.Promise.resolve();
        55 goog.async.run.schedule_ = function() {
        56 promise.then(goog.async.run.processWorkQueue);
        57 };
        58 } else {
        59 goog.async.run.schedule_ = function() {
        60 goog.async.nextTick(goog.async.run.processWorkQueue);
        61 };
        62 }
        63};
        64
        65
        66/**
        67 * Forces goog.async.run to use nextTick instead of Promise.
        68 *
        69 * This should only be done in unit tests. It's useful because MockClock
        70 * replaces nextTick, but not the browser Promise implementation, so it allows
        71 * Promise-based code to be tested with MockClock.
        72 */
        73goog.async.run.forceNextTick = function() {
        74 goog.async.run.schedule_ = function() {
        75 goog.async.nextTick(goog.async.run.processWorkQueue);
        76 };
        77};
        78
        79
        80/**
        81 * The function used to schedule work asynchronousely.
        82 * @private {function()}
        83 */
        84goog.async.run.schedule_;
        85
        86
        87/** @private {boolean} */
        88goog.async.run.workQueueScheduled_ = false;
        89
        90
        91/** @private {!Array.<!goog.async.run.WorkItem_>} */
        92goog.async.run.workQueue_ = [];
        93
        94
        95if (goog.DEBUG) {
        96 /**
        97 * Reset the event queue.
        98 * @private
        99 */
        100 goog.async.run.resetQueue_ = function() {
        101 goog.async.run.workQueueScheduled_ = false;
        102 goog.async.run.workQueue_ = [];
        103 };
        104
        105 // If there is a clock implemenation in use for testing
        106 // and it is reset, reset the queue.
        107 goog.testing.watchers.watchClockReset(goog.async.run.resetQueue_);
        108}
        109
        110
        111/**
        112 * Run any pending goog.async.run work items. This function is not intended
        113 * for general use, but for use by entry point handlers to run items ahead of
        114 * goog.async.nextTick.
        115 */
        116goog.async.run.processWorkQueue = function() {
        117 // NOTE: additional work queue items may be pushed while processing.
        118 while (goog.async.run.workQueue_.length) {
        119 // Don't let the work queue grow indefinitely.
        120 var workItems = goog.async.run.workQueue_;
        121 goog.async.run.workQueue_ = [];
        122 for (var i = 0; i < workItems.length; i++) {
        123 var workItem = workItems[i];
        124 try {
        125 workItem.fn.call(workItem.scope);
        126 } catch (e) {
        127 goog.async.throwException(e);
        128 }
        129 }
        130 }
        131
        132 // There are no more work items, reset the work queue.
        133 goog.async.run.workQueueScheduled_ = false;
        134};
        135
        136
        137
        138/**
        139 * @constructor
        140 * @final
        141 * @struct
        142 * @private
        143 *
        144 * @param {function()} fn
        145 * @param {Object|null|undefined} scope
        146 */
        147goog.async.run.WorkItem_ = function(fn, scope) {
        148 /** @const */ this.fn = fn;
        149 /** @const */ this.scope = scope;
        150};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/base.js.src.html b/docs/api/javascript/source/lib/goog/base.js.src.html index 6b78dc299bfb5..5bcc4b1b424a4 100644 --- a/docs/api/javascript/source/lib/goog/base.js.src.html +++ b/docs/api/javascript/source/lib/goog/base.js.src.html @@ -1 +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 +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.
        243 // A goog.module/goog.provide maps a goog.require to a specific file
        244 if (goog.isProvided_(name)) {
        245 throw Error('Namespace "' + name + '" already declared.');
        246 }
        247 delete goog.implicitNamespaces_[name];
        248
        249 var namespace = name;
        250 while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {
        251 if (goog.getObjectByName(namespace)) {
        252 break;
        253 }
        254 goog.implicitNamespaces_[namespace] = true;
        255 }
        256 }
        257
        258 goog.exportPath_(name);
        259};
        260
        261
        262/**
        263 * goog.module serves two purposes:
        264 * - marks a file that must be loaded as a module
        265 * - reserves a namespace (it can not also be goog.provided)
        266 * and has three requirements:
        267 * - goog.module may not be used in the same file as goog.provide.
        268 * - goog.module must be the first statement in the file.
        269 * - only one goog.module is allowed per file.
        270 * When a goog.module annotated file is loaded, it is loaded enclosed in
        271 * a strict function closure. This means that:
        272 * - any variable declared in a goog.module file are private to the file,
        273 * not global. Although the compiler is expected to inline the module.
        274 * - The code must obey all the rules of "strict" JavaScript.
        275 * - the file will be marked as "use strict"
        276 *
        277 * NOTE: unlike goog.provide, goog.module does not declare any symbols by
        278 * itself.
        279 *
        280 * @param {string} name Namespace provided by this file in the form
        281 * "goog.package.part", is expected but not required.
        282 */
        283goog.module = function(name) {
        284 if (!goog.isString(name) || !name) {
        285 throw Error('Invalid module identifier');
        286 }
        287 if (!goog.isInModuleLoader_()) {
        288 throw Error('Module ' + name + ' has been loaded incorrectly.');
        289 }
        290 if (goog.moduleLoaderState_.moduleName) {
        291 throw Error('goog.module may only be called once per module.');
        292 }
        293
        294 // Store the module name for the loader.
        295 goog.moduleLoaderState_.moduleName = name;
        296 if (!COMPILED) {
        297 // Ensure that the same namespace isn't provided twice.
        298 // A goog.module/goog.provide maps a goog.require to a specific file
        299 if (goog.isProvided_(name)) {
        300 throw Error('Namespace "' + name + '" already declared.');
        301 }
        302 delete goog.implicitNamespaces_[name];
        303 }
        304};
        305
        306
        307/** @private {{
        308 * moduleName:(string|undefined),
        309 * exportTestMethods:boolean}|null}}
        310 */
        311goog.moduleLoaderState_ = null;
        312
        313
        314/**
        315 * @private
        316 * @return {boolean} Whether a goog.module is currently being initialized.
        317 */
        318goog.isInModuleLoader_ = function() {
        319 return goog.moduleLoaderState_ != null;
        320};
        321
        322
        323/**
        324 * Indicate that a module's exports that are known test methods should
        325 * be copied to the global object. This makes the test methods visible to
        326 * test runners that inspect the global object.
        327 *
        328 * TODO(johnlenz): Make the test framework aware of goog.module so
        329 * that this isn't necessary. Alternately combine this with goog.setTestOnly
        330 * to minimize boiler plate.
        331 */
        332goog.module.exportTestMethods = function() {
        333 if (!goog.isInModuleLoader_()) {
        334 throw new Error('goog.module.exportTestMethods must be called from ' +
        335 'within a goog.module');
        336 }
        337 goog.moduleLoaderState_.exportTestMethods = true;
        338};
        339
        340
        341/**
        342 * Marks that the current file should only be used for testing, and never for
        343 * live code in production.
        344 *
        345 * In the case of unit tests, the message may optionally be an exact namespace
        346 * for the test (e.g. 'goog.stringTest'). The linter will then ignore the extra
        347 * provide (if not explicitly defined in the code).
        348 *
        349 * @param {string=} opt_message Optional message to add to the error that's
        350 * raised when used in production code.
        351 */
        352goog.setTestOnly = function(opt_message) {
        353 if (COMPILED && !goog.DEBUG) {
        354 opt_message = opt_message || '';
        355 throw Error('Importing test-only code into non-debug environment' +
        356 (opt_message ? ': ' + opt_message : '.'));
        357 }
        358};
        359
        360
        361/**
        362 * Forward declares a symbol. This is an indication to the compiler that the
        363 * symbol may be used in the source yet is not required and may not be provided
        364 * in compilation.
        365 *
        366 * The most common usage of forward declaration is code that takes a type as a
        367 * function parameter but does not need to require it. By forward declaring
        368 * instead of requiring, no hard dependency is made, and (if not required
        369 * elsewhere) the namespace may never be required and thus, not be pulled
        370 * into the JavaScript binary. If it is required elsewhere, it will be type
        371 * checked as normal.
        372 *
        373 *
        374 * @param {string} name The namespace to forward declare in the form of
        375 * "goog.package.part".
        376 */
        377goog.forwardDeclare = function(name) {};
        378
        379
        380if (!COMPILED) {
        381
        382 /**
        383 * Check if the given name has been goog.provided. This will return false for
        384 * names that are available only as implicit namespaces.
        385 * @param {string} name name of the object to look for.
        386 * @return {boolean} Whether the name has been provided.
        387 * @private
        388 */
        389 goog.isProvided_ = function(name) {
        390 return (name in goog.loadedModules_) ||
        391 (!goog.implicitNamespaces_[name] &&
        392 goog.isDefAndNotNull(goog.getObjectByName(name)));
        393 };
        394
        395 /**
        396 * Namespaces implicitly defined by goog.provide. For example,
        397 * goog.provide('goog.events.Event') implicitly declares that 'goog' and
        398 * 'goog.events' must be namespaces.
        399 *
        400 * @type {Object.<string, (boolean|undefined)>}
        401 * @private
        402 */
        403 goog.implicitNamespaces_ = {'goog.module': true};
        404
        405 // NOTE: We add goog.module as an implicit namespace as goog.module is defined
        406 // here and because the existing module package has not been moved yet out of
        407 // the goog.module namespace. This satisifies both the debug loader and
        408 // ahead-of-time dependency management.
        409}
        410
        411
        412/**
        413 * Returns an object based on its fully qualified external name. The object
        414 * is not found if null or undefined. If you are using a compilation pass that
        415 * renames property names beware that using this function will not find renamed
        416 * properties.
        417 *
        418 * @param {string} name The fully qualified name.
        419 * @param {Object=} opt_obj The object within which to look; default is
        420 * |goog.global|.
        421 * @return {?} The value (object or primitive) or, if not found, null.
        422 */
        423goog.getObjectByName = function(name, opt_obj) {
        424 var parts = name.split('.');
        425 var cur = opt_obj || goog.global;
        426 for (var part; part = parts.shift(); ) {
        427 if (goog.isDefAndNotNull(cur[part])) {
        428 cur = cur[part];
        429 } else {
        430 return null;
        431 }
        432 }
        433 return cur;
        434};
        435
        436
        437/**
        438 * Globalizes a whole namespace, such as goog or goog.lang.
        439 *
        440 * @param {Object} obj The namespace to globalize.
        441 * @param {Object=} opt_global The object to add the properties to.
        442 * @deprecated Properties may be explicitly exported to the global scope, but
        443 * this should no longer be done in bulk.
        444 */
        445goog.globalize = function(obj, opt_global) {
        446 var global = opt_global || goog.global;
        447 for (var x in obj) {
        448 global[x] = obj[x];
        449 }
        450};
        451
        452
        453/**
        454 * Adds a dependency from a file to the files it requires.
        455 * @param {string} relPath The path to the js file.
        456 * @param {Array} provides An array of strings with the names of the objects
        457 * this file provides.
        458 * @param {Array} requires An array of strings with the names of the objects
        459 * this file requires.
        460 * @param {boolean=} opt_isModule Whether this dependency must be loaded as
        461 * a module as declared by goog.module.
        462 */
        463goog.addDependency = function(relPath, provides, requires, opt_isModule) {
        464 if (goog.DEPENDENCIES_ENABLED) {
        465 var provide, require;
        466 var path = relPath.replace(/\\/g, '/');
        467 var deps = goog.dependencies_;
        468 for (var i = 0; provide = provides[i]; i++) {
        469 deps.nameToPath[provide] = path;
        470 deps.pathIsModule[path] = !!opt_isModule;
        471 }
        472 for (var j = 0; require = requires[j]; j++) {
        473 if (!(path in deps.requires)) {
        474 deps.requires[path] = {};
        475 }
        476 deps.requires[path][require] = true;
        477 }
        478 }
        479};
        480
        481
        482
        483
        484// NOTE(nnaze): The debug DOM loader was included in base.js as an original way
        485// to do "debug-mode" development. The dependency system can sometimes be
        486// confusing, as can the debug DOM loader's asynchronous nature.
        487//
        488// With the DOM loader, a call to goog.require() is not blocking -- the script
        489// will not load until some point after the current script. If a namespace is
        490// needed at runtime, it needs to be defined in a previous script, or loaded via
        491// require() with its registered dependencies.
        492// User-defined namespaces may need their own deps file. See http://go/js_deps,
        493// http://go/genjsdeps, or, externally, DepsWriter.
        494// https://developers.google.com/closure/library/docs/depswriter
        495//
        496// Because of legacy clients, the DOM loader can't be easily removed from
        497// base.js. Work is being done to make it disableable or replaceable for
        498// different environments (DOM-less JavaScript interpreters like Rhino or V8,
        499// for example). See bootstrap/ for more information.
        500
        501
        502/**
        503 * @define {boolean} Whether to enable the debug loader.
        504 *
        505 * If enabled, a call to goog.require() will attempt to load the namespace by
        506 * appending a script tag to the DOM (if the namespace has been registered).
        507 *
        508 * If disabled, goog.require() will simply assert that the namespace has been
        509 * provided (and depend on the fact that some outside tool correctly ordered
        510 * the script).
        511 */
        512goog.define('goog.ENABLE_DEBUG_LOADER', true);
        513
        514
        515/**
        516 * @param {string} msg
        517 * @private
        518 */
        519goog.logToConsole_ = function(msg) {
        520 if (goog.global.console) {
        521 goog.global.console['error'](msg);
        522 }
        523};
        524
        525
        526/**
        527 * Implements a system for the dynamic resolution of dependencies that works in
        528 * parallel with the BUILD system. Note that all calls to goog.require will be
        529 * stripped by the JSCompiler when the --closure_pass option is used.
        530 * @see goog.provide
        531 * @param {string} name Namespace to include (as was given in goog.provide()) in
        532 * the form "goog.package.part".
        533 * @return {?} If called within a goog.module file, the associated namespace or
        534 * module otherwise null.
        535 */
        536goog.require = function(name) {
        537
        538 // If the object already exists we do not need do do anything.
        539 if (!COMPILED) {
        540 if (goog.isProvided_(name)) {
        541 if (goog.isInModuleLoader_()) {
        542 // goog.require only return a value with-in goog.module files.
        543 return name in goog.loadedModules_ ?
        544 goog.loadedModules_[name] :
        545 goog.getObjectByName(name);
        546 } else {
        547 return null;
        548 }
        549 }
        550
        551 if (goog.ENABLE_DEBUG_LOADER) {
        552 var path = goog.getPathFromDeps_(name);
        553 if (path) {
        554 goog.included_[path] = true;
        555 goog.writeScripts_();
        556 return null;
        557 }
        558 }
        559
        560 var errorMessage = 'goog.require could not find: ' + name;
        561 goog.logToConsole_(errorMessage);
        562
        563 throw Error(errorMessage);
        564 }
        565};
        566
        567
        568/**
        569 * Path for included scripts.
        570 * @type {string}
        571 */
        572goog.basePath = '';
        573
        574
        575/**
        576 * A hook for overriding the base path.
        577 * @type {string|undefined}
        578 */
        579goog.global.CLOSURE_BASE_PATH;
        580
        581
        582/**
        583 * Whether to write out Closure's deps file. By default, the deps are written.
        584 * @type {boolean|undefined}
        585 */
        586goog.global.CLOSURE_NO_DEPS;
        587
        588
        589/**
        590 * A function to import a single script. This is meant to be overridden when
        591 * Closure is being run in non-HTML contexts, such as web workers. It's defined
        592 * in the global scope so that it can be set before base.js is loaded, which
        593 * allows deps.js to be imported properly.
        594 *
        595 * The function is passed the script source, which is a relative URI. It should
        596 * return true if the script was imported, false otherwise.
        597 * @type {(function(string): boolean)|undefined}
        598 */
        599goog.global.CLOSURE_IMPORT_SCRIPT;
        600
        601
        602/**
        603 * Null function used for default values of callbacks, etc.
        604 * @return {void} Nothing.
        605 */
        606goog.nullFunction = function() {};
        607
        608
        609/**
        610 * The identity function. Returns its first argument.
        611 *
        612 * @param {*=} opt_returnValue The single value that will be returned.
        613 * @param {...*} var_args Optional trailing arguments. These are ignored.
        614 * @return {?} The first argument. We can't know the type -- just pass it along
        615 * without type.
        616 * @deprecated Use goog.functions.identity instead.
        617 */
        618goog.identityFunction = function(opt_returnValue, var_args) {
        619 return opt_returnValue;
        620};
        621
        622
        623/**
        624 * When defining a class Foo with an abstract method bar(), you can do:
        625 * Foo.prototype.bar = goog.abstractMethod
        626 *
        627 * Now if a subclass of Foo fails to override bar(), an error will be thrown
        628 * when bar() is invoked.
        629 *
        630 * Note: This does not take the name of the function to override as an argument
        631 * because that would make it more difficult to obfuscate our JavaScript code.
        632 *
        633 * @type {!Function}
        634 * @throws {Error} when invoked to indicate the method should be overridden.
        635 */
        636goog.abstractMethod = function() {
        637 throw Error('unimplemented abstract method');
        638};
        639
        640
        641/**
        642 * Adds a {@code getInstance} static method that always returns the same
        643 * instance object.
        644 * @param {!Function} ctor The constructor for the class to add the static
        645 * method to.
        646 */
        647goog.addSingletonGetter = function(ctor) {
        648 ctor.getInstance = function() {
        649 if (ctor.instance_) {
        650 return ctor.instance_;
        651 }
        652 if (goog.DEBUG) {
        653 // NOTE: JSCompiler can't optimize away Array#push.
        654 goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor;
        655 }
        656 return ctor.instance_ = new ctor;
        657 };
        658};
        659
        660
        661/**
        662 * All singleton classes that have been instantiated, for testing. Don't read
        663 * it directly, use the {@code goog.testing.singleton} module. The compiler
        664 * removes this variable if unused.
        665 * @type {!Array.<!Function>}
        666 * @private
        667 */
        668goog.instantiatedSingletons_ = [];
        669
        670
        671/**
        672 * @define {boolean} Whether to load goog.modules using {@code eval} when using
        673 * the debug loader. This provides a better debugging experience as the
        674 * source is unmodified and can be edited using Chrome Workspaces or
        675 * similiar. However in some environments the use of {@code eval} is banned
        676 * so we provide an alternative.
        677 */
        678goog.define('goog.LOAD_MODULE_USING_EVAL', true);
        679
        680
        681/**
        682 * The registry of initialized modules:
        683 * the module identifier to module exports map.
        684 * @private @const {Object.<string, ?>}
        685 */
        686goog.loadedModules_ = {};
        687
        688
        689/**
        690 * True if goog.dependencies_ is available.
        691 * @const {boolean}
        692 */
        693goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;
        694
        695
        696if (goog.DEPENDENCIES_ENABLED) {
        697 /**
        698 * Object used to keep track of urls that have already been added. This record
        699 * allows the prevention of circular dependencies.
        700 * @type {Object}
        701 * @private
        702 */
        703 goog.included_ = {};
        704
        705
        706 /**
        707 * This object is used to keep track of dependencies and other data that is
        708 * used for loading scripts.
        709 * @private
        710 * @type {Object}
        711 */
        712 goog.dependencies_ = {
        713 pathIsModule: {}, // 1 to 1
        714 nameToPath: {}, // many to 1
        715 requires: {}, // 1 to many
        716 // Used when resolving dependencies to prevent us from visiting file twice.
        717 visited: {},
        718 written: {} // Used to keep track of script files we have written.
        719 };
        720
        721
        722 /**
        723 * Tries to detect whether is in the context of an HTML document.
        724 * @return {boolean} True if it looks like HTML document.
        725 * @private
        726 */
        727 goog.inHtmlDocument_ = function() {
        728 var doc = goog.global.document;
        729 return typeof doc != 'undefined' &&
        730 'write' in doc; // XULDocument misses write.
        731 };
        732
        733
        734 /**
        735 * Tries to detect the base path of base.js script that bootstraps Closure.
        736 * @private
        737 */
        738 goog.findBasePath_ = function() {
        739 if (goog.global.CLOSURE_BASE_PATH) {
        740 goog.basePath = goog.global.CLOSURE_BASE_PATH;
        741 return;
        742 } else if (!goog.inHtmlDocument_()) {
        743 return;
        744 }
        745 var doc = goog.global.document;
        746 var scripts = doc.getElementsByTagName('script');
        747 // Search backwards since the current script is in almost all cases the one
        748 // that has base.js.
        749 for (var i = scripts.length - 1; i >= 0; --i) {
        750 var src = scripts[i].src;
        751 var qmark = src.lastIndexOf('?');
        752 var l = qmark == -1 ? src.length : qmark;
        753 if (src.substr(l - 7, 7) == 'base.js') {
        754 goog.basePath = src.substr(0, l - 7);
        755 return;
        756 }
        757 }
        758 };
        759
        760
        761 /**
        762 * Imports a script if, and only if, that script hasn't already been imported.
        763 * (Must be called at execution time)
        764 * @param {string} src Script source.
        765 * @param {string=} opt_sourceText The optionally source text to evaluate
        766 * @private
        767 */
        768 goog.importScript_ = function(src, opt_sourceText) {
        769 var importScript = goog.global.CLOSURE_IMPORT_SCRIPT ||
        770 goog.writeScriptTag_;
        771 if (importScript(src, opt_sourceText)) {
        772 goog.dependencies_.written[src] = true;
        773 }
        774 };
        775
        776
        777 /** @const @private {boolean} */
        778 goog.IS_OLD_IE_ = goog.global.document &&
        779 goog.global.document.all && !goog.global.atob;
        780
        781
        782 /**
        783 * Given a URL initiate retrieval and execution of the module.
        784 * @param {string} src Script source URL.
        785 * @private
        786 */
        787 goog.importModule_ = function(src) {
        788 // In an attempt to keep browsers from timing out loading scripts using
        789 // synchronous XHRs, put each load in its own script block.
        790 var bootstrap = 'goog.retrieveAndExecModule_("' + src + '");';
        791
        792 if (goog.importScript_('', bootstrap)) {
        793 goog.dependencies_.written[src] = true;
        794 }
        795 };
        796
        797
        798 /** @private {Array.<string>} */
        799 goog.queuedModules_ = [];
        800
        801
        802 /**
        803 * Retrieve and execute a module.
        804 * @param {string} src Script source URL.
        805 * @private
        806 */
        807 goog.retrieveAndExecModule_ = function(src) {
        808 var importScript = goog.global.CLOSURE_IMPORT_SCRIPT ||
        809 goog.writeScriptTag_;
        810
        811 var scriptText = null;
        812
        813 var xhr = new goog.global['XMLHttpRequest']();
        814
        815 /** @this {Object} */
        816 xhr.onload = function() {
        817 scriptText = this.responseText;
        818 };
        819 xhr.open('get', src, false);
        820 xhr.send();
        821
        822 scriptText = xhr.responseText;
        823
        824 if (scriptText != null) {
        825 var execModuleScript = goog.wrapModule_(src, scriptText);
        826 var isOldIE = goog.IS_OLD_IE_;
        827 if (isOldIE) {
        828 goog.queuedModules_.push(execModuleScript);
        829 } else {
        830 importScript(src, execModuleScript);
        831 }
        832 goog.dependencies_.written[src] = true;
        833 } else {
        834 throw new Error('load of ' + src + 'failed');
        835 }
        836 };
        837
        838
        839 /**
        840 * Return an appropriate module text. Suitable to insert into
        841 * a script tag (that is unescaped).
        842 * @param {string} srcUrl
        843 * @param {string} scriptText
        844 * @return {string}
        845 * @private
        846 */
        847 goog.wrapModule_ = function(srcUrl, scriptText) {
        848 if (!goog.LOAD_MODULE_USING_EVAL || !goog.isDef(goog.global.JSON)) {
        849 return '' +
        850 'goog.loadModule(function(exports) {' +
        851 '"use strict";' +
        852 scriptText +
        853 '\n' + // terminate any trailing single line comment.
        854 ';return exports' +
        855 '});' +
        856 '\n//# sourceURL=' + srcUrl + '\n';
        857 } else {
        858 return '' +
        859 'goog.loadModule(' +
        860 goog.global.JSON.stringify(
        861 scriptText + '\n//# sourceURL=' + srcUrl + '\n') +
        862 ');';
        863 }
        864 };
        865
        866
        867 /**
        868 * Load any deferred goog.module loads.
        869 * @private
        870 */
        871 goog.loadQueuedModules_ = function() {
        872 var count = goog.queuedModules_.length;
        873 if (count > 0) {
        874 var queue = goog.queuedModules_;
        875 goog.queuedModules_ = [];
        876 for (var i = 0; i < count; i++) {
        877 var entry = queue[i];
        878 goog.globalEval(entry);
        879 }
        880 }
        881 };
        882
        883
        884 /**
        885 * @param {function(?):?|string} moduleDef The module definition.
        886 */
        887 goog.loadModule = function(moduleDef) {
        888 // NOTE: we allow function definitions to be either in the from
        889 // of a string to eval (which keeps the original source intact) or
        890 // in a eval forbidden environment (CSP) we allow a function definition
        891 // which in its body must call {@code goog.module}, and return the exports
        892 // of the module.
        893 try {
        894 goog.moduleLoaderState_ = {
        895 moduleName: undefined, exportTestMethods: false};
        896 var exports;
        897 if (goog.isFunction(moduleDef)) {
        898 exports = moduleDef.call(goog.global, {});
        899 } else if (goog.isString(moduleDef)) {
        900 exports = goog.loadModuleFromSource_.call(goog.global, moduleDef);
        901 } else {
        902 throw Error('Invalid module definition');
        903 }
        904
        905 if (Object.seal) {
        906 Object.seal(exports);
        907 }
        908 var moduleName = goog.moduleLoaderState_.moduleName;
        909 if (!goog.isString(moduleName) || !moduleName) {
        910 throw Error('Invalid module name \"' + moduleName + '\"');
        911 }
        912
        913 goog.loadedModules_[moduleName] = exports;
        914 if (goog.moduleLoaderState_.exportTestMethods) {
        915 for (var entry in exports) {
        916 if (entry.indexOf('test', 0) === 0 ||
        917 entry == 'tearDown' ||
        918 entry == 'setup') {
        919 goog.global[entry] = exports[entry];
        920 }
        921 }
        922 }
        923 } finally {
        924 goog.moduleLoaderState_ = null;
        925 }
        926 };
        927
        928
        929 /**
        930 * @private @const {function(string):?}
        931 */
        932 goog.loadModuleFromSource_ = function() {
        933 // NOTE: we avoid declaring parameters or local variables here to avoid
        934 // masking globals or leaking values into the module definition.
        935 'use strict';
        936 var exports = {};
        937 eval(arguments[0]);
        938 return exports;
        939 };
        940
        941
        942 /**
        943 * The default implementation of the import function. Writes a script tag to
        944 * import the script.
        945 *
        946 * @param {string} src The script url.
        947 * @param {string=} opt_sourceText The optionally source text to evaluate
        948 * @return {boolean} True if the script was imported, false otherwise.
        949 * @private
        950 */
        951 goog.writeScriptTag_ = function(src, opt_sourceText) {
        952 if (goog.inHtmlDocument_()) {
        953 var doc = goog.global.document;
        954
        955 // If the user tries to require a new symbol after document load,
        956 // something has gone terribly wrong. Doing a document.write would
        957 // wipe out the page.
        958 if (doc.readyState == 'complete') {
        959 // Certain test frameworks load base.js multiple times, which tries
        960 // to write deps.js each time. If that happens, just fail silently.
        961 // These frameworks wipe the page between each load of base.js, so this
        962 // is OK.
        963 var isDeps = /\bdeps.js$/.test(src);
        964 if (isDeps) {
        965 return false;
        966 } else {
        967 throw Error('Cannot write "' + src + '" after document load');
        968 }
        969 }
        970
        971 var isOldIE = goog.IS_OLD_IE_;
        972
        973 if (opt_sourceText === undefined) {
        974 if (!isOldIE) {
        975 doc.write(
        976 '<script type="text/javascript" src="' +
        977 src + '"></' + 'script>');
        978 } else {
        979 var state = " onreadystatechange='goog.onScriptLoad_(this, " +
        980 ++goog.lastNonModuleScriptIndex_ + ")' ";
        981 doc.write(
        982 '<script type="text/javascript" src="' +
        983 src + '"' + state + '></' + 'script>');
        984 }
        985 } else {
        986 doc.write(
        987 '<script type="text/javascript">' +
        988 opt_sourceText +
        989 '</' + 'script>');
        990 }
        991 return true;
        992 } else {
        993 return false;
        994 }
        995 };
        996
        997
        998 /** @private {number} */
        999 goog.lastNonModuleScriptIndex_ = 0;
        1000
        1001
        1002 /**
        1003 * A readystatechange handler for legacy IE
        1004 * @param {HTMLScriptElement} script
        1005 * @param {number} scriptIndex
        1006 * @return {boolean}
        1007 * @private
        1008 */
        1009 goog.onScriptLoad_ = function(script, scriptIndex) {
        1010 // for now load the modules when we reach the last script,
        1011 // later allow more inter-mingling.
        1012 if (script.readyState == 'complete' &&
        1013 goog.lastNonModuleScriptIndex_ == scriptIndex) {
        1014 goog.loadQueuedModules_();
        1015 }
        1016 return true;
        1017 };
        1018
        1019 /**
        1020 * Resolves dependencies based on the dependencies added using addDependency
        1021 * and calls importScript_ in the correct order.
        1022 * @private
        1023 */
        1024 goog.writeScripts_ = function() {
        1025 // The scripts we need to write this time.
        1026 var scripts = [];
        1027 var seenScript = {};
        1028 var deps = goog.dependencies_;
        1029
        1030 function visitNode(path) {
        1031 if (path in deps.written) {
        1032 return;
        1033 }
        1034
        1035 // We have already visited this one. We can get here if we have cyclic
        1036 // dependencies.
        1037 if (path in deps.visited) {
        1038 if (!(path in seenScript)) {
        1039 seenScript[path] = true;
        1040 scripts.push(path);
        1041 }
        1042 return;
        1043 }
        1044
        1045 deps.visited[path] = true;
        1046
        1047 if (path in deps.requires) {
        1048 for (var requireName in deps.requires[path]) {
        1049 // If the required name is defined, we assume that it was already
        1050 // bootstrapped by other means.
        1051 if (!goog.isProvided_(requireName)) {
        1052 if (requireName in deps.nameToPath) {
        1053 visitNode(deps.nameToPath[requireName]);
        1054 } else {
        1055 throw Error('Undefined nameToPath for ' + requireName);
        1056 }
        1057 }
        1058 }
        1059 }
        1060
        1061 if (!(path in seenScript)) {
        1062 seenScript[path] = true;
        1063 scripts.push(path);
        1064 }
        1065 }
        1066
        1067 for (var path in goog.included_) {
        1068 if (!deps.written[path]) {
        1069 visitNode(path);
        1070 }
        1071 }
        1072
        1073 // record that we are going to load all these scripts.
        1074 for (var i = 0; i < scripts.length; i++) {
        1075 var path = scripts[i];
        1076 goog.dependencies_.written[path] = true;
        1077 }
        1078
        1079 // If a module is loaded synchronously then we need to
        1080 // clear the current inModuleLoader value, and restore it when we are
        1081 // done loading the current "requires".
        1082 var moduleState = goog.moduleLoaderState_;
        1083 goog.moduleLoaderState_ = null;
        1084
        1085 var loadingModule = false;
        1086 for (var i = 0; i < scripts.length; i++) {
        1087 var path = scripts[i];
        1088 if (path) {
        1089 if (!deps.pathIsModule[path]) {
        1090 goog.importScript_(goog.basePath + path);
        1091 } else {
        1092 loadingModule = true;
        1093 goog.importModule_(goog.basePath + path);
        1094 }
        1095 } else {
        1096 goog.moduleLoaderState_ = moduleState;
        1097 throw Error('Undefined script input');
        1098 }
        1099 }
        1100
        1101 // restore the current "module loading state"
        1102 goog.moduleLoaderState_ = moduleState;
        1103 };
        1104
        1105
        1106 /**
        1107 * Looks at the dependency rules and tries to determine the script file that
        1108 * fulfills a particular rule.
        1109 * @param {string} rule In the form goog.namespace.Class or project.script.
        1110 * @return {?string} Url corresponding to the rule, or null.
        1111 * @private
        1112 */
        1113 goog.getPathFromDeps_ = function(rule) {
        1114 if (rule in goog.dependencies_.nameToPath) {
        1115 return goog.dependencies_.nameToPath[rule];
        1116 } else {
        1117 return null;
        1118 }
        1119 };
        1120
        1121 goog.findBasePath_();
        1122
        1123 // Allow projects to manage the deps files themselves.
        1124 if (!goog.global.CLOSURE_NO_DEPS) {
        1125 goog.importScript_(goog.basePath + 'deps.js');
        1126 }
        1127}
        1128
        1129
        1130
        1131//==============================================================================
        1132// Language Enhancements
        1133//==============================================================================
        1134
        1135
        1136/**
        1137 * This is a "fixed" version of the typeof operator. It differs from the typeof
        1138 * operator in such a way that null returns 'null' and arrays return 'array'.
        1139 * @param {*} value The value to get the type of.
        1140 * @return {string} The name of the type.
        1141 */
        1142goog.typeOf = function(value) {
        1143 var s = typeof value;
        1144 if (s == 'object') {
        1145 if (value) {
        1146 // Check these first, so we can avoid calling Object.prototype.toString if
        1147 // possible.
        1148 //
        1149 // IE improperly marshals tyepof across execution contexts, but a
        1150 // cross-context object will still return false for "instanceof Object".
        1151 if (value instanceof Array) {
        1152 return 'array';
        1153 } else if (value instanceof Object) {
        1154 return s;
        1155 }
        1156
        1157 // HACK: In order to use an Object prototype method on the arbitrary
        1158 // value, the compiler requires the value be cast to type Object,
        1159 // even though the ECMA spec explicitly allows it.
        1160 var className = Object.prototype.toString.call(
        1161 /** @type {Object} */ (value));
        1162 // In Firefox 3.6, attempting to access iframe window objects' length
        1163 // property throws an NS_ERROR_FAILURE, so we need to special-case it
        1164 // here.
        1165 if (className == '[object Window]') {
        1166 return 'object';
        1167 }
        1168
        1169 // We cannot always use constructor == Array or instanceof Array because
        1170 // different frames have different Array objects. In IE6, if the iframe
        1171 // where the array was created is destroyed, the array loses its
        1172 // prototype. Then dereferencing val.splice here throws an exception, so
        1173 // we can't use goog.isFunction. Calling typeof directly returns 'unknown'
        1174 // so that will work. In this case, this function will return false and
        1175 // most array functions will still work because the array is still
        1176 // array-like (supports length and []) even though it has lost its
        1177 // prototype.
        1178 // Mark Miller noticed that Object.prototype.toString
        1179 // allows access to the unforgeable [[Class]] property.
        1180 // 15.2.4.2 Object.prototype.toString ( )
        1181 // When the toString method is called, the following steps are taken:
        1182 // 1. Get the [[Class]] property of this object.
        1183 // 2. Compute a string value by concatenating the three strings
        1184 // "[object ", Result(1), and "]".
        1185 // 3. Return Result(2).
        1186 // and this behavior survives the destruction of the execution context.
        1187 if ((className == '[object Array]' ||
        1188 // In IE all non value types are wrapped as objects across window
        1189 // boundaries (not iframe though) so we have to do object detection
        1190 // for this edge case.
        1191 typeof value.length == 'number' &&
        1192 typeof value.splice != 'undefined' &&
        1193 typeof value.propertyIsEnumerable != 'undefined' &&
        1194 !value.propertyIsEnumerable('splice')
        1195
        1196 )) {
        1197 return 'array';
        1198 }
        1199 // HACK: There is still an array case that fails.
        1200 // function ArrayImpostor() {}
        1201 // ArrayImpostor.prototype = [];
        1202 // var impostor = new ArrayImpostor;
        1203 // this can be fixed by getting rid of the fast path
        1204 // (value instanceof Array) and solely relying on
        1205 // (value && Object.prototype.toString.vall(value) === '[object Array]')
        1206 // but that would require many more function calls and is not warranted
        1207 // unless closure code is receiving objects from untrusted sources.
        1208
        1209 // IE in cross-window calls does not correctly marshal the function type
        1210 // (it appears just as an object) so we cannot use just typeof val ==
        1211 // 'function'. However, if the object has a call property, it is a
        1212 // function.
        1213 if ((className == '[object Function]' ||
        1214 typeof value.call != 'undefined' &&
        1215 typeof value.propertyIsEnumerable != 'undefined' &&
        1216 !value.propertyIsEnumerable('call'))) {
        1217 return 'function';
        1218 }
        1219
        1220 } else {
        1221 return 'null';
        1222 }
        1223
        1224 } else if (s == 'function' && typeof value.call == 'undefined') {
        1225 // In Safari typeof nodeList returns 'function', and on Firefox typeof
        1226 // behaves similarly for HTML{Applet,Embed,Object}, Elements and RegExps. We
        1227 // would like to return object for those and we can detect an invalid
        1228 // function by making sure that the function object has a call method.
        1229 return 'object';
        1230 }
        1231 return s;
        1232};
        1233
        1234
        1235/**
        1236 * Returns true if the specified value is null.
        1237 * @param {?} val Variable to test.
        1238 * @return {boolean} Whether variable is null.
        1239 */
        1240goog.isNull = function(val) {
        1241 return val === null;
        1242};
        1243
        1244
        1245/**
        1246 * Returns true if the specified value is defined and not null.
        1247 * @param {?} val Variable to test.
        1248 * @return {boolean} Whether variable is defined and not null.
        1249 */
        1250goog.isDefAndNotNull = function(val) {
        1251 // Note that undefined == null.
        1252 return val != null;
        1253};
        1254
        1255
        1256/**
        1257 * Returns true if the specified value is an array.
        1258 * @param {?} val Variable to test.
        1259 * @return {boolean} Whether variable is an array.
        1260 */
        1261goog.isArray = function(val) {
        1262 return goog.typeOf(val) == 'array';
        1263};
        1264
        1265
        1266/**
        1267 * Returns true if the object looks like an array. To qualify as array like
        1268 * the value needs to be either a NodeList or an object with a Number length
        1269 * property.
        1270 * @param {?} val Variable to test.
        1271 * @return {boolean} Whether variable is an array.
        1272 */
        1273goog.isArrayLike = function(val) {
        1274 var type = goog.typeOf(val);
        1275 return type == 'array' || type == 'object' && typeof val.length == 'number';
        1276};
        1277
        1278
        1279/**
        1280 * Returns true if the object looks like a Date. To qualify as Date-like the
        1281 * value needs to be an object and have a getFullYear() function.
        1282 * @param {?} val Variable to test.
        1283 * @return {boolean} Whether variable is a like a Date.
        1284 */
        1285goog.isDateLike = function(val) {
        1286 return goog.isObject(val) && typeof val.getFullYear == 'function';
        1287};
        1288
        1289
        1290/**
        1291 * Returns true if the specified value is a string.
        1292 * @param {?} val Variable to test.
        1293 * @return {boolean} Whether variable is a string.
        1294 */
        1295goog.isString = function(val) {
        1296 return typeof val == 'string';
        1297};
        1298
        1299
        1300/**
        1301 * Returns true if the specified value is a boolean.
        1302 * @param {?} val Variable to test.
        1303 * @return {boolean} Whether variable is boolean.
        1304 */
        1305goog.isBoolean = function(val) {
        1306 return typeof val == 'boolean';
        1307};
        1308
        1309
        1310/**
        1311 * Returns true if the specified value is a number.
        1312 * @param {?} val Variable to test.
        1313 * @return {boolean} Whether variable is a number.
        1314 */
        1315goog.isNumber = function(val) {
        1316 return typeof val == 'number';
        1317};
        1318
        1319
        1320/**
        1321 * Returns true if the specified value is a function.
        1322 * @param {?} val Variable to test.
        1323 * @return {boolean} Whether variable is a function.
        1324 */
        1325goog.isFunction = function(val) {
        1326 return goog.typeOf(val) == 'function';
        1327};
        1328
        1329
        1330/**
        1331 * Returns true if the specified value is an object. This includes arrays and
        1332 * functions.
        1333 * @param {?} val Variable to test.
        1334 * @return {boolean} Whether variable is an object.
        1335 */
        1336goog.isObject = function(val) {
        1337 var type = typeof val;
        1338 return type == 'object' && val != null || type == 'function';
        1339 // return Object(val) === val also works, but is slower, especially if val is
        1340 // not an object.
        1341};
        1342
        1343
        1344/**
        1345 * Gets a unique ID for an object. This mutates the object so that further calls
        1346 * with the same object as a parameter returns the same value. The unique ID is
        1347 * guaranteed to be unique across the current session amongst objects that are
        1348 * passed into {@code getUid}. There is no guarantee that the ID is unique or
        1349 * consistent across sessions. It is unsafe to generate unique ID for function
        1350 * prototypes.
        1351 *
        1352 * @param {Object} obj The object to get the unique ID for.
        1353 * @return {number} The unique ID for the object.
        1354 */
        1355goog.getUid = function(obj) {
        1356 // TODO(arv): Make the type stricter, do not accept null.
        1357
        1358 // In Opera window.hasOwnProperty exists but always returns false so we avoid
        1359 // using it. As a consequence the unique ID generated for BaseClass.prototype
        1360 // and SubClass.prototype will be the same.
        1361 return obj[goog.UID_PROPERTY_] ||
        1362 (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_);
        1363};
        1364
        1365
        1366/**
        1367 * Whether the given object is alreay assigned a unique ID.
        1368 *
        1369 * This does not modify the object.
        1370 *
        1371 * @param {Object} obj The object to check.
        1372 * @return {boolean} Whether there an assigned unique id for the object.
        1373 */
        1374goog.hasUid = function(obj) {
        1375 return !!obj[goog.UID_PROPERTY_];
        1376};
        1377
        1378
        1379/**
        1380 * Removes the unique ID from an object. This is useful if the object was
        1381 * previously mutated using {@code goog.getUid} in which case the mutation is
        1382 * undone.
        1383 * @param {Object} obj The object to remove the unique ID field from.
        1384 */
        1385goog.removeUid = function(obj) {
        1386 // TODO(arv): Make the type stricter, do not accept null.
        1387
        1388 // In IE, DOM nodes are not instances of Object and throw an exception if we
        1389 // try to delete. Instead we try to use removeAttribute.
        1390 if ('removeAttribute' in obj) {
        1391 obj.removeAttribute(goog.UID_PROPERTY_);
        1392 }
        1393 /** @preserveTry */
        1394 try {
        1395 delete obj[goog.UID_PROPERTY_];
        1396 } catch (ex) {
        1397 }
        1398};
        1399
        1400
        1401/**
        1402 * Name for unique ID property. Initialized in a way to help avoid collisions
        1403 * with other closure JavaScript on the same page.
        1404 * @type {string}
        1405 * @private
        1406 */
        1407goog.UID_PROPERTY_ = 'closure_uid_' + ((Math.random() * 1e9) >>> 0);
        1408
        1409
        1410/**
        1411 * Counter for UID.
        1412 * @type {number}
        1413 * @private
        1414 */
        1415goog.uidCounter_ = 0;
        1416
        1417
        1418/**
        1419 * Adds a hash code field to an object. The hash code is unique for the
        1420 * given object.
        1421 * @param {Object} obj The object to get the hash code for.
        1422 * @return {number} The hash code for the object.
        1423 * @deprecated Use goog.getUid instead.
        1424 */
        1425goog.getHashCode = goog.getUid;
        1426
        1427
        1428/**
        1429 * Removes the hash code field from an object.
        1430 * @param {Object} obj The object to remove the field from.
        1431 * @deprecated Use goog.removeUid instead.
        1432 */
        1433goog.removeHashCode = goog.removeUid;
        1434
        1435
        1436/**
        1437 * Clones a value. The input may be an Object, Array, or basic type. Objects and
        1438 * arrays will be cloned recursively.
        1439 *
        1440 * WARNINGS:
        1441 * <code>goog.cloneObject</code> does not detect reference loops. Objects that
        1442 * refer to themselves will cause infinite recursion.
        1443 *
        1444 * <code>goog.cloneObject</code> is unaware of unique identifiers, and copies
        1445 * UIDs created by <code>getUid</code> into cloned results.
        1446 *
        1447 * @param {*} obj The value to clone.
        1448 * @return {*} A clone of the input value.
        1449 * @deprecated goog.cloneObject is unsafe. Prefer the goog.object methods.
        1450 */
        1451goog.cloneObject = function(obj) {
        1452 var type = goog.typeOf(obj);
        1453 if (type == 'object' || type == 'array') {
        1454 if (obj.clone) {
        1455 return obj.clone();
        1456 }
        1457 var clone = type == 'array' ? [] : {};
        1458 for (var key in obj) {
        1459 clone[key] = goog.cloneObject(obj[key]);
        1460 }
        1461 return clone;
        1462 }
        1463
        1464 return obj;
        1465};
        1466
        1467
        1468/**
        1469 * A native implementation of goog.bind.
        1470 * @param {Function} fn A function to partially apply.
        1471 * @param {Object|undefined} selfObj Specifies the object which this should
        1472 * point to when the function is run.
        1473 * @param {...*} var_args Additional arguments that are partially applied to the
        1474 * function.
        1475 * @return {!Function} A partially-applied form of the function bind() was
        1476 * invoked as a method of.
        1477 * @private
        1478 * @suppress {deprecated} The compiler thinks that Function.prototype.bind is
        1479 * deprecated because some people have declared a pure-JS version.
        1480 * Only the pure-JS version is truly deprecated.
        1481 */
        1482goog.bindNative_ = function(fn, selfObj, var_args) {
        1483 return /** @type {!Function} */ (fn.call.apply(fn.bind, arguments));
        1484};
        1485
        1486
        1487/**
        1488 * A pure-JS implementation of goog.bind.
        1489 * @param {Function} fn A function to partially apply.
        1490 * @param {Object|undefined} selfObj Specifies the object which this should
        1491 * point to when the function is run.
        1492 * @param {...*} var_args Additional arguments that are partially applied to the
        1493 * function.
        1494 * @return {!Function} A partially-applied form of the function bind() was
        1495 * invoked as a method of.
        1496 * @private
        1497 */
        1498goog.bindJs_ = function(fn, selfObj, var_args) {
        1499 if (!fn) {
        1500 throw new Error();
        1501 }
        1502
        1503 if (arguments.length > 2) {
        1504 var boundArgs = Array.prototype.slice.call(arguments, 2);
        1505 return function() {
        1506 // Prepend the bound arguments to the current arguments.
        1507 var newArgs = Array.prototype.slice.call(arguments);
        1508 Array.prototype.unshift.apply(newArgs, boundArgs);
        1509 return fn.apply(selfObj, newArgs);
        1510 };
        1511
        1512 } else {
        1513 return function() {
        1514 return fn.apply(selfObj, arguments);
        1515 };
        1516 }
        1517};
        1518
        1519
        1520/**
        1521 * Partially applies this function to a particular 'this object' and zero or
        1522 * more arguments. The result is a new function with some arguments of the first
        1523 * function pre-filled and the value of this 'pre-specified'.
        1524 *
        1525 * Remaining arguments specified at call-time are appended to the pre-specified
        1526 * ones.
        1527 *
        1528 * Also see: {@link #partial}.
        1529 *
        1530 * Usage:
        1531 * <pre>var barMethBound = bind(myFunction, myObj, 'arg1', 'arg2');
        1532 * barMethBound('arg3', 'arg4');</pre>
        1533 *
        1534 * @param {?function(this:T, ...)} fn A function to partially apply.
        1535 * @param {T} selfObj Specifies the object which this should point to when the
        1536 * function is run.
        1537 * @param {...*} var_args Additional arguments that are partially applied to the
        1538 * function.
        1539 * @return {!Function} A partially-applied form of the function bind() was
        1540 * invoked as a method of.
        1541 * @template T
        1542 * @suppress {deprecated} See above.
        1543 */
        1544goog.bind = function(fn, selfObj, var_args) {
        1545 // TODO(nicksantos): narrow the type signature.
        1546 if (Function.prototype.bind &&
        1547 // NOTE(nicksantos): Somebody pulled base.js into the default Chrome
        1548 // extension environment. This means that for Chrome extensions, they get
        1549 // the implementation of Function.prototype.bind that calls goog.bind
        1550 // instead of the native one. Even worse, we don't want to introduce a
        1551 // circular dependency between goog.bind and Function.prototype.bind, so
        1552 // we have to hack this to make sure it works correctly.
        1553 Function.prototype.bind.toString().indexOf('native code') != -1) {
        1554 goog.bind = goog.bindNative_;
        1555 } else {
        1556 goog.bind = goog.bindJs_;
        1557 }
        1558 return goog.bind.apply(null, arguments);
        1559};
        1560
        1561
        1562/**
        1563 * Like bind(), except that a 'this object' is not required. Useful when the
        1564 * target function is already bound.
        1565 *
        1566 * Usage:
        1567 * var g = partial(f, arg1, arg2);
        1568 * g(arg3, arg4);
        1569 *
        1570 * @param {Function} fn A function to partially apply.
        1571 * @param {...*} var_args Additional arguments that are partially applied to fn.
        1572 * @return {!Function} A partially-applied form of the function bind() was
        1573 * invoked as a method of.
        1574 */
        1575goog.partial = function(fn, var_args) {
        1576 var args = Array.prototype.slice.call(arguments, 1);
        1577 return function() {
        1578 // Clone the array (with slice()) and append additional arguments
        1579 // to the existing arguments.
        1580 var newArgs = args.slice();
        1581 newArgs.push.apply(newArgs, arguments);
        1582 return fn.apply(this, newArgs);
        1583 };
        1584};
        1585
        1586
        1587/**
        1588 * Copies all the members of a source object to a target object. This method
        1589 * does not work on all browsers for all objects that contain keys such as
        1590 * toString or hasOwnProperty. Use goog.object.extend for this purpose.
        1591 * @param {Object} target Target.
        1592 * @param {Object} source Source.
        1593 */
        1594goog.mixin = function(target, source) {
        1595 for (var x in source) {
        1596 target[x] = source[x];
        1597 }
        1598
        1599 // For IE7 or lower, the for-in-loop does not contain any properties that are
        1600 // not enumerable on the prototype object (for example, isPrototypeOf from
        1601 // Object.prototype) but also it will not include 'replace' on objects that
        1602 // extend String and change 'replace' (not that it is common for anyone to
        1603 // extend anything except Object).
        1604};
        1605
        1606
        1607/**
        1608 * @return {number} An integer value representing the number of milliseconds
        1609 * between midnight, January 1, 1970 and the current time.
        1610 */
        1611goog.now = (goog.TRUSTED_SITE && Date.now) || (function() {
        1612 // Unary plus operator converts its operand to a number which in the case of
        1613 // a date is done by calling getTime().
        1614 return +new Date();
        1615});
        1616
        1617
        1618/**
        1619 * Evals JavaScript in the global scope. In IE this uses execScript, other
        1620 * browsers use goog.global.eval. If goog.global.eval does not evaluate in the
        1621 * global scope (for example, in Safari), appends a script tag instead.
        1622 * Throws an exception if neither execScript or eval is defined.
        1623 * @param {string} script JavaScript string.
        1624 */
        1625goog.globalEval = function(script) {
        1626 if (goog.global.execScript) {
        1627 goog.global.execScript(script, 'JavaScript');
        1628 } else if (goog.global.eval) {
        1629 // Test to see if eval works
        1630 if (goog.evalWorksForGlobals_ == null) {
        1631 goog.global.eval('var _et_ = 1;');
        1632 if (typeof goog.global['_et_'] != 'undefined') {
        1633 delete goog.global['_et_'];
        1634 goog.evalWorksForGlobals_ = true;
        1635 } else {
        1636 goog.evalWorksForGlobals_ = false;
        1637 }
        1638 }
        1639
        1640 if (goog.evalWorksForGlobals_) {
        1641 goog.global.eval(script);
        1642 } else {
        1643 var doc = goog.global.document;
        1644 var scriptElt = doc.createElement('script');
        1645 scriptElt.type = 'text/javascript';
        1646 scriptElt.defer = false;
        1647 // Note(user): can't use .innerHTML since "t('<test>')" will fail and
        1648 // .text doesn't work in Safari 2. Therefore we append a text node.
        1649 scriptElt.appendChild(doc.createTextNode(script));
        1650 doc.body.appendChild(scriptElt);
        1651 doc.body.removeChild(scriptElt);
        1652 }
        1653 } else {
        1654 throw Error('goog.globalEval not available');
        1655 }
        1656};
        1657
        1658
        1659/**
        1660 * Indicates whether or not we can call 'eval' directly to eval code in the
        1661 * global scope. Set to a Boolean by the first call to goog.globalEval (which
        1662 * empirically tests whether eval works for globals). @see goog.globalEval
        1663 * @type {?boolean}
        1664 * @private
        1665 */
        1666goog.evalWorksForGlobals_ = null;
        1667
        1668
        1669/**
        1670 * Optional map of CSS class names to obfuscated names used with
        1671 * goog.getCssName().
        1672 * @type {Object|undefined}
        1673 * @private
        1674 * @see goog.setCssNameMapping
        1675 */
        1676goog.cssNameMapping_;
        1677
        1678
        1679/**
        1680 * Optional obfuscation style for CSS class names. Should be set to either
        1681 * 'BY_WHOLE' or 'BY_PART' if defined.
        1682 * @type {string|undefined}
        1683 * @private
        1684 * @see goog.setCssNameMapping
        1685 */
        1686goog.cssNameMappingStyle_;
        1687
        1688
        1689/**
        1690 * Handles strings that are intended to be used as CSS class names.
        1691 *
        1692 * This function works in tandem with @see goog.setCssNameMapping.
        1693 *
        1694 * Without any mapping set, the arguments are simple joined with a hyphen and
        1695 * passed through unaltered.
        1696 *
        1697 * When there is a mapping, there are two possible styles in which these
        1698 * mappings are used. In the BY_PART style, each part (i.e. in between hyphens)
        1699 * of the passed in css name is rewritten according to the map. In the BY_WHOLE
        1700 * style, the full css name is looked up in the map directly. If a rewrite is
        1701 * not specified by the map, the compiler will output a warning.
        1702 *
        1703 * When the mapping is passed to the compiler, it will replace calls to
        1704 * goog.getCssName with the strings from the mapping, e.g.
        1705 * var x = goog.getCssName('foo');
        1706 * var y = goog.getCssName(this.baseClass, 'active');
        1707 * becomes:
        1708 * var x= 'foo';
        1709 * var y = this.baseClass + '-active';
        1710 *
        1711 * If one argument is passed it will be processed, if two are passed only the
        1712 * modifier will be processed, as it is assumed the first argument was generated
        1713 * as a result of calling goog.getCssName.
        1714 *
        1715 * @param {string} className The class name.
        1716 * @param {string=} opt_modifier A modifier to be appended to the class name.
        1717 * @return {string} The class name or the concatenation of the class name and
        1718 * the modifier.
        1719 */
        1720goog.getCssName = function(className, opt_modifier) {
        1721 var getMapping = function(cssName) {
        1722 return goog.cssNameMapping_[cssName] || cssName;
        1723 };
        1724
        1725 var renameByParts = function(cssName) {
        1726 // Remap all the parts individually.
        1727 var parts = cssName.split('-');
        1728 var mapped = [];
        1729 for (var i = 0; i < parts.length; i++) {
        1730 mapped.push(getMapping(parts[i]));
        1731 }
        1732 return mapped.join('-');
        1733 };
        1734
        1735 var rename;
        1736 if (goog.cssNameMapping_) {
        1737 rename = goog.cssNameMappingStyle_ == 'BY_WHOLE' ?
        1738 getMapping : renameByParts;
        1739 } else {
        1740 rename = function(a) {
        1741 return a;
        1742 };
        1743 }
        1744
        1745 if (opt_modifier) {
        1746 return className + '-' + rename(opt_modifier);
        1747 } else {
        1748 return rename(className);
        1749 }
        1750};
        1751
        1752
        1753/**
        1754 * Sets the map to check when returning a value from goog.getCssName(). Example:
        1755 * <pre>
        1756 * goog.setCssNameMapping({
        1757 * "goog": "a",
        1758 * "disabled": "b",
        1759 * });
        1760 *
        1761 * var x = goog.getCssName('goog');
        1762 * // The following evaluates to: "a a-b".
        1763 * goog.getCssName('goog') + ' ' + goog.getCssName(x, 'disabled')
        1764 * </pre>
        1765 * When declared as a map of string literals to string literals, the JSCompiler
        1766 * will replace all calls to goog.getCssName() using the supplied map if the
        1767 * --closure_pass flag is set.
        1768 *
        1769 * @param {!Object} mapping A map of strings to strings where keys are possible
        1770 * arguments to goog.getCssName() and values are the corresponding values
        1771 * that should be returned.
        1772 * @param {string=} opt_style The style of css name mapping. There are two valid
        1773 * options: 'BY_PART', and 'BY_WHOLE'.
        1774 * @see goog.getCssName for a description.
        1775 */
        1776goog.setCssNameMapping = function(mapping, opt_style) {
        1777 goog.cssNameMapping_ = mapping;
        1778 goog.cssNameMappingStyle_ = opt_style;
        1779};
        1780
        1781
        1782/**
        1783 * To use CSS renaming in compiled mode, one of the input files should have a
        1784 * call to goog.setCssNameMapping() with an object literal that the JSCompiler
        1785 * can extract and use to replace all calls to goog.getCssName(). In uncompiled
        1786 * mode, JavaScript code should be loaded before this base.js file that declares
        1787 * a global variable, CLOSURE_CSS_NAME_MAPPING, which is used below. This is
        1788 * to ensure that the mapping is loaded before any calls to goog.getCssName()
        1789 * are made in uncompiled mode.
        1790 *
        1791 * A hook for overriding the CSS name mapping.
        1792 * @type {Object|undefined}
        1793 */
        1794goog.global.CLOSURE_CSS_NAME_MAPPING;
        1795
        1796
        1797if (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) {
        1798 // This does not call goog.setCssNameMapping() because the JSCompiler
        1799 // requires that goog.setCssNameMapping() be called with an object literal.
        1800 goog.cssNameMapping_ = goog.global.CLOSURE_CSS_NAME_MAPPING;
        1801}
        1802
        1803
        1804/**
        1805 * Gets a localized message.
        1806 *
        1807 * This function is a compiler primitive. If you give the compiler a localized
        1808 * message bundle, it will replace the string at compile-time with a localized
        1809 * version, and expand goog.getMsg call to a concatenated string.
        1810 *
        1811 * Messages must be initialized in the form:
        1812 * <code>
        1813 * var MSG_NAME = goog.getMsg('Hello {$placeholder}', {'placeholder': 'world'});
        1814 * </code>
        1815 *
        1816 * @param {string} str Translatable string, places holders in the form {$foo}.
        1817 * @param {Object=} opt_values Map of place holder name to value.
        1818 * @return {string} message with placeholders filled.
        1819 */
        1820goog.getMsg = function(str, opt_values) {
        1821 if (opt_values) {
        1822 str = str.replace(/\{\$([^}]+)}/g, function(match, key) {
        1823 return key in opt_values ? opt_values[key] : match;
        1824 });
        1825 }
        1826 return str;
        1827};
        1828
        1829
        1830/**
        1831 * Gets a localized message. If the message does not have a translation, gives a
        1832 * fallback message.
        1833 *
        1834 * This is useful when introducing a new message that has not yet been
        1835 * translated into all languages.
        1836 *
        1837 * This function is a compiler primitive. Must be used in the form:
        1838 * <code>var x = goog.getMsgWithFallback(MSG_A, MSG_B);</code>
        1839 * where MSG_A and MSG_B were initialized with goog.getMsg.
        1840 *
        1841 * @param {string} a The preferred message.
        1842 * @param {string} b The fallback message.
        1843 * @return {string} The best translated message.
        1844 */
        1845goog.getMsgWithFallback = function(a, b) {
        1846 return a;
        1847};
        1848
        1849
        1850/**
        1851 * Exposes an unobfuscated global namespace path for the given object.
        1852 * Note that fields of the exported object *will* be obfuscated, unless they are
        1853 * exported in turn via this function or goog.exportProperty.
        1854 *
        1855 * Also handy for making public items that are defined in anonymous closures.
        1856 *
        1857 * ex. goog.exportSymbol('public.path.Foo', Foo);
        1858 *
        1859 * ex. goog.exportSymbol('public.path.Foo.staticFunction', Foo.staticFunction);
        1860 * public.path.Foo.staticFunction();
        1861 *
        1862 * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod',
        1863 * Foo.prototype.myMethod);
        1864 * new public.path.Foo().myMethod();
        1865 *
        1866 * @param {string} publicPath Unobfuscated name to export.
        1867 * @param {*} object Object the name should point to.
        1868 * @param {Object=} opt_objectToExportTo The object to add the path to; default
        1869 * is goog.global.
        1870 */
        1871goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) {
        1872 goog.exportPath_(publicPath, object, opt_objectToExportTo);
        1873};
        1874
        1875
        1876/**
        1877 * Exports a property unobfuscated into the object's namespace.
        1878 * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction);
        1879 * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod);
        1880 * @param {Object} object Object whose static property is being exported.
        1881 * @param {string} publicName Unobfuscated name to export.
        1882 * @param {*} symbol Object the name should point to.
        1883 */
        1884goog.exportProperty = function(object, publicName, symbol) {
        1885 object[publicName] = symbol;
        1886};
        1887
        1888
        1889/**
        1890 * Inherit the prototype methods from one constructor into another.
        1891 *
        1892 * Usage:
        1893 * <pre>
        1894 * function ParentClass(a, b) { }
        1895 * ParentClass.prototype.foo = function(a) { };
        1896 *
        1897 * function ChildClass(a, b, c) {
        1898 * ChildClass.base(this, 'constructor', a, b);
        1899 * }
        1900 * goog.inherits(ChildClass, ParentClass);
        1901 *
        1902 * var child = new ChildClass('a', 'b', 'see');
        1903 * child.foo(); // This works.
        1904 * </pre>
        1905 *
        1906 * @param {Function} childCtor Child class.
        1907 * @param {Function} parentCtor Parent class.
        1908 */
        1909goog.inherits = function(childCtor, parentCtor) {
        1910 /** @constructor */
        1911 function tempCtor() {};
        1912 tempCtor.prototype = parentCtor.prototype;
        1913 childCtor.superClass_ = parentCtor.prototype;
        1914 childCtor.prototype = new tempCtor();
        1915 /** @override */
        1916 childCtor.prototype.constructor = childCtor;
        1917
        1918 /**
        1919 * Calls superclass constructor/method.
        1920 *
        1921 * This function is only available if you use goog.inherits to
        1922 * express inheritance relationships between classes.
        1923 *
        1924 * NOTE: This is a replacement for goog.base and for superClass_
        1925 * property defined in childCtor.
        1926 *
        1927 * @param {!Object} me Should always be "this".
        1928 * @param {string} methodName The method name to call. Calling
        1929 * superclass constructor can be done with the special string
        1930 * 'constructor'.
        1931 * @param {...*} var_args The arguments to pass to superclass
        1932 * method/constructor.
        1933 * @return {*} The return value of the superclass method/constructor.
        1934 */
        1935 childCtor.base = function(me, methodName, var_args) {
        1936 var args = Array.prototype.slice.call(arguments, 2);
        1937 return parentCtor.prototype[methodName].apply(me, args);
        1938 };
        1939};
        1940
        1941
        1942/**
        1943 * Call up to the superclass.
        1944 *
        1945 * If this is called from a constructor, then this calls the superclass
        1946 * constructor with arguments 1-N.
        1947 *
        1948 * If this is called from a prototype method, then you must pass the name of the
        1949 * method as the second argument to this function. If you do not, you will get a
        1950 * runtime error. This calls the superclass' method with arguments 2-N.
        1951 *
        1952 * This function only works if you use goog.inherits to express inheritance
        1953 * relationships between your classes.
        1954 *
        1955 * This function is a compiler primitive. At compile-time, the compiler will do
        1956 * macro expansion to remove a lot of the extra overhead that this function
        1957 * introduces. The compiler will also enforce a lot of the assumptions that this
        1958 * function makes, and treat it as a compiler error if you break them.
        1959 *
        1960 * @param {!Object} me Should always be "this".
        1961 * @param {*=} opt_methodName The method name if calling a super method.
        1962 * @param {...*} var_args The rest of the arguments.
        1963 * @return {*} The return value of the superclass method.
        1964 * @suppress {es5Strict} This method can not be used in strict mode, but
        1965 * all Closure Library consumers must depend on this file.
        1966 */
        1967goog.base = function(me, opt_methodName, var_args) {
        1968 var caller = arguments.callee.caller;
        1969
        1970 if (goog.STRICT_MODE_COMPATIBLE || (goog.DEBUG && !caller)) {
        1971 throw Error('arguments.caller not defined. goog.base() cannot be used ' +
        1972 'with strict mode code. See ' +
        1973 'http://www.ecma-international.org/ecma-262/5.1/#sec-C');
        1974 }
        1975
        1976 if (caller.superClass_) {
        1977 // This is a constructor. Call the superclass constructor.
        1978 return caller.superClass_.constructor.apply(
        1979 me, Array.prototype.slice.call(arguments, 1));
        1980 }
        1981
        1982 var args = Array.prototype.slice.call(arguments, 2);
        1983 var foundCaller = false;
        1984 for (var ctor = me.constructor;
        1985 ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) {
        1986 if (ctor.prototype[opt_methodName] === caller) {
        1987 foundCaller = true;
        1988 } else if (foundCaller) {
        1989 return ctor.prototype[opt_methodName].apply(me, args);
        1990 }
        1991 }
        1992
        1993 // If we did not find the caller in the prototype chain, then one of two
        1994 // things happened:
        1995 // 1) The caller is an instance method.
        1996 // 2) This method was not called by the right caller.
        1997 if (me[opt_methodName] === caller) {
        1998 return me.constructor.prototype[opt_methodName].apply(me, args);
        1999 } else {
        2000 throw Error(
        2001 'goog.base called from a method of one name ' +
        2002 'to a method of a different name');
        2003 }
        2004};
        2005
        2006
        2007/**
        2008 * Allow for aliasing within scope functions. This function exists for
        2009 * uncompiled code - in compiled code the calls will be inlined and the aliases
        2010 * applied. In uncompiled code the function is simply run since the aliases as
        2011 * written are valid JavaScript.
        2012 *
        2013 *
        2014 * @param {function()} fn Function to call. This function can contain aliases
        2015 * to namespaces (e.g. "var dom = goog.dom") or classes
        2016 * (e.g. "var Timer = goog.Timer").
        2017 */
        2018goog.scope = function(fn) {
        2019 fn.call(goog.global);
        2020};
        2021
        2022
        2023/*
        2024 * To support uncompiled, strict mode bundles that use eval to divide source
        2025 * like so:
        2026 * eval('someSource;//# sourceUrl sourcefile.js');
        2027 * We need to export the globally defined symbols "goog" and "COMPILED".
        2028 * Exporting "goog" breaks the compiler optimizations, so we required that
        2029 * be defined externally.
        2030 * NOTE: We don't use goog.exportSymbol here because we don't want to trigger
        2031 * extern generation when that compiler option is enabled.
        2032 */
        2033if (!COMPILED) {
        2034 goog.global['COMPILED'] = COMPILED;
        2035}
        2036
        2037
        2038
        2039//==============================================================================
        2040// goog.defineClass implementation
        2041//==============================================================================
        2042
        2043/**
        2044 * Creates a restricted form of a Closure "class":
        2045 * - from the compiler's perspective, the instance returned from the
        2046 * constructor is sealed (no new properties may be added). This enables
        2047 * better checks.
        2048 * - the compiler will rewrite this definition to a form that is optimal
        2049 * for type checking and optimization (initially this will be a more
        2050 * traditional form).
        2051 *
        2052 * @param {Function} superClass The superclass, Object or null.
        2053 * @param {goog.defineClass.ClassDescriptor} def
        2054 * An object literal describing the
        2055 * the class. It may have the following properties:
        2056 * "constructor": the constructor function
        2057 * "statics": an object literal containing methods to add to the constructor
        2058 * as "static" methods or a function that will receive the constructor
        2059 * function as its only parameter to which static properties can
        2060 * be added.
        2061 * all other properties are added to the prototype.
        2062 * @return {!Function} The class constructor.
        2063 */
        2064goog.defineClass = function(superClass, def) {
        2065 // TODO(johnlenz): consider making the superClass an optional parameter.
        2066 var constructor = def.constructor;
        2067 var statics = def.statics;
        2068 // Wrap the constructor prior to setting up the prototype and static methods.
        2069 if (!constructor || constructor == Object.prototype.constructor) {
        2070 constructor = function() {
        2071 throw Error('cannot instantiate an interface (no constructor defined).');
        2072 };
        2073 }
        2074
        2075 var cls = goog.defineClass.createSealingConstructor_(constructor, superClass);
        2076 if (superClass) {
        2077 goog.inherits(cls, superClass);
        2078 }
        2079
        2080 // Remove all the properties that should not be copied to the prototype.
        2081 delete def.constructor;
        2082 delete def.statics;
        2083
        2084 goog.defineClass.applyProperties_(cls.prototype, def);
        2085 if (statics != null) {
        2086 if (statics instanceof Function) {
        2087 statics(cls);
        2088 } else {
        2089 goog.defineClass.applyProperties_(cls, statics);
        2090 }
        2091 }
        2092
        2093 return cls;
        2094};
        2095
        2096
        2097/**
        2098 * @typedef {
        2099 * !Object|
        2100 * {constructor:!Function}|
        2101 * {constructor:!Function, statics:(Object|function(Function):void)}}
        2102 */
        2103goog.defineClass.ClassDescriptor;
        2104
        2105
        2106/**
        2107 * @define {boolean} Whether the instances returned by
        2108 * goog.defineClass should be sealed when possible.
        2109 */
        2110goog.define('goog.defineClass.SEAL_CLASS_INSTANCES', goog.DEBUG);
        2111
        2112
        2113/**
        2114 * If goog.defineClass.SEAL_CLASS_INSTANCES is enabled and Object.seal is
        2115 * defined, this function will wrap the constructor in a function that seals the
        2116 * results of the provided constructor function.
        2117 *
        2118 * @param {!Function} ctr The constructor whose results maybe be sealed.
        2119 * @param {Function} superClass The superclass constructor.
        2120 * @return {!Function} The replacement constructor.
        2121 * @private
        2122 */
        2123goog.defineClass.createSealingConstructor_ = function(ctr, superClass) {
        2124 if (goog.defineClass.SEAL_CLASS_INSTANCES &&
        2125 Object.seal instanceof Function) {
        2126 // Don't seal subclasses of unsealable-tagged legacy classes.
        2127 if (superClass && superClass.prototype &&
        2128 superClass.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_]) {
        2129 return ctr;
        2130 }
        2131 /** @this {*} */
        2132 var wrappedCtr = function() {
        2133 // Don't seal an instance of a subclass when it calls the constructor of
        2134 // its super class as there is most likely still setup to do.
        2135 var instance = ctr.apply(this, arguments) || this;
        2136 instance[goog.UID_PROPERTY_] = instance[goog.UID_PROPERTY_];
        2137 if (this.constructor === wrappedCtr) {
        2138 Object.seal(instance);
        2139 }
        2140 return instance;
        2141 };
        2142 return wrappedCtr;
        2143 }
        2144 return ctr;
        2145};
        2146
        2147
        2148// TODO(johnlenz): share these values with the goog.object
        2149/**
        2150 * The names of the fields that are defined on Object.prototype.
        2151 * @type {!Array.<string>}
        2152 * @private
        2153 * @const
        2154 */
        2155goog.defineClass.OBJECT_PROTOTYPE_FIELDS_ = [
        2156 'constructor',
        2157 'hasOwnProperty',
        2158 'isPrototypeOf',
        2159 'propertyIsEnumerable',
        2160 'toLocaleString',
        2161 'toString',
        2162 'valueOf'
        2163];
        2164
        2165
        2166// TODO(johnlenz): share this function with the goog.object
        2167/**
        2168 * @param {!Object} target The object to add properties to.
        2169 * @param {!Object} source The object to copy properites from.
        2170 * @private
        2171 */
        2172goog.defineClass.applyProperties_ = function(target, source) {
        2173 // TODO(johnlenz): update this to support ES5 getters/setters
        2174
        2175 var key;
        2176 for (key in source) {
        2177 if (Object.prototype.hasOwnProperty.call(source, key)) {
        2178 target[key] = source[key];
        2179 }
        2180 }
        2181
        2182 // For IE the for-in-loop does not contain any properties that are not
        2183 // enumerable on the prototype object (for example isPrototypeOf from
        2184 // Object.prototype) and it will also not include 'replace' on objects that
        2185 // extend String and change 'replace' (not that it is common for anyone to
        2186 // extend anything except Object).
        2187 for (var i = 0; i < goog.defineClass.OBJECT_PROTOTYPE_FIELDS_.length; i++) {
        2188 key = goog.defineClass.OBJECT_PROTOTYPE_FIELDS_[i];
        2189 if (Object.prototype.hasOwnProperty.call(source, key)) {
        2190 target[key] = source[key];
        2191 }
        2192 }
        2193};
        2194
        2195
        2196/**
        2197 * Sealing classes breaks the older idiom of assigning properties on the
        2198 * prototype rather than in the constructor. As such, goog.defineClass
        2199 * must not seal subclasses of these old-style classes until they are fixed.
        2200 * Until then, this marks a class as "broken", instructing defineClass
        2201 * not to seal subclasses.
        2202 * @param {!Function} ctr The legacy constructor to tag as unsealable.
        2203 */
        2204goog.tagUnsealableClass = function(ctr) {
        2205 if (!COMPILED && goog.defineClass.SEAL_CLASS_INSTANCES) {
        2206 ctr.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_] = true;
        2207 }
        2208};
        2209
        2210
        2211/**
        2212 * Name for unsealable tag property.
        2213 * @const @private {string}
        2214 */
        2215goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_ = 'goog_defineClass_legacy_unsealable';
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/debug/debug.js.src.html b/docs/api/javascript/source/lib/goog/debug/debug.js.src.html new file mode 100644 index 0000000000000..1a2daf455ef2d --- /dev/null +++ b/docs/api/javascript/source/lib/goog/debug/debug.js.src.html @@ -0,0 +1 @@ +debug.js

        lib/goog/debug/debug.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 Logging and debugging utilities.
        17 *
        18 * @see ../demos/debug.html
        19 */
        20
        21goog.provide('goog.debug');
        22
        23goog.require('goog.array');
        24goog.require('goog.string');
        25goog.require('goog.structs.Set');
        26goog.require('goog.userAgent');
        27
        28
        29/** @define {boolean} Whether logging should be enabled. */
        30goog.define('goog.debug.LOGGING_ENABLED', goog.DEBUG);
        31
        32
        33/**
        34 * Catches onerror events fired by windows and similar objects.
        35 * @param {function(Object)} logFunc The function to call with the error
        36 * information.
        37 * @param {boolean=} opt_cancel Whether to stop the error from reaching the
        38 * browser.
        39 * @param {Object=} opt_target Object that fires onerror events.
        40 */
        41goog.debug.catchErrors = function(logFunc, opt_cancel, opt_target) {
        42 var target = opt_target || goog.global;
        43 var oldErrorHandler = target.onerror;
        44 var retVal = !!opt_cancel;
        45
        46 // Chrome interprets onerror return value backwards (http://crbug.com/92062)
        47 // until it was fixed in webkit revision r94061 (Webkit 535.3). This
        48 // workaround still needs to be skipped in Safari after the webkit change
        49 // gets pushed out in Safari.
        50 // See https://bugs.webkit.org/show_bug.cgi?id=67119
        51 if (goog.userAgent.WEBKIT &&
        52 !goog.userAgent.isVersionOrHigher('535.3')) {
        53 retVal = !retVal;
        54 }
        55
        56 /**
        57 * New onerror handler for this target. This onerror handler follows the spec
        58 * according to
        59 * http://www.whatwg.org/specs/web-apps/current-work/#runtime-script-errors
        60 * The spec was changed in August 2013 to support receiving column information
        61 * and an error object for all scripts on the same origin or cross origin
        62 * scripts with the proper headers. See
        63 * https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror
        64 *
        65 * @param {string} message The error message. For cross-origin errors, this
        66 * will be scrubbed to just "Script error.". For new browsers that have
        67 * updated to follow the latest spec, errors that come from origins that
        68 * have proper cross origin headers will not be scrubbed.
        69 * @param {string} url The URL of the script that caused the error. The URL
        70 * will be scrubbed to "" for cross origin scripts unless the script has
        71 * proper cross origin headers and the browser has updated to the latest
        72 * spec.
        73 * @param {number} line The line number in the script that the error
        74 * occurred on.
        75 * @param {number=} opt_col The optional column number that the error
        76 * occurred on. Only browsers that have updated to the latest spec will
        77 * include this.
        78 * @param {Error=} opt_error The optional actual error object for this
        79 * error that should include the stack. Only browsers that have updated
        80 * to the latest spec will inlude this parameter.
        81 * @return {boolean} Whether to prevent the error from reaching the browser.
        82 */
        83 target.onerror = function(message, url, line, opt_col, opt_error) {
        84 if (oldErrorHandler) {
        85 oldErrorHandler(message, url, line, opt_col, opt_error);
        86 }
        87 logFunc({
        88 message: message,
        89 fileName: url,
        90 line: line,
        91 col: opt_col,
        92 error: opt_error
        93 });
        94 return retVal;
        95 };
        96};
        97
        98
        99/**
        100 * Creates a string representing an object and all its properties.
        101 * @param {Object|null|undefined} obj Object to expose.
        102 * @param {boolean=} opt_showFn Show the functions as well as the properties,
        103 * default is false.
        104 * @return {string} The string representation of {@code obj}.
        105 */
        106goog.debug.expose = function(obj, opt_showFn) {
        107 if (typeof obj == 'undefined') {
        108 return 'undefined';
        109 }
        110 if (obj == null) {
        111 return 'NULL';
        112 }
        113 var str = [];
        114
        115 for (var x in obj) {
        116 if (!opt_showFn && goog.isFunction(obj[x])) {
        117 continue;
        118 }
        119 var s = x + ' = ';
        120 /** @preserveTry */
        121 try {
        122 s += obj[x];
        123 } catch (e) {
        124 s += '*** ' + e + ' ***';
        125 }
        126 str.push(s);
        127 }
        128 return str.join('\n');
        129};
        130
        131
        132/**
        133 * Creates a string representing a given primitive or object, and for an
        134 * object, all its properties and nested objects. WARNING: If an object is
        135 * given, it and all its nested objects will be modified. To detect reference
        136 * cycles, this method identifies objects using goog.getUid() which mutates the
        137 * object.
        138 * @param {*} obj Object to expose.
        139 * @param {boolean=} opt_showFn Also show properties that are functions (by
        140 * default, functions are omitted).
        141 * @return {string} A string representation of {@code obj}.
        142 */
        143goog.debug.deepExpose = function(obj, opt_showFn) {
        144 var str = [];
        145
        146 var helper = function(obj, space, parentSeen) {
        147 var nestspace = space + ' ';
        148 var seen = new goog.structs.Set(parentSeen);
        149
        150 var indentMultiline = function(str) {
        151 return str.replace(/\n/g, '\n' + space);
        152 };
        153
        154 /** @preserveTry */
        155 try {
        156 if (!goog.isDef(obj)) {
        157 str.push('undefined');
        158 } else if (goog.isNull(obj)) {
        159 str.push('NULL');
        160 } else if (goog.isString(obj)) {
        161 str.push('"' + indentMultiline(obj) + '"');
        162 } else if (goog.isFunction(obj)) {
        163 str.push(indentMultiline(String(obj)));
        164 } else if (goog.isObject(obj)) {
        165 if (seen.contains(obj)) {
        166 str.push('*** reference loop detected ***');
        167 } else {
        168 seen.add(obj);
        169 str.push('{');
        170 for (var x in obj) {
        171 if (!opt_showFn && goog.isFunction(obj[x])) {
        172 continue;
        173 }
        174 str.push('\n');
        175 str.push(nestspace);
        176 str.push(x + ' = ');
        177 helper(obj[x], nestspace, seen);
        178 }
        179 str.push('\n' + space + '}');
        180 }
        181 } else {
        182 str.push(obj);
        183 }
        184 } catch (e) {
        185 str.push('*** ' + e + ' ***');
        186 }
        187 };
        188
        189 helper(obj, '', new goog.structs.Set());
        190 return str.join('');
        191};
        192
        193
        194/**
        195 * Recursively outputs a nested array as a string.
        196 * @param {Array} arr The array.
        197 * @return {string} String representing nested array.
        198 */
        199goog.debug.exposeArray = function(arr) {
        200 var str = [];
        201 for (var i = 0; i < arr.length; i++) {
        202 if (goog.isArray(arr[i])) {
        203 str.push(goog.debug.exposeArray(arr[i]));
        204 } else {
        205 str.push(arr[i]);
        206 }
        207 }
        208 return '[ ' + str.join(', ') + ' ]';
        209};
        210
        211
        212/**
        213 * Exposes an exception that has been caught by a try...catch and outputs the
        214 * error with a stack trace.
        215 * @param {Object} err Error object or string.
        216 * @param {Function=} opt_fn Optional function to start stack trace from.
        217 * @return {string} Details of exception.
        218 */
        219goog.debug.exposeException = function(err, opt_fn) {
        220 /** @preserveTry */
        221 try {
        222 var e = goog.debug.normalizeErrorObject(err);
        223
        224 // Create the error message
        225 var error = 'Message: ' + goog.string.htmlEscape(e.message) +
        226 '\nUrl: <a href="view-source:' + e.fileName + '" target="_new">' +
        227 e.fileName + '</a>\nLine: ' + e.lineNumber + '\n\nBrowser stack:\n' +
        228 goog.string.htmlEscape(e.stack + '-> ') +
        229 '[end]\n\nJS stack traversal:\n' + goog.string.htmlEscape(
        230 goog.debug.getStacktrace(opt_fn) + '-> ');
        231 return error;
        232 } catch (e2) {
        233 return 'Exception trying to expose exception! You win, we lose. ' + e2;
        234 }
        235};
        236
        237
        238/**
        239 * Normalizes the error/exception object between browsers.
        240 * @param {Object} err Raw error object.
        241 * @return {!Object} Normalized error object.
        242 */
        243goog.debug.normalizeErrorObject = function(err) {
        244 var href = goog.getObjectByName('window.location.href');
        245 if (goog.isString(err)) {
        246 return {
        247 'message': err,
        248 'name': 'Unknown error',
        249 'lineNumber': 'Not available',
        250 'fileName': href,
        251 'stack': 'Not available'
        252 };
        253 }
        254
        255 var lineNumber, fileName;
        256 var threwError = false;
        257
        258 try {
        259 lineNumber = err.lineNumber || err.line || 'Not available';
        260 } catch (e) {
        261 // Firefox 2 sometimes throws an error when accessing 'lineNumber':
        262 // Message: Permission denied to get property UnnamedClass.lineNumber
        263 lineNumber = 'Not available';
        264 threwError = true;
        265 }
        266
        267 try {
        268 fileName = err.fileName || err.filename || err.sourceURL ||
        269 // $googDebugFname may be set before a call to eval to set the filename
        270 // that the eval is supposed to present.
        271 goog.global['$googDebugFname'] || href;
        272 } catch (e) {
        273 // Firefox 2 may also throw an error when accessing 'filename'.
        274 fileName = 'Not available';
        275 threwError = true;
        276 }
        277
        278 // The IE Error object contains only the name and the message.
        279 // The Safari Error object uses the line and sourceURL fields.
        280 if (threwError || !err.lineNumber || !err.fileName || !err.stack ||
        281 !err.message || !err.name) {
        282 return {
        283 'message': err.message || 'Not available',
        284 'name': err.name || 'UnknownError',
        285 'lineNumber': lineNumber,
        286 'fileName': fileName,
        287 'stack': err.stack || 'Not available'
        288 };
        289 }
        290
        291 // Standards error object
        292 return err;
        293};
        294
        295
        296/**
        297 * Converts an object to an Error if it's a String,
        298 * adds a stacktrace if there isn't one,
        299 * and optionally adds an extra message.
        300 * @param {Error|string} err the original thrown object or string.
        301 * @param {string=} opt_message optional additional message to add to the
        302 * error.
        303 * @return {!Error} If err is a string, it is used to create a new Error,
        304 * which is enhanced and returned. Otherwise err itself is enhanced
        305 * and returned.
        306 */
        307goog.debug.enhanceError = function(err, opt_message) {
        308 var error;
        309 if (typeof err == 'string') {
        310 error = Error(err);
        311 if (Error.captureStackTrace) {
        312 // Trim this function off the call stack, if we can.
        313 Error.captureStackTrace(error, goog.debug.enhanceError);
        314 }
        315 } else {
        316 error = err;
        317 }
        318
        319 if (!error.stack) {
        320 error.stack = goog.debug.getStacktrace(goog.debug.enhanceError);
        321 }
        322 if (opt_message) {
        323 // find the first unoccupied 'messageX' property
        324 var x = 0;
        325 while (error['message' + x]) {
        326 ++x;
        327 }
        328 error['message' + x] = String(opt_message);
        329 }
        330 return error;
        331};
        332
        333
        334/**
        335 * Gets the current stack trace. Simple and iterative - doesn't worry about
        336 * catching circular references or getting the args.
        337 * @param {number=} opt_depth Optional maximum depth to trace back to.
        338 * @return {string} A string with the function names of all functions in the
        339 * stack, separated by \n.
        340 * @suppress {es5Strict}
        341 */
        342goog.debug.getStacktraceSimple = function(opt_depth) {
        343 if (goog.STRICT_MODE_COMPATIBLE) {
        344 var stack = goog.debug.getNativeStackTrace_(goog.debug.getStacktraceSimple);
        345 if (stack) {
        346 return stack;
        347 }
        348 // NOTE: browsers that have strict mode support also have native "stack"
        349 // properties. Fall-through for legacy browser support.
        350 }
        351
        352 var sb = [];
        353 var fn = arguments.callee.caller;
        354 var depth = 0;
        355
        356 while (fn && (!opt_depth || depth < opt_depth)) {
        357 sb.push(goog.debug.getFunctionName(fn));
        358 sb.push('()\n');
        359 /** @preserveTry */
        360 try {
        361 fn = fn.caller;
        362 } catch (e) {
        363 sb.push('[exception trying to get caller]\n');
        364 break;
        365 }
        366 depth++;
        367 if (depth >= goog.debug.MAX_STACK_DEPTH) {
        368 sb.push('[...long stack...]');
        369 break;
        370 }
        371 }
        372 if (opt_depth && depth >= opt_depth) {
        373 sb.push('[...reached max depth limit...]');
        374 } else {
        375 sb.push('[end]');
        376 }
        377
        378 return sb.join('');
        379};
        380
        381
        382/**
        383 * Max length of stack to try and output
        384 * @type {number}
        385 */
        386goog.debug.MAX_STACK_DEPTH = 50;
        387
        388
        389/**
        390 * @param {Function} fn The function to start getting the trace from.
        391 * @return {?string}
        392 * @private
        393 */
        394goog.debug.getNativeStackTrace_ = function(fn) {
        395 var tempErr = new Error();
        396 if (Error.captureStackTrace) {
        397 Error.captureStackTrace(tempErr, fn);
        398 return String(tempErr.stack);
        399 } else {
        400 // IE10, only adds stack traces when an exception is thrown.
        401 try {
        402 throw tempErr;
        403 } catch (e) {
        404 tempErr = e;
        405 }
        406 var stack = tempErr.stack;
        407 if (stack) {
        408 return String(stack);
        409 }
        410 }
        411 return null;
        412};
        413
        414
        415/**
        416 * Gets the current stack trace, either starting from the caller or starting
        417 * from a specified function that's currently on the call stack.
        418 * @param {Function=} opt_fn Optional function to start getting the trace from.
        419 * If not provided, defaults to the function that called this.
        420 * @return {string} Stack trace.
        421 * @suppress {es5Strict}
        422 */
        423goog.debug.getStacktrace = function(opt_fn) {
        424 var stack;
        425 if (goog.STRICT_MODE_COMPATIBLE) {
        426 // Try to get the stack trace from the environment if it is available.
        427 var contextFn = opt_fn || goog.debug.getStacktrace;
        428 stack = goog.debug.getNativeStackTrace_(contextFn);
        429 }
        430 if (!stack) {
        431 // NOTE: browsers that have strict mode support also have native "stack"
        432 // properties. This function will throw in strict mode.
        433 stack = goog.debug.getStacktraceHelper_(
        434 opt_fn || arguments.callee.caller, []);
        435 }
        436 return stack;
        437};
        438
        439
        440/**
        441 * Private helper for getStacktrace().
        442 * @param {Function} fn Function to start getting the trace from.
        443 * @param {Array} visited List of functions visited so far.
        444 * @return {string} Stack trace starting from function fn.
        445 * @suppress {es5Strict}
        446 * @private
        447 */
        448goog.debug.getStacktraceHelper_ = function(fn, visited) {
        449 var sb = [];
        450
        451 // Circular reference, certain functions like bind seem to cause a recursive
        452 // loop so we need to catch circular references
        453 if (goog.array.contains(visited, fn)) {
        454 sb.push('[...circular reference...]');
        455
        456 // Traverse the call stack until function not found or max depth is reached
        457 } else if (fn && visited.length < goog.debug.MAX_STACK_DEPTH) {
        458 sb.push(goog.debug.getFunctionName(fn) + '(');
        459 var args = fn.arguments;
        460 // Args may be null for some special functions such as host objects or eval.
        461 for (var i = 0; args && i < args.length; i++) {
        462 if (i > 0) {
        463 sb.push(', ');
        464 }
        465 var argDesc;
        466 var arg = args[i];
        467 switch (typeof arg) {
        468 case 'object':
        469 argDesc = arg ? 'object' : 'null';
        470 break;
        471
        472 case 'string':
        473 argDesc = arg;
        474 break;
        475
        476 case 'number':
        477 argDesc = String(arg);
        478 break;
        479
        480 case 'boolean':
        481 argDesc = arg ? 'true' : 'false';
        482 break;
        483
        484 case 'function':
        485 argDesc = goog.debug.getFunctionName(arg);
        486 argDesc = argDesc ? argDesc : '[fn]';
        487 break;
        488
        489 case 'undefined':
        490 default:
        491 argDesc = typeof arg;
        492 break;
        493 }
        494
        495 if (argDesc.length > 40) {
        496 argDesc = argDesc.substr(0, 40) + '...';
        497 }
        498 sb.push(argDesc);
        499 }
        500 visited.push(fn);
        501 sb.push(')\n');
        502 /** @preserveTry */
        503 try {
        504 sb.push(goog.debug.getStacktraceHelper_(fn.caller, visited));
        505 } catch (e) {
        506 sb.push('[exception trying to get caller]\n');
        507 }
        508
        509 } else if (fn) {
        510 sb.push('[...long stack...]');
        511 } else {
        512 sb.push('[end]');
        513 }
        514 return sb.join('');
        515};
        516
        517
        518/**
        519 * Set a custom function name resolver.
        520 * @param {function(Function): string} resolver Resolves functions to their
        521 * names.
        522 */
        523goog.debug.setFunctionResolver = function(resolver) {
        524 goog.debug.fnNameResolver_ = resolver;
        525};
        526
        527
        528/**
        529 * Gets a function name
        530 * @param {Function} fn Function to get name of.
        531 * @return {string} Function's name.
        532 */
        533goog.debug.getFunctionName = function(fn) {
        534 if (goog.debug.fnNameCache_[fn]) {
        535 return goog.debug.fnNameCache_[fn];
        536 }
        537 if (goog.debug.fnNameResolver_) {
        538 var name = goog.debug.fnNameResolver_(fn);
        539 if (name) {
        540 goog.debug.fnNameCache_[fn] = name;
        541 return name;
        542 }
        543 }
        544
        545 // Heuristically determine function name based on code.
        546 var functionSource = String(fn);
        547 if (!goog.debug.fnNameCache_[functionSource]) {
        548 var matches = /function ([^\(]+)/.exec(functionSource);
        549 if (matches) {
        550 var method = matches[1];
        551 goog.debug.fnNameCache_[functionSource] = method;
        552 } else {
        553 goog.debug.fnNameCache_[functionSource] = '[Anonymous]';
        554 }
        555 }
        556
        557 return goog.debug.fnNameCache_[functionSource];
        558};
        559
        560
        561/**
        562 * Makes whitespace visible by replacing it with printable characters.
        563 * This is useful in finding diffrences between the expected and the actual
        564 * output strings of a testcase.
        565 * @param {string} string whose whitespace needs to be made visible.
        566 * @return {string} string whose whitespace is made visible.
        567 */
        568goog.debug.makeWhitespaceVisible = function(string) {
        569 return string.replace(/ /g, '[_]')
        570 .replace(/\f/g, '[f]')
        571 .replace(/\n/g, '[n]\n')
        572 .replace(/\r/g, '[r]')
        573 .replace(/\t/g, '[t]');
        574};
        575
        576
        577/**
        578 * Hash map for storing function names that have already been looked up.
        579 * @type {Object}
        580 * @private
        581 */
        582goog.debug.fnNameCache_ = {};
        583
        584
        585/**
        586 * Resolves functions to their names. Resolved function names will be cached.
        587 * @type {function(Function):string}
        588 * @private
        589 */
        590goog.debug.fnNameResolver_;
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/debug/entrypointregistry.js.src.html b/docs/api/javascript/source/lib/goog/debug/entrypointregistry.js.src.html new file mode 100644 index 0000000000000..f9c3433bf3338 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/debug/entrypointregistry.js.src.html @@ -0,0 +1 @@ +entrypointregistry.js

        lib/goog/debug/entrypointregistry.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 A global registry for entry points into a program,
        17 * so that they can be instrumented. Each module should register their
        18 * entry points with this registry. Designed to be compiled out
        19 * if no instrumentation is requested.
        20 *
        21 * Entry points may be registered before or after a call to
        22 * goog.debug.entryPointRegistry.monitorAll. If an entry point is registered
        23 * later, the existing monitor will instrument the new entry point.
        24 *
        25 * @author nicksantos@google.com (Nick Santos)
        26 */
        27
        28goog.provide('goog.debug.EntryPointMonitor');
        29goog.provide('goog.debug.entryPointRegistry');
        30
        31goog.require('goog.asserts');
        32
        33
        34
        35/**
        36 * @interface
        37 */
        38goog.debug.EntryPointMonitor = function() {};
        39
        40
        41/**
        42 * Instruments a function.
        43 *
        44 * @param {!Function} fn A function to instrument.
        45 * @return {!Function} The instrumented function.
        46 */
        47goog.debug.EntryPointMonitor.prototype.wrap;
        48
        49
        50/**
        51 * Try to remove an instrumentation wrapper created by this monitor.
        52 * If the function passed to unwrap is not a wrapper created by this
        53 * monitor, then we will do nothing.
        54 *
        55 * Notice that some wrappers may not be unwrappable. For example, if other
        56 * monitors have applied their own wrappers, then it will be impossible to
        57 * unwrap them because their wrappers will have captured our wrapper.
        58 *
        59 * So it is important that entry points are unwrapped in the reverse
        60 * order that they were wrapped.
        61 *
        62 * @param {!Function} fn A function to unwrap.
        63 * @return {!Function} The unwrapped function, or {@code fn} if it was not
        64 * a wrapped function created by this monitor.
        65 */
        66goog.debug.EntryPointMonitor.prototype.unwrap;
        67
        68
        69/**
        70 * An array of entry point callbacks.
        71 * @type {!Array.<function(!Function)>}
        72 * @private
        73 */
        74goog.debug.entryPointRegistry.refList_ = [];
        75
        76
        77/**
        78 * Monitors that should wrap all the entry points.
        79 * @type {!Array.<!goog.debug.EntryPointMonitor>}
        80 * @private
        81 */
        82goog.debug.entryPointRegistry.monitors_ = [];
        83
        84
        85/**
        86 * Whether goog.debug.entryPointRegistry.monitorAll has ever been called.
        87 * Checking this allows the compiler to optimize out the registrations.
        88 * @type {boolean}
        89 * @private
        90 */
        91goog.debug.entryPointRegistry.monitorsMayExist_ = false;
        92
        93
        94/**
        95 * Register an entry point with this module.
        96 *
        97 * The entry point will be instrumented when a monitor is passed to
        98 * goog.debug.entryPointRegistry.monitorAll. If this has already occurred, the
        99 * entry point is instrumented immediately.
        100 *
        101 * @param {function(!Function)} callback A callback function which is called
        102 * with a transforming function to instrument the entry point. The callback
        103 * is responsible for wrapping the relevant entry point with the
        104 * transforming function.
        105 */
        106goog.debug.entryPointRegistry.register = function(callback) {
        107 // Don't use push(), so that this can be compiled out.
        108 goog.debug.entryPointRegistry.refList_[
        109 goog.debug.entryPointRegistry.refList_.length] = callback;
        110 // If no one calls monitorAll, this can be compiled out.
        111 if (goog.debug.entryPointRegistry.monitorsMayExist_) {
        112 var monitors = goog.debug.entryPointRegistry.monitors_;
        113 for (var i = 0; i < monitors.length; i++) {
        114 callback(goog.bind(monitors[i].wrap, monitors[i]));
        115 }
        116 }
        117};
        118
        119
        120/**
        121 * Configures a monitor to wrap all entry points.
        122 *
        123 * Entry points that have already been registered are immediately wrapped by
        124 * the monitor. When an entry point is registered in the future, it will also
        125 * be wrapped by the monitor when it is registered.
        126 *
        127 * @param {!goog.debug.EntryPointMonitor} monitor An entry point monitor.
        128 */
        129goog.debug.entryPointRegistry.monitorAll = function(monitor) {
        130 goog.debug.entryPointRegistry.monitorsMayExist_ = true;
        131 var transformer = goog.bind(monitor.wrap, monitor);
        132 for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) {
        133 goog.debug.entryPointRegistry.refList_[i](transformer);
        134 }
        135 goog.debug.entryPointRegistry.monitors_.push(monitor);
        136};
        137
        138
        139/**
        140 * Try to unmonitor all the entry points that have already been registered. If
        141 * an entry point is registered in the future, it will not be wrapped by the
        142 * monitor when it is registered. Note that this may fail if the entry points
        143 * have additional wrapping.
        144 *
        145 * @param {!goog.debug.EntryPointMonitor} monitor The last monitor to wrap
        146 * the entry points.
        147 * @throws {Error} If the monitor is not the most recently configured monitor.
        148 */
        149goog.debug.entryPointRegistry.unmonitorAllIfPossible = function(monitor) {
        150 var monitors = goog.debug.entryPointRegistry.monitors_;
        151 goog.asserts.assert(monitor == monitors[monitors.length - 1],
        152 'Only the most recent monitor can be unwrapped.');
        153 var transformer = goog.bind(monitor.unwrap, monitor);
        154 for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) {
        155 goog.debug.entryPointRegistry.refList_[i](transformer);
        156 }
        157 monitors.length--;
        158};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/debug/error.js.src.html b/docs/api/javascript/source/lib/goog/debug/error.js.src.html index e0d429571fdd9..37dee8340a451 100644 --- a/docs/api/javascript/source/lib/goog/debug/error.js.src.html +++ b/docs/api/javascript/source/lib/goog/debug/error.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/debug/logbuffer.js.src.html b/docs/api/javascript/source/lib/goog/debug/logbuffer.js.src.html new file mode 100644 index 0000000000000..901499c13b5d4 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/debug/logbuffer.js.src.html @@ -0,0 +1 @@ +logbuffer.js

        lib/goog/debug/logbuffer.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 A buffer for log records. The purpose of this is to improve
        17 * logging performance by re-using old objects when the buffer becomes full and
        18 * to eliminate the need for each app to implement their own log buffer. The
        19 * disadvantage to doing this is that log handlers cannot maintain references to
        20 * log records and expect that they are not overwriten at a later point.
        21 *
        22 * @author agrieve@google.com (Andrew Grieve)
        23 */
        24
        25goog.provide('goog.debug.LogBuffer');
        26
        27goog.require('goog.asserts');
        28goog.require('goog.debug.LogRecord');
        29
        30
        31
        32/**
        33 * Creates the log buffer.
        34 * @constructor
        35 * @final
        36 */
        37goog.debug.LogBuffer = function() {
        38 goog.asserts.assert(goog.debug.LogBuffer.isBufferingEnabled(),
        39 'Cannot use goog.debug.LogBuffer without defining ' +
        40 'goog.debug.LogBuffer.CAPACITY.');
        41 this.clear();
        42};
        43
        44
        45/**
        46 * A static method that always returns the same instance of LogBuffer.
        47 * @return {!goog.debug.LogBuffer} The LogBuffer singleton instance.
        48 */
        49goog.debug.LogBuffer.getInstance = function() {
        50 if (!goog.debug.LogBuffer.instance_) {
        51 // This function is written with the return statement after the assignment
        52 // to avoid the jscompiler StripCode bug described in http://b/2608064.
        53 // After that bug is fixed this can be refactored.
        54 goog.debug.LogBuffer.instance_ = new goog.debug.LogBuffer();
        55 }
        56 return goog.debug.LogBuffer.instance_;
        57};
        58
        59
        60/**
        61 * @define {number} The number of log records to buffer. 0 means disable
        62 * buffering.
        63 */
        64goog.define('goog.debug.LogBuffer.CAPACITY', 0);
        65
        66
        67/**
        68 * The array to store the records.
        69 * @type {!Array.<!goog.debug.LogRecord|undefined>}
        70 * @private
        71 */
        72goog.debug.LogBuffer.prototype.buffer_;
        73
        74
        75/**
        76 * The index of the most recently added record or -1 if there are no records.
        77 * @type {number}
        78 * @private
        79 */
        80goog.debug.LogBuffer.prototype.curIndex_;
        81
        82
        83/**
        84 * Whether the buffer is at capacity.
        85 * @type {boolean}
        86 * @private
        87 */
        88goog.debug.LogBuffer.prototype.isFull_;
        89
        90
        91/**
        92 * Adds a log record to the buffer, possibly overwriting the oldest record.
        93 * @param {goog.debug.Logger.Level} level One of the level identifiers.
        94 * @param {string} msg The string message.
        95 * @param {string} loggerName The name of the source logger.
        96 * @return {!goog.debug.LogRecord} The log record.
        97 */
        98goog.debug.LogBuffer.prototype.addRecord = function(level, msg, loggerName) {
        99 var curIndex = (this.curIndex_ + 1) % goog.debug.LogBuffer.CAPACITY;
        100 this.curIndex_ = curIndex;
        101 if (this.isFull_) {
        102 var ret = this.buffer_[curIndex];
        103 ret.reset(level, msg, loggerName);
        104 return ret;
        105 }
        106 this.isFull_ = curIndex == goog.debug.LogBuffer.CAPACITY - 1;
        107 return this.buffer_[curIndex] =
        108 new goog.debug.LogRecord(level, msg, loggerName);
        109};
        110
        111
        112/**
        113 * @return {boolean} Whether the log buffer is enabled.
        114 */
        115goog.debug.LogBuffer.isBufferingEnabled = function() {
        116 return goog.debug.LogBuffer.CAPACITY > 0;
        117};
        118
        119
        120/**
        121 * Removes all buffered log records.
        122 */
        123goog.debug.LogBuffer.prototype.clear = function() {
        124 this.buffer_ = new Array(goog.debug.LogBuffer.CAPACITY);
        125 this.curIndex_ = -1;
        126 this.isFull_ = false;
        127};
        128
        129
        130/**
        131 * Calls the given function for each buffered log record, starting with the
        132 * oldest one.
        133 * @param {function(!goog.debug.LogRecord)} func The function to call.
        134 */
        135goog.debug.LogBuffer.prototype.forEachRecord = function(func) {
        136 var buffer = this.buffer_;
        137 // Corner case: no records.
        138 if (!buffer[0]) {
        139 return;
        140 }
        141 var curIndex = this.curIndex_;
        142 var i = this.isFull_ ? curIndex : -1;
        143 do {
        144 i = (i + 1) % goog.debug.LogBuffer.CAPACITY;
        145 func(/** @type {!goog.debug.LogRecord} */ (buffer[i]));
        146 } while (i != curIndex);
        147};
        148
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/debug/logger.js.src.html b/docs/api/javascript/source/lib/goog/debug/logger.js.src.html new file mode 100644 index 0000000000000..a0c8db19a9375 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/debug/logger.js.src.html @@ -0,0 +1 @@ +logger.js

        lib/goog/debug/logger.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 the Logger class. Please minimize dependencies
        17 * this file has on other closure classes as any dependency it takes won't be
        18 * able to use the logging infrastructure.
        19 *
        20 * @see ../demos/debug.html
        21 */
        22
        23goog.provide('goog.debug.LogManager');
        24goog.provide('goog.debug.Loggable');
        25goog.provide('goog.debug.Logger');
        26goog.provide('goog.debug.Logger.Level');
        27
        28goog.require('goog.array');
        29goog.require('goog.asserts');
        30goog.require('goog.debug');
        31goog.require('goog.debug.LogBuffer');
        32goog.require('goog.debug.LogRecord');
        33
        34
        35/**
        36 * A message value that can be handled by a Logger.
        37 *
        38 * Functions are treated like callbacks, but are only called when the event's
        39 * log level is enabled. This is useful for logging messages that are expensive
        40 * to construct.
        41 *
        42 * @typedef {string|function(): string}
        43 */
        44goog.debug.Loggable;
        45
        46
        47
        48/**
        49 * The Logger is an object used for logging debug messages. Loggers are
        50 * normally named, using a hierarchical dot-separated namespace. Logger names
        51 * can be arbitrary strings, but they should normally be based on the package
        52 * name or class name of the logged component, such as goog.net.BrowserChannel.
        53 *
        54 * The Logger object is loosely based on the java class
        55 * java.util.logging.Logger. It supports different levels of filtering for
        56 * different loggers.
        57 *
        58 * The logger object should never be instantiated by application code. It
        59 * should always use the goog.debug.Logger.getLogger function.
        60 *
        61 * @constructor
        62 * @param {string} name The name of the Logger.
        63 * @final
        64 */
        65goog.debug.Logger = function(name) {
        66 /**
        67 * Name of the Logger. Generally a dot-separated namespace
        68 * @private {string}
        69 */
        70 this.name_ = name;
        71
        72 /**
        73 * Parent Logger.
        74 * @private {goog.debug.Logger}
        75 */
        76 this.parent_ = null;
        77
        78 /**
        79 * Level that this logger only filters above. Null indicates it should
        80 * inherit from the parent.
        81 * @private {goog.debug.Logger.Level}
        82 */
        83 this.level_ = null;
        84
        85 /**
        86 * Map of children loggers. The keys are the leaf names of the children and
        87 * the values are the child loggers.
        88 * @private {Object}
        89 */
        90 this.children_ = null;
        91
        92 /**
        93 * Handlers that are listening to this logger.
        94 * @private {Array.<Function>}
        95 */
        96 this.handlers_ = null;
        97};
        98
        99
        100/** @const */
        101goog.debug.Logger.ROOT_LOGGER_NAME = '';
        102
        103
        104/**
        105 * @define {boolean} Toggles whether loggers other than the root logger can have
        106 * log handlers attached to them and whether they can have their log level
        107 * set. Logging is a bit faster when this is set to false.
        108 */
        109goog.define('goog.debug.Logger.ENABLE_HIERARCHY', true);
        110
        111
        112if (!goog.debug.Logger.ENABLE_HIERARCHY) {
        113 /**
        114 * @type {!Array.<Function>}
        115 * @private
        116 */
        117 goog.debug.Logger.rootHandlers_ = [];
        118
        119
        120 /**
        121 * @type {goog.debug.Logger.Level}
        122 * @private
        123 */
        124 goog.debug.Logger.rootLevel_;
        125}
        126
        127
        128
        129/**
        130 * The Level class defines a set of standard logging levels that
        131 * can be used to control logging output. The logging Level objects
        132 * are ordered and are specified by ordered integers. Enabling logging
        133 * at a given level also enables logging at all higher levels.
        134 * <p>
        135 * Clients should normally use the predefined Level constants such
        136 * as Level.SEVERE.
        137 * <p>
        138 * The levels in descending order are:
        139 * <ul>
        140 * <li>SEVERE (highest value)
        141 * <li>WARNING
        142 * <li>INFO
        143 * <li>CONFIG
        144 * <li>FINE
        145 * <li>FINER
        146 * <li>FINEST (lowest value)
        147 * </ul>
        148 * In addition there is a level OFF that can be used to turn
        149 * off logging, and a level ALL that can be used to enable
        150 * logging of all messages.
        151 *
        152 * @param {string} name The name of the level.
        153 * @param {number} value The numeric value of the level.
        154 * @constructor
        155 * @final
        156 */
        157goog.debug.Logger.Level = function(name, value) {
        158 /**
        159 * The name of the level
        160 * @type {string}
        161 */
        162 this.name = name;
        163
        164 /**
        165 * The numeric value of the level
        166 * @type {number}
        167 */
        168 this.value = value;
        169};
        170
        171
        172/**
        173 * @return {string} String representation of the logger level.
        174 * @override
        175 */
        176goog.debug.Logger.Level.prototype.toString = function() {
        177 return this.name;
        178};
        179
        180
        181/**
        182 * OFF is a special level that can be used to turn off logging.
        183 * This level is initialized to <CODE>Infinity</CODE>.
        184 * @type {!goog.debug.Logger.Level}
        185 */
        186goog.debug.Logger.Level.OFF =
        187 new goog.debug.Logger.Level('OFF', Infinity);
        188
        189
        190/**
        191 * SHOUT is a message level for extra debugging loudness.
        192 * This level is initialized to <CODE>1200</CODE>.
        193 * @type {!goog.debug.Logger.Level}
        194 */
        195goog.debug.Logger.Level.SHOUT = new goog.debug.Logger.Level('SHOUT', 1200);
        196
        197
        198/**
        199 * SEVERE is a message level indicating a serious failure.
        200 * This level is initialized to <CODE>1000</CODE>.
        201 * @type {!goog.debug.Logger.Level}
        202 */
        203goog.debug.Logger.Level.SEVERE = new goog.debug.Logger.Level('SEVERE', 1000);
        204
        205
        206/**
        207 * WARNING is a message level indicating a potential problem.
        208 * This level is initialized to <CODE>900</CODE>.
        209 * @type {!goog.debug.Logger.Level}
        210 */
        211goog.debug.Logger.Level.WARNING = new goog.debug.Logger.Level('WARNING', 900);
        212
        213
        214/**
        215 * INFO is a message level for informational messages.
        216 * This level is initialized to <CODE>800</CODE>.
        217 * @type {!goog.debug.Logger.Level}
        218 */
        219goog.debug.Logger.Level.INFO = new goog.debug.Logger.Level('INFO', 800);
        220
        221
        222/**
        223 * CONFIG is a message level for static configuration messages.
        224 * This level is initialized to <CODE>700</CODE>.
        225 * @type {!goog.debug.Logger.Level}
        226 */
        227goog.debug.Logger.Level.CONFIG = new goog.debug.Logger.Level('CONFIG', 700);
        228
        229
        230/**
        231 * FINE is a message level providing tracing information.
        232 * This level is initialized to <CODE>500</CODE>.
        233 * @type {!goog.debug.Logger.Level}
        234 */
        235goog.debug.Logger.Level.FINE = new goog.debug.Logger.Level('FINE', 500);
        236
        237
        238/**
        239 * FINER indicates a fairly detailed tracing message.
        240 * This level is initialized to <CODE>400</CODE>.
        241 * @type {!goog.debug.Logger.Level}
        242 */
        243goog.debug.Logger.Level.FINER = new goog.debug.Logger.Level('FINER', 400);
        244
        245/**
        246 * FINEST indicates a highly detailed tracing message.
        247 * This level is initialized to <CODE>300</CODE>.
        248 * @type {!goog.debug.Logger.Level}
        249 */
        250
        251goog.debug.Logger.Level.FINEST = new goog.debug.Logger.Level('FINEST', 300);
        252
        253
        254/**
        255 * ALL indicates that all messages should be logged.
        256 * This level is initialized to <CODE>0</CODE>.
        257 * @type {!goog.debug.Logger.Level}
        258 */
        259goog.debug.Logger.Level.ALL = new goog.debug.Logger.Level('ALL', 0);
        260
        261
        262/**
        263 * The predefined levels.
        264 * @type {!Array.<!goog.debug.Logger.Level>}
        265 * @final
        266 */
        267goog.debug.Logger.Level.PREDEFINED_LEVELS = [
        268 goog.debug.Logger.Level.OFF,
        269 goog.debug.Logger.Level.SHOUT,
        270 goog.debug.Logger.Level.SEVERE,
        271 goog.debug.Logger.Level.WARNING,
        272 goog.debug.Logger.Level.INFO,
        273 goog.debug.Logger.Level.CONFIG,
        274 goog.debug.Logger.Level.FINE,
        275 goog.debug.Logger.Level.FINER,
        276 goog.debug.Logger.Level.FINEST,
        277 goog.debug.Logger.Level.ALL];
        278
        279
        280/**
        281 * A lookup map used to find the level object based on the name or value of
        282 * the level object.
        283 * @type {Object}
        284 * @private
        285 */
        286goog.debug.Logger.Level.predefinedLevelsCache_ = null;
        287
        288
        289/**
        290 * Creates the predefined levels cache and populates it.
        291 * @private
        292 */
        293goog.debug.Logger.Level.createPredefinedLevelsCache_ = function() {
        294 goog.debug.Logger.Level.predefinedLevelsCache_ = {};
        295 for (var i = 0, level; level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];
        296 i++) {
        297 goog.debug.Logger.Level.predefinedLevelsCache_[level.value] = level;
        298 goog.debug.Logger.Level.predefinedLevelsCache_[level.name] = level;
        299 }
        300};
        301
        302
        303/**
        304 * Gets the predefined level with the given name.
        305 * @param {string} name The name of the level.
        306 * @return {goog.debug.Logger.Level} The level, or null if none found.
        307 */
        308goog.debug.Logger.Level.getPredefinedLevel = function(name) {
        309 if (!goog.debug.Logger.Level.predefinedLevelsCache_) {
        310 goog.debug.Logger.Level.createPredefinedLevelsCache_();
        311 }
        312
        313 return goog.debug.Logger.Level.predefinedLevelsCache_[name] || null;
        314};
        315
        316
        317/**
        318 * Gets the highest predefined level <= #value.
        319 * @param {number} value Level value.
        320 * @return {goog.debug.Logger.Level} The level, or null if none found.
        321 */
        322goog.debug.Logger.Level.getPredefinedLevelByValue = function(value) {
        323 if (!goog.debug.Logger.Level.predefinedLevelsCache_) {
        324 goog.debug.Logger.Level.createPredefinedLevelsCache_();
        325 }
        326
        327 if (value in goog.debug.Logger.Level.predefinedLevelsCache_) {
        328 return goog.debug.Logger.Level.predefinedLevelsCache_[value];
        329 }
        330
        331 for (var i = 0; i < goog.debug.Logger.Level.PREDEFINED_LEVELS.length; ++i) {
        332 var level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];
        333 if (level.value <= value) {
        334 return level;
        335 }
        336 }
        337 return null;
        338};
        339
        340
        341/**
        342 * Finds or creates a logger for a named subsystem. If a logger has already been
        343 * created with the given name it is returned. Otherwise a new logger is
        344 * created. If a new logger is created its log level will be configured based
        345 * on the LogManager configuration and it will configured to also send logging
        346 * output to its parent's handlers. It will be registered in the LogManager
        347 * global namespace.
        348 *
        349 * @param {string} name A name for the logger. This should be a dot-separated
        350 * name and should normally be based on the package name or class name of the
        351 * subsystem, such as goog.net.BrowserChannel.
        352 * @return {!goog.debug.Logger} The named logger.
        353 * @deprecated use goog.log instead. http://go/goog-debug-logger-deprecated
        354 */
        355goog.debug.Logger.getLogger = function(name) {
        356 return goog.debug.LogManager.getLogger(name);
        357};
        358
        359
        360/**
        361 * Logs a message to profiling tools, if available.
        362 * {@see https://developers.google.com/web-toolkit/speedtracer/logging-api}
        363 * {@see http://msdn.microsoft.com/en-us/library/dd433074(VS.85).aspx}
        364 * @param {string} msg The message to log.
        365 */
        366goog.debug.Logger.logToProfilers = function(msg) {
        367 // Using goog.global, as loggers might be used in window-less contexts.
        368 if (goog.global['console']) {
        369 if (goog.global['console']['timeStamp']) {
        370 // Logs a message to Firebug, Web Inspector, SpeedTracer, etc.
        371 goog.global['console']['timeStamp'](msg);
        372 } else if (goog.global['console']['markTimeline']) {
        373 // TODO(user): markTimeline is deprecated. Drop this else clause entirely
        374 // after Chrome M14 hits stable.
        375 goog.global['console']['markTimeline'](msg);
        376 }
        377 }
        378
        379 if (goog.global['msWriteProfilerMark']) {
        380 // Logs a message to the Microsoft profiler
        381 goog.global['msWriteProfilerMark'](msg);
        382 }
        383};
        384
        385
        386/**
        387 * Gets the name of this logger.
        388 * @return {string} The name of this logger.
        389 */
        390goog.debug.Logger.prototype.getName = function() {
        391 return this.name_;
        392};
        393
        394
        395/**
        396 * Adds a handler to the logger. This doesn't use the event system because
        397 * we want to be able to add logging to the event system.
        398 * @param {Function} handler Handler function to add.
        399 */
        400goog.debug.Logger.prototype.addHandler = function(handler) {
        401 if (goog.debug.LOGGING_ENABLED) {
        402 if (goog.debug.Logger.ENABLE_HIERARCHY) {
        403 if (!this.handlers_) {
        404 this.handlers_ = [];
        405 }
        406 this.handlers_.push(handler);
        407 } else {
        408 goog.asserts.assert(!this.name_,
        409 'Cannot call addHandler on a non-root logger when ' +
        410 'goog.debug.Logger.ENABLE_HIERARCHY is false.');
        411 goog.debug.Logger.rootHandlers_.push(handler);
        412 }
        413 }
        414};
        415
        416
        417/**
        418 * Removes a handler from the logger. This doesn't use the event system because
        419 * we want to be able to add logging to the event system.
        420 * @param {Function} handler Handler function to remove.
        421 * @return {boolean} Whether the handler was removed.
        422 */
        423goog.debug.Logger.prototype.removeHandler = function(handler) {
        424 if (goog.debug.LOGGING_ENABLED) {
        425 var handlers = goog.debug.Logger.ENABLE_HIERARCHY ? this.handlers_ :
        426 goog.debug.Logger.rootHandlers_;
        427 return !!handlers && goog.array.remove(handlers, handler);
        428 } else {
        429 return false;
        430 }
        431};
        432
        433
        434/**
        435 * Returns the parent of this logger.
        436 * @return {goog.debug.Logger} The parent logger or null if this is the root.
        437 */
        438goog.debug.Logger.prototype.getParent = function() {
        439 return this.parent_;
        440};
        441
        442
        443/**
        444 * Returns the children of this logger as a map of the child name to the logger.
        445 * @return {!Object} The map where the keys are the child leaf names and the
        446 * values are the Logger objects.
        447 */
        448goog.debug.Logger.prototype.getChildren = function() {
        449 if (!this.children_) {
        450 this.children_ = {};
        451 }
        452 return this.children_;
        453};
        454
        455
        456/**
        457 * Set the log level specifying which message levels will be logged by this
        458 * logger. Message levels lower than this value will be discarded.
        459 * The level value Level.OFF can be used to turn off logging. If the new level
        460 * is null, it means that this node should inherit its level from its nearest
        461 * ancestor with a specific (non-null) level value.
        462 *
        463 * @param {goog.debug.Logger.Level} level The new level.
        464 */
        465goog.debug.Logger.prototype.setLevel = function(level) {
        466 if (goog.debug.LOGGING_ENABLED) {
        467 if (goog.debug.Logger.ENABLE_HIERARCHY) {
        468 this.level_ = level;
        469 } else {
        470 goog.asserts.assert(!this.name_,
        471 'Cannot call setLevel() on a non-root logger when ' +
        472 'goog.debug.Logger.ENABLE_HIERARCHY is false.');
        473 goog.debug.Logger.rootLevel_ = level;
        474 }
        475 }
        476};
        477
        478
        479/**
        480 * Gets the log level specifying which message levels will be logged by this
        481 * logger. Message levels lower than this value will be discarded.
        482 * The level value Level.OFF can be used to turn off logging. If the level
        483 * is null, it means that this node should inherit its level from its nearest
        484 * ancestor with a specific (non-null) level value.
        485 *
        486 * @return {goog.debug.Logger.Level} The level.
        487 */
        488goog.debug.Logger.prototype.getLevel = function() {
        489 return goog.debug.LOGGING_ENABLED ?
        490 this.level_ : goog.debug.Logger.Level.OFF;
        491};
        492
        493
        494/**
        495 * Returns the effective level of the logger based on its ancestors' levels.
        496 * @return {goog.debug.Logger.Level} The level.
        497 */
        498goog.debug.Logger.prototype.getEffectiveLevel = function() {
        499 if (!goog.debug.LOGGING_ENABLED) {
        500 return goog.debug.Logger.Level.OFF;
        501 }
        502
        503 if (!goog.debug.Logger.ENABLE_HIERARCHY) {
        504 return goog.debug.Logger.rootLevel_;
        505 }
        506 if (this.level_) {
        507 return this.level_;
        508 }
        509 if (this.parent_) {
        510 return this.parent_.getEffectiveLevel();
        511 }
        512 goog.asserts.fail('Root logger has no level set.');
        513 return null;
        514};
        515
        516
        517/**
        518 * Checks if a message of the given level would actually be logged by this
        519 * logger. This check is based on the Loggers effective level, which may be
        520 * inherited from its parent.
        521 * @param {goog.debug.Logger.Level} level The level to check.
        522 * @return {boolean} Whether the message would be logged.
        523 */
        524goog.debug.Logger.prototype.isLoggable = function(level) {
        525 return goog.debug.LOGGING_ENABLED &&
        526 level.value >= this.getEffectiveLevel().value;
        527};
        528
        529
        530/**
        531 * Logs a message. If the logger is currently enabled for the
        532 * given message level then the given message is forwarded to all the
        533 * registered output Handler objects.
        534 * @param {goog.debug.Logger.Level} level One of the level identifiers.
        535 * @param {goog.debug.Loggable} msg The message to log.
        536 * @param {Error|Object=} opt_exception An exception associated with the
        537 * message.
        538 */
        539goog.debug.Logger.prototype.log = function(level, msg, opt_exception) {
        540 // java caches the effective level, not sure it's necessary here
        541 if (goog.debug.LOGGING_ENABLED && this.isLoggable(level)) {
        542 // Message callbacks can be useful when a log message is expensive to build.
        543 if (goog.isFunction(msg)) {
        544 msg = msg();
        545 }
        546
        547 this.doLogRecord_(this.getLogRecord(
        548 level, msg, opt_exception, goog.debug.Logger.prototype.log));
        549 }
        550};
        551
        552
        553/**
        554 * Creates a new log record and adds the exception (if present) to it.
        555 * @param {goog.debug.Logger.Level} level One of the level identifiers.
        556 * @param {string} msg The string message.
        557 * @param {Error|Object=} opt_exception An exception associated with the
        558 * message.
        559 * @param {Function=} opt_fnStackContext A function to use as the base
        560 * of the stack trace used in the log record.
        561 * @return {!goog.debug.LogRecord} A log record.
        562 * @suppress {es5Strict}
        563 */
        564goog.debug.Logger.prototype.getLogRecord = function(
        565 level, msg, opt_exception, opt_fnStackContext) {
        566 if (goog.debug.LogBuffer.isBufferingEnabled()) {
        567 var logRecord =
        568 goog.debug.LogBuffer.getInstance().addRecord(level, msg, this.name_);
        569 } else {
        570 logRecord = new goog.debug.LogRecord(level, String(msg), this.name_);
        571 }
        572 if (opt_exception) {
        573 var context;
        574 if (goog.STRICT_MODE_COMPATIBLE) {
        575 context = opt_fnStackContext || goog.debug.Logger.prototype.getLogRecord;
        576 } else {
        577 context = opt_fnStackContext || arguments.callee.caller;
        578 }
        579
        580 logRecord.setException(opt_exception);
        581 logRecord.setExceptionText(
        582 goog.debug.exposeException(opt_exception,
        583 opt_fnStackContext || goog.debug.Logger.prototype.getLogRecord));
        584 }
        585 return logRecord;
        586};
        587
        588
        589/**
        590 * Logs a message at the Logger.Level.SHOUT level.
        591 * If the logger is currently enabled for the given message level then the
        592 * given message is forwarded to all the registered output Handler objects.
        593 * @param {goog.debug.Loggable} msg The message to log.
        594 * @param {Error=} opt_exception An exception associated with the message.
        595 */
        596goog.debug.Logger.prototype.shout = function(msg, opt_exception) {
        597 if (goog.debug.LOGGING_ENABLED) {
        598 this.log(goog.debug.Logger.Level.SHOUT, msg, opt_exception);
        599 }
        600};
        601
        602
        603/**
        604 * Logs a message at the Logger.Level.SEVERE level.
        605 * If the logger is currently enabled for the given message level then the
        606 * given message is forwarded to all the registered output Handler objects.
        607 * @param {goog.debug.Loggable} msg The message to log.
        608 * @param {Error=} opt_exception An exception associated with the message.
        609 */
        610goog.debug.Logger.prototype.severe = function(msg, opt_exception) {
        611 if (goog.debug.LOGGING_ENABLED) {
        612 this.log(goog.debug.Logger.Level.SEVERE, msg, opt_exception);
        613 }
        614};
        615
        616
        617/**
        618 * Logs a message at the Logger.Level.WARNING level.
        619 * If the logger is currently enabled for the given message level then the
        620 * given message is forwarded to all the registered output Handler objects.
        621 * @param {goog.debug.Loggable} msg The message to log.
        622 * @param {Error=} opt_exception An exception associated with the message.
        623 */
        624goog.debug.Logger.prototype.warning = function(msg, opt_exception) {
        625 if (goog.debug.LOGGING_ENABLED) {
        626 this.log(goog.debug.Logger.Level.WARNING, msg, opt_exception);
        627 }
        628};
        629
        630
        631/**
        632 * Logs a message at the Logger.Level.INFO level.
        633 * If the logger is currently enabled for the given message level then the
        634 * given message is forwarded to all the registered output Handler objects.
        635 * @param {goog.debug.Loggable} msg The message to log.
        636 * @param {Error=} opt_exception An exception associated with the message.
        637 */
        638goog.debug.Logger.prototype.info = function(msg, opt_exception) {
        639 if (goog.debug.LOGGING_ENABLED) {
        640 this.log(goog.debug.Logger.Level.INFO, msg, opt_exception);
        641 }
        642};
        643
        644
        645/**
        646 * Logs a message at the Logger.Level.CONFIG level.
        647 * If the logger is currently enabled for the given message level then the
        648 * given message is forwarded to all the registered output Handler objects.
        649 * @param {goog.debug.Loggable} msg The message to log.
        650 * @param {Error=} opt_exception An exception associated with the message.
        651 */
        652goog.debug.Logger.prototype.config = function(msg, opt_exception) {
        653 if (goog.debug.LOGGING_ENABLED) {
        654 this.log(goog.debug.Logger.Level.CONFIG, msg, opt_exception);
        655 }
        656};
        657
        658
        659/**
        660 * Logs a message at the Logger.Level.FINE level.
        661 * If the logger is currently enabled for the given message level then the
        662 * given message is forwarded to all the registered output Handler objects.
        663 * @param {goog.debug.Loggable} msg The message to log.
        664 * @param {Error=} opt_exception An exception associated with the message.
        665 */
        666goog.debug.Logger.prototype.fine = function(msg, opt_exception) {
        667 if (goog.debug.LOGGING_ENABLED) {
        668 this.log(goog.debug.Logger.Level.FINE, msg, opt_exception);
        669 }
        670};
        671
        672
        673/**
        674 * Logs a message at the Logger.Level.FINER level.
        675 * If the logger is currently enabled for the given message level then the
        676 * given message is forwarded to all the registered output Handler objects.
        677 * @param {goog.debug.Loggable} msg The message to log.
        678 * @param {Error=} opt_exception An exception associated with the message.
        679 */
        680goog.debug.Logger.prototype.finer = function(msg, opt_exception) {
        681 if (goog.debug.LOGGING_ENABLED) {
        682 this.log(goog.debug.Logger.Level.FINER, msg, opt_exception);
        683 }
        684};
        685
        686
        687/**
        688 * Logs a message at the Logger.Level.FINEST level.
        689 * If the logger is currently enabled for the given message level then the
        690 * given message is forwarded to all the registered output Handler objects.
        691 * @param {goog.debug.Loggable} msg The message to log.
        692 * @param {Error=} opt_exception An exception associated with the message.
        693 */
        694goog.debug.Logger.prototype.finest = function(msg, opt_exception) {
        695 if (goog.debug.LOGGING_ENABLED) {
        696 this.log(goog.debug.Logger.Level.FINEST, msg, opt_exception);
        697 }
        698};
        699
        700
        701/**
        702 * Logs a LogRecord. If the logger is currently enabled for the
        703 * given message level then the given message is forwarded to all the
        704 * registered output Handler objects.
        705 * @param {goog.debug.LogRecord} logRecord A log record to log.
        706 */
        707goog.debug.Logger.prototype.logRecord = function(logRecord) {
        708 if (goog.debug.LOGGING_ENABLED && this.isLoggable(logRecord.getLevel())) {
        709 this.doLogRecord_(logRecord);
        710 }
        711};
        712
        713
        714/**
        715 * Logs a LogRecord.
        716 * @param {goog.debug.LogRecord} logRecord A log record to log.
        717 * @private
        718 */
        719goog.debug.Logger.prototype.doLogRecord_ = function(logRecord) {
        720 goog.debug.Logger.logToProfilers('log:' + logRecord.getMessage());
        721 if (goog.debug.Logger.ENABLE_HIERARCHY) {
        722 var target = this;
        723 while (target) {
        724 target.callPublish_(logRecord);
        725 target = target.getParent();
        726 }
        727 } else {
        728 for (var i = 0, handler; handler = goog.debug.Logger.rootHandlers_[i++]; ) {
        729 handler(logRecord);
        730 }
        731 }
        732};
        733
        734
        735/**
        736 * Calls the handlers for publish.
        737 * @param {goog.debug.LogRecord} logRecord The log record to publish.
        738 * @private
        739 */
        740goog.debug.Logger.prototype.callPublish_ = function(logRecord) {
        741 if (this.handlers_) {
        742 for (var i = 0, handler; handler = this.handlers_[i]; i++) {
        743 handler(logRecord);
        744 }
        745 }
        746};
        747
        748
        749/**
        750 * Sets the parent of this logger. This is used for setting up the logger tree.
        751 * @param {goog.debug.Logger} parent The parent logger.
        752 * @private
        753 */
        754goog.debug.Logger.prototype.setParent_ = function(parent) {
        755 this.parent_ = parent;
        756};
        757
        758
        759/**
        760 * Adds a child to this logger. This is used for setting up the logger tree.
        761 * @param {string} name The leaf name of the child.
        762 * @param {goog.debug.Logger} logger The child logger.
        763 * @private
        764 */
        765goog.debug.Logger.prototype.addChild_ = function(name, logger) {
        766 this.getChildren()[name] = logger;
        767};
        768
        769
        770/**
        771 * There is a single global LogManager object that is used to maintain a set of
        772 * shared state about Loggers and log services. This is loosely based on the
        773 * java class java.util.logging.LogManager.
        774 */
        775goog.debug.LogManager = {};
        776
        777
        778/**
        779 * Map of logger names to logger objects.
        780 *
        781 * @type {!Object.<string, !goog.debug.Logger>}
        782 * @private
        783 */
        784goog.debug.LogManager.loggers_ = {};
        785
        786
        787/**
        788 * The root logger which is the root of the logger tree.
        789 * @type {goog.debug.Logger}
        790 * @private
        791 */
        792goog.debug.LogManager.rootLogger_ = null;
        793
        794
        795/**
        796 * Initializes the LogManager if not already initialized.
        797 */
        798goog.debug.LogManager.initialize = function() {
        799 if (!goog.debug.LogManager.rootLogger_) {
        800 goog.debug.LogManager.rootLogger_ = new goog.debug.Logger(
        801 goog.debug.Logger.ROOT_LOGGER_NAME);
        802 goog.debug.LogManager.loggers_[goog.debug.Logger.ROOT_LOGGER_NAME] =
        803 goog.debug.LogManager.rootLogger_;
        804 goog.debug.LogManager.rootLogger_.setLevel(goog.debug.Logger.Level.CONFIG);
        805 }
        806};
        807
        808
        809/**
        810 * Returns all the loggers.
        811 * @return {!Object.<string, !goog.debug.Logger>} Map of logger names to logger
        812 * objects.
        813 */
        814goog.debug.LogManager.getLoggers = function() {
        815 return goog.debug.LogManager.loggers_;
        816};
        817
        818
        819/**
        820 * Returns the root of the logger tree namespace, the logger with the empty
        821 * string as its name.
        822 *
        823 * @return {!goog.debug.Logger} The root logger.
        824 */
        825goog.debug.LogManager.getRoot = function() {
        826 goog.debug.LogManager.initialize();
        827 return /** @type {!goog.debug.Logger} */ (goog.debug.LogManager.rootLogger_);
        828};
        829
        830
        831/**
        832 * Finds a named logger.
        833 *
        834 * @param {string} name A name for the logger. This should be a dot-separated
        835 * name and should normally be based on the package name or class name of the
        836 * subsystem, such as goog.net.BrowserChannel.
        837 * @return {!goog.debug.Logger} The named logger.
        838 */
        839goog.debug.LogManager.getLogger = function(name) {
        840 goog.debug.LogManager.initialize();
        841 var ret = goog.debug.LogManager.loggers_[name];
        842 return ret || goog.debug.LogManager.createLogger_(name);
        843};
        844
        845
        846/**
        847 * Creates a function that can be passed to goog.debug.catchErrors. The function
        848 * will log all reported errors using the given logger.
        849 * @param {goog.debug.Logger=} opt_logger The logger to log the errors to.
        850 * Defaults to the root logger.
        851 * @return {function(Object)} The created function.
        852 */
        853goog.debug.LogManager.createFunctionForCatchErrors = function(opt_logger) {
        854 return function(info) {
        855 var logger = opt_logger || goog.debug.LogManager.getRoot();
        856 logger.severe('Error: ' + info.message + ' (' + info.fileName +
        857 ' @ Line: ' + info.line + ')');
        858 };
        859};
        860
        861
        862/**
        863 * Creates the named logger. Will also create the parents of the named logger
        864 * if they don't yet exist.
        865 * @param {string} name The name of the logger.
        866 * @return {!goog.debug.Logger} The named logger.
        867 * @private
        868 */
        869goog.debug.LogManager.createLogger_ = function(name) {
        870 // find parent logger
        871 var logger = new goog.debug.Logger(name);
        872 if (goog.debug.Logger.ENABLE_HIERARCHY) {
        873 var lastDotIndex = name.lastIndexOf('.');
        874 var parentName = name.substr(0, lastDotIndex);
        875 var leafName = name.substr(lastDotIndex + 1);
        876 var parentLogger = goog.debug.LogManager.getLogger(parentName);
        877
        878 // tell the parent about the child and the child about the parent
        879 parentLogger.addChild_(leafName, logger);
        880 logger.setParent_(parentLogger);
        881 }
        882
        883 goog.debug.LogManager.loggers_[name] = logger;
        884 return logger;
        885};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/debug/logrecord.js.src.html b/docs/api/javascript/source/lib/goog/debug/logrecord.js.src.html new file mode 100644 index 0000000000000..c3b9b67351b69 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/debug/logrecord.js.src.html @@ -0,0 +1 @@ +logrecord.js

        lib/goog/debug/logrecord.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 the LogRecord class. Please minimize
        17 * dependencies this file has on other closure classes as any dependency it
        18 * takes won't be able to use the logging infrastructure.
        19 *
        20 */
        21
        22goog.provide('goog.debug.LogRecord');
        23
        24
        25
        26/**
        27 * LogRecord objects are used to pass logging requests between
        28 * the logging framework and individual log Handlers.
        29 * @constructor
        30 * @param {goog.debug.Logger.Level} level One of the level identifiers.
        31 * @param {string} msg The string message.
        32 * @param {string} loggerName The name of the source logger.
        33 * @param {number=} opt_time Time this log record was created if other than now.
        34 * If 0, we use #goog.now.
        35 * @param {number=} opt_sequenceNumber Sequence number of this log record. This
        36 * should only be passed in when restoring a log record from persistence.
        37 */
        38goog.debug.LogRecord = function(level, msg, loggerName,
        39 opt_time, opt_sequenceNumber) {
        40 this.reset(level, msg, loggerName, opt_time, opt_sequenceNumber);
        41};
        42
        43
        44/**
        45 * Time the LogRecord was created.
        46 * @type {number}
        47 * @private
        48 */
        49goog.debug.LogRecord.prototype.time_;
        50
        51
        52/**
        53 * Level of the LogRecord
        54 * @type {goog.debug.Logger.Level}
        55 * @private
        56 */
        57goog.debug.LogRecord.prototype.level_;
        58
        59
        60/**
        61 * Message associated with the record
        62 * @type {string}
        63 * @private
        64 */
        65goog.debug.LogRecord.prototype.msg_;
        66
        67
        68/**
        69 * Name of the logger that created the record.
        70 * @type {string}
        71 * @private
        72 */
        73goog.debug.LogRecord.prototype.loggerName_;
        74
        75
        76/**
        77 * Sequence number for the LogRecord. Each record has a unique sequence number
        78 * that is greater than all log records created before it.
        79 * @type {number}
        80 * @private
        81 */
        82goog.debug.LogRecord.prototype.sequenceNumber_ = 0;
        83
        84
        85/**
        86 * Exception associated with the record
        87 * @type {Object}
        88 * @private
        89 */
        90goog.debug.LogRecord.prototype.exception_ = null;
        91
        92
        93/**
        94 * Exception text associated with the record
        95 * @type {?string}
        96 * @private
        97 */
        98goog.debug.LogRecord.prototype.exceptionText_ = null;
        99
        100
        101/**
        102 * @define {boolean} Whether to enable log sequence numbers.
        103 */
        104goog.define('goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS', true);
        105
        106
        107/**
        108 * A sequence counter for assigning increasing sequence numbers to LogRecord
        109 * objects.
        110 * @type {number}
        111 * @private
        112 */
        113goog.debug.LogRecord.nextSequenceNumber_ = 0;
        114
        115
        116/**
        117 * Sets all fields of the log record.
        118 * @param {goog.debug.Logger.Level} level One of the level identifiers.
        119 * @param {string} msg The string message.
        120 * @param {string} loggerName The name of the source logger.
        121 * @param {number=} opt_time Time this log record was created if other than now.
        122 * If 0, we use #goog.now.
        123 * @param {number=} opt_sequenceNumber Sequence number of this log record. This
        124 * should only be passed in when restoring a log record from persistence.
        125 */
        126goog.debug.LogRecord.prototype.reset = function(level, msg, loggerName,
        127 opt_time, opt_sequenceNumber) {
        128 if (goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS) {
        129 this.sequenceNumber_ = typeof opt_sequenceNumber == 'number' ?
        130 opt_sequenceNumber : goog.debug.LogRecord.nextSequenceNumber_++;
        131 }
        132
        133 this.time_ = opt_time || goog.now();
        134 this.level_ = level;
        135 this.msg_ = msg;
        136 this.loggerName_ = loggerName;
        137 delete this.exception_;
        138 delete this.exceptionText_;
        139};
        140
        141
        142/**
        143 * Get the source Logger's name.
        144 *
        145 * @return {string} source logger name (may be null).
        146 */
        147goog.debug.LogRecord.prototype.getLoggerName = function() {
        148 return this.loggerName_;
        149};
        150
        151
        152/**
        153 * Get the exception that is part of the log record.
        154 *
        155 * @return {Object} the exception.
        156 */
        157goog.debug.LogRecord.prototype.getException = function() {
        158 return this.exception_;
        159};
        160
        161
        162/**
        163 * Set the exception that is part of the log record.
        164 *
        165 * @param {Object} exception the exception.
        166 */
        167goog.debug.LogRecord.prototype.setException = function(exception) {
        168 this.exception_ = exception;
        169};
        170
        171
        172/**
        173 * Get the exception text that is part of the log record.
        174 *
        175 * @return {?string} Exception text.
        176 */
        177goog.debug.LogRecord.prototype.getExceptionText = function() {
        178 return this.exceptionText_;
        179};
        180
        181
        182/**
        183 * Set the exception text that is part of the log record.
        184 *
        185 * @param {string} text The exception text.
        186 */
        187goog.debug.LogRecord.prototype.setExceptionText = function(text) {
        188 this.exceptionText_ = text;
        189};
        190
        191
        192/**
        193 * Get the source Logger's name.
        194 *
        195 * @param {string} loggerName source logger name (may be null).
        196 */
        197goog.debug.LogRecord.prototype.setLoggerName = function(loggerName) {
        198 this.loggerName_ = loggerName;
        199};
        200
        201
        202/**
        203 * Get the logging message level, for example Level.SEVERE.
        204 * @return {goog.debug.Logger.Level} the logging message level.
        205 */
        206goog.debug.LogRecord.prototype.getLevel = function() {
        207 return this.level_;
        208};
        209
        210
        211/**
        212 * Set the logging message level, for example Level.SEVERE.
        213 * @param {goog.debug.Logger.Level} level the logging message level.
        214 */
        215goog.debug.LogRecord.prototype.setLevel = function(level) {
        216 this.level_ = level;
        217};
        218
        219
        220/**
        221 * Get the "raw" log message, before localization or formatting.
        222 *
        223 * @return {string} the raw message string.
        224 */
        225goog.debug.LogRecord.prototype.getMessage = function() {
        226 return this.msg_;
        227};
        228
        229
        230/**
        231 * Set the "raw" log message, before localization or formatting.
        232 *
        233 * @param {string} msg the raw message string.
        234 */
        235goog.debug.LogRecord.prototype.setMessage = function(msg) {
        236 this.msg_ = msg;
        237};
        238
        239
        240/**
        241 * Get event time in milliseconds since 1970.
        242 *
        243 * @return {number} event time in millis since 1970.
        244 */
        245goog.debug.LogRecord.prototype.getMillis = function() {
        246 return this.time_;
        247};
        248
        249
        250/**
        251 * Set event time in milliseconds since 1970.
        252 *
        253 * @param {number} time event time in millis since 1970.
        254 */
        255goog.debug.LogRecord.prototype.setMillis = function(time) {
        256 this.time_ = time;
        257};
        258
        259
        260/**
        261 * Get the sequence number.
        262 * <p>
        263 * Sequence numbers are normally assigned in the LogRecord
        264 * constructor, which assigns unique sequence numbers to
        265 * each new LogRecord in increasing order.
        266 * @return {number} the sequence number.
        267 */
        268goog.debug.LogRecord.prototype.getSequenceNumber = function() {
        269 return this.sequenceNumber_;
        270};
        271
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/deps.js.src.html b/docs/api/javascript/source/lib/goog/deps.js.src.html index 6889637251fb4..dbe50dbead27e 100644 --- a/docs/api/javascript/source/lib/goog/deps.js.src.html +++ b/docs/api/javascript/source/lib/goog/deps.js.src.html @@ -1 +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 +deps.js

        lib/goog/deps.js

        1// This file has been auto-generated; do not edit by hand
        2goog.addDependency("../webdriver/test/events_test.js", [], ["goog.testing.jsunit","webdriver.EventEmitter"]);
        3goog.addDependency("testing/jsunit.js", ["goog.testing.jsunit"], ["goog.testing.TestCase","goog.testing.TestRunner"]);
        4goog.addDependency("testing/testcase.js", ["goog.testing.TestCase","goog.testing.TestCase.Error","goog.testing.TestCase.Order","goog.testing.TestCase.Result","goog.testing.TestCase.Test"], ["goog.object","goog.testing.asserts","goog.testing.stacktrace"]);
        5goog.addDependency("object/object.js", ["goog.object"], ["goog.array"]);
        6goog.addDependency("array/array.js", ["goog.array","goog.array.ArrayLike"], ["goog.asserts"]);
        7goog.addDependency("asserts/asserts.js", ["goog.asserts","goog.asserts.AssertionError"], ["goog.debug.Error","goog.dom.NodeType","goog.string"]);
        8goog.addDependency("debug/error.js", ["goog.debug.Error"], []);
        9goog.addDependency("dom/nodetype.js", ["goog.dom.NodeType"], []);
        10goog.addDependency("string/string.js", ["goog.string","goog.string.Unicode"], []);
        11goog.addDependency("testing/asserts.js", ["goog.testing.JsUnitException","goog.testing.asserts"], ["goog.testing.stacktrace"]);
        12goog.addDependency("testing/stacktrace.js", ["goog.testing.stacktrace","goog.testing.stacktrace.Frame"], []);
        13goog.addDependency("testing/testrunner.js", ["goog.testing.TestRunner"], ["goog.testing.TestCase"]);
        14goog.addDependency("../webdriver/events.js", ["webdriver.EventEmitter"], []);
        15goog.addDependency("../webdriver/test/promise_test.js", [], ["goog.testing.jsunit","webdriver.promise","webdriver.promise.Deferred","webdriver.test.testutil"]);
        16goog.addDependency("../webdriver/promise.js", ["webdriver.promise","webdriver.promise.ControlFlow","webdriver.promise.ControlFlow.Timer","webdriver.promise.Deferred","webdriver.promise.Promise","webdriver.promise.Thenable"], ["goog.array","goog.debug.Error","goog.object","webdriver.EventEmitter","webdriver.stacktrace.Snapshot"]);
        17goog.addDependency("../webdriver/stacktrace.js", ["webdriver.stacktrace","webdriver.stacktrace.Snapshot"], ["goog.array","goog.string","goog.userAgent"]);
        18goog.addDependency("useragent/useragent.js", ["goog.userAgent"], ["goog.labs.userAgent.browser","goog.labs.userAgent.engine","goog.labs.userAgent.util","goog.string"]);
        19goog.addDependency("labs/useragent/browser.js", ["goog.labs.userAgent.browser"], ["goog.array","goog.labs.userAgent.util","goog.object","goog.string"]);
        20goog.addDependency("labs/useragent/util.js", ["goog.labs.userAgent.util"], ["goog.string"]);
        21goog.addDependency("labs/useragent/engine.js", ["goog.labs.userAgent.engine"], ["goog.array","goog.labs.userAgent.util","goog.string"]);
        22goog.addDependency("../webdriver/test/testutil.js", ["webdriver.test.testutil"], ["goog.array","goog.json","goog.string","goog.testing.MockClock","goog.testing.recordFunction","webdriver.stacktrace"]);
        23goog.addDependency("json/json.js", ["goog.json","goog.json.Replacer","goog.json.Reviver","goog.json.Serializer"], []);
        24goog.addDependency("testing/mockclock.js", ["goog.testing.MockClock"], ["goog.Disposable","goog.async.run","goog.testing.PropertyReplacer","goog.testing.events","goog.testing.events.Event","goog.testing.watchers"]);
        25goog.addDependency("disposable/disposable.js", ["goog.Disposable","goog.dispose","goog.disposeAll"], ["goog.disposable.IDisposable"]);
        26goog.addDependency("disposable/idisposable.js", ["goog.disposable.IDisposable"], []);
        27goog.addDependency("async/run.js", ["goog.async.run"], ["goog.async.nextTick","goog.async.throwException","goog.testing.watchers"]);
        28goog.addDependency("async/nexttick.js", ["goog.async.nextTick","goog.async.throwException"], ["goog.debug.entryPointRegistry","goog.functions","goog.labs.userAgent.browser"]);
        29goog.addDependency("debug/entrypointregistry.js", ["goog.debug.EntryPointMonitor","goog.debug.entryPointRegistry"], ["goog.asserts"]);
        30goog.addDependency("functions/functions.js", ["goog.functions"], []);
        31goog.addDependency("testing/watchers.js", ["goog.testing.watchers"], []);
        32goog.addDependency("testing/propertyreplacer.js", ["goog.testing.PropertyReplacer"], ["goog.testing.ObjectPropertyString","goog.userAgent"]);
        33goog.addDependency("testing/objectpropertystring.js", ["goog.testing.ObjectPropertyString"], []);
        34goog.addDependency("testing/events/events.js", ["goog.testing.events","goog.testing.events.Event"], ["goog.Disposable","goog.asserts","goog.dom.NodeType","goog.events","goog.events.BrowserEvent","goog.events.BrowserFeature","goog.events.EventTarget","goog.events.EventType","goog.events.KeyCodes","goog.object","goog.style","goog.userAgent"]);
        35goog.addDependency("events/events.js", ["goog.events","goog.events.CaptureSimulationMode","goog.events.Key","goog.events.ListenableType"], ["goog.asserts","goog.debug.entryPointRegistry","goog.events.BrowserEvent","goog.events.BrowserFeature","goog.events.Listenable","goog.events.ListenerMap"]);
        36goog.addDependency("events/browserevent.js", ["goog.events.BrowserEvent","goog.events.BrowserEvent.MouseButton"], ["goog.events.BrowserFeature","goog.events.Event","goog.events.EventType","goog.reflect","goog.userAgent"]);
        37goog.addDependency("events/browserfeature.js", ["goog.events.BrowserFeature"], ["goog.userAgent"]);
        38goog.addDependency("events/event.js", ["goog.events.Event","goog.events.EventLike"], ["goog.Disposable","goog.events.EventId"]);
        39goog.addDependency("events/eventid.js", ["goog.events.EventId"], []);
        40goog.addDependency("events/eventtype.js", ["goog.events.EventType"], ["goog.userAgent"]);
        41goog.addDependency("reflect/reflect.js", ["goog.reflect"], []);
        42goog.addDependency("events/listenable.js", ["goog.events.Listenable","goog.events.ListenableKey"], ["goog.events.EventId"]);
        43goog.addDependency("events/listenermap.js", ["goog.events.ListenerMap"], ["goog.array","goog.events.Listener","goog.object"]);
        44goog.addDependency("events/listener.js", ["goog.events.Listener"], ["goog.events.ListenableKey"]);
        45goog.addDependency("events/eventtarget.js", ["goog.events.EventTarget"], ["goog.Disposable","goog.asserts","goog.events","goog.events.Event","goog.events.Listenable","goog.events.ListenerMap","goog.object"]);
        46goog.addDependency("events/keycodes.js", ["goog.events.KeyCodes"], ["goog.userAgent"]);
        47goog.addDependency("style/style.js", ["goog.style"], ["goog.array","goog.asserts","goog.dom","goog.dom.NodeType","goog.dom.vendor","goog.math.Box","goog.math.Coordinate","goog.math.Rect","goog.math.Size","goog.object","goog.string","goog.userAgent"]);
        48goog.addDependency("dom/dom.js", ["goog.dom","goog.dom.Appendable","goog.dom.DomHelper"], ["goog.array","goog.asserts","goog.dom.BrowserFeature","goog.dom.NodeType","goog.dom.TagName","goog.math.Coordinate","goog.math.Size","goog.object","goog.string","goog.userAgent"]);
        49goog.addDependency("dom/browserfeature.js", ["goog.dom.BrowserFeature"], ["goog.userAgent"]);
        50goog.addDependency("dom/tagname.js", ["goog.dom.TagName"], []);
        51goog.addDependency("math/coordinate.js", ["goog.math.Coordinate"], ["goog.math"]);
        52goog.addDependency("math/math.js", ["goog.math"], ["goog.array","goog.asserts"]);
        53goog.addDependency("math/size.js", ["goog.math.Size"], []);
        54goog.addDependency("dom/vendor.js", ["goog.dom.vendor"], ["goog.string","goog.userAgent"]);
        55goog.addDependency("math/box.js", ["goog.math.Box"], ["goog.math.Coordinate"]);
        56goog.addDependency("math/rect.js", ["goog.math.Rect"], ["goog.math.Box","goog.math.Coordinate","goog.math.Size"]);
        57goog.addDependency("testing/recordfunction.js", ["goog.testing.FunctionCall","goog.testing.recordConstructor","goog.testing.recordFunction"], ["goog.testing.asserts"]);
        58goog.addDependency("../webdriver/test/logging_test.js", [], ["goog.debug.LogRecord","goog.debug.Logger","goog.testing.jsunit","webdriver.logging"]);
        59goog.addDependency("debug/logrecord.js", ["goog.debug.LogRecord"], []);
        60goog.addDependency("debug/logger.js", ["goog.debug.LogManager","goog.debug.Loggable","goog.debug.Logger","goog.debug.Logger.Level"], ["goog.array","goog.asserts","goog.debug","goog.debug.LogBuffer","goog.debug.LogRecord"]);
        61goog.addDependency("debug/debug.js", ["goog.debug"], ["goog.array","goog.string","goog.structs.Set","goog.userAgent"]);
        62goog.addDependency("structs/set.js", ["goog.structs.Set"], ["goog.structs","goog.structs.Collection","goog.structs.Map"]);
        63goog.addDependency("structs/structs.js", ["goog.structs"], ["goog.array","goog.object"]);
        64goog.addDependency("structs/collection.js", ["goog.structs.Collection"], []);
        65goog.addDependency("structs/map.js", ["goog.structs.Map"], ["goog.iter.Iterator","goog.iter.StopIteration","goog.object"]);
        66goog.addDependency("iter/iter.js", ["goog.iter","goog.iter.Iterable","goog.iter.Iterator","goog.iter.StopIteration"], ["goog.array","goog.asserts","goog.functions","goog.math"]);
        67goog.addDependency("debug/logbuffer.js", ["goog.debug.LogBuffer"], ["goog.asserts","goog.debug.LogRecord"]);
        68goog.addDependency("../webdriver/logging.js", ["webdriver.logging","webdriver.logging.Preferences"], ["goog.object"]);
        69goog.addDependency("../webdriver/test/process_test.js", [], ["goog.testing.PropertyReplacer","goog.testing.jsunit","webdriver.process","webdriver.test.testutil"]);
        70goog.addDependency("../webdriver/process.js", ["webdriver.process"], ["goog.Uri","goog.array","goog.json"]);
        71goog.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"]);
        72goog.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"]);
        73goog.addDependency("../webdriver/test/test_bootstrap.js", [], []);
        74goog.addDependency("../webdriver/test/promise_flow_test.js", [], ["goog.array","goog.functions","goog.string","goog.testing.FunctionMock","goog.testing.jsunit","goog.userAgent","webdriver.promise.ControlFlow","webdriver.stacktrace.Snapshot","webdriver.test.testutil","webdriver.testing.promise.FlowTester"]);
        75goog.addDependency("testing/functionmock.js", ["goog.testing","goog.testing.FunctionMock","goog.testing.GlobalFunctionMock","goog.testing.MethodMock"], ["goog.object","goog.testing.LooseMock","goog.testing.Mock","goog.testing.MockInterface","goog.testing.PropertyReplacer","goog.testing.StrictMock"]);
        76goog.addDependency("testing/loosemock.js", ["goog.testing.LooseExpectationCollection","goog.testing.LooseMock"], ["goog.array","goog.structs.Map","goog.testing.Mock"]);
        77goog.addDependency("testing/mock.js", ["goog.testing.Mock","goog.testing.MockExpectation"], ["goog.array","goog.object","goog.testing.JsUnitException","goog.testing.MockInterface","goog.testing.mockmatchers"]);
        78goog.addDependency("testing/mockinterface.js", ["goog.testing.MockInterface"], []);
        79goog.addDependency("testing/mockmatchers.js", ["goog.testing.mockmatchers","goog.testing.mockmatchers.ArgumentMatcher","goog.testing.mockmatchers.IgnoreArgument","goog.testing.mockmatchers.InstanceOf","goog.testing.mockmatchers.ObjectEquals","goog.testing.mockmatchers.RegexpMatch","goog.testing.mockmatchers.SaveArgument","goog.testing.mockmatchers.TypeOf"], ["goog.array","goog.dom","goog.testing.asserts"]);
        80goog.addDependency("testing/strictmock.js", ["goog.testing.StrictMock"], ["goog.array","goog.testing.Mock"]);
        81goog.addDependency("../webdriver/testing/flowtester.js", ["webdriver.testing.Clock","webdriver.testing.promise.FlowTester"], ["goog.array","webdriver.promise.ControlFlow"]);
        82goog.addDependency("../webdriver/test/locators_test.js", [], ["goog.json","goog.testing.jsunit","webdriver.By","webdriver.Locator","webdriver.Locator.Strategy","webdriver.test.testutil"]);
        83goog.addDependency("../webdriver/locators.js", ["webdriver.By","webdriver.Locator","webdriver.Locator.Strategy"], ["goog.array","goog.object","goog.string"]);
        84goog.addDependency("../webdriver/test/webdriver_test.js", [], ["bot.ErrorCode","goog.functions","goog.json","goog.testing.PropertyReplacer","goog.testing.MockControl","goog.testing.jsunit","webdriver.Capabilities","webdriver.Command","webdriver.CommandExecutor","webdriver.CommandName","webdriver.WebDriver","webdriver.Session","webdriver.logging","webdriver.promise","webdriver.promise.ControlFlow","webdriver.promise.Deferred","webdriver.promise.Promise","webdriver.test.testutil","webdriver.testing.promise.FlowTester"]);
        85goog.addDependency("../atoms/error.js", ["bot.Error","bot.ErrorCode"], []);
        86goog.addDependency("testing/mockcontrol.js", ["goog.testing.MockControl"], ["goog.array","goog.testing","goog.testing.LooseMock","goog.testing.StrictMock"]);
        87goog.addDependency("../webdriver/capabilities.js", ["webdriver.Browser","webdriver.Capabilities","webdriver.Capability","webdriver.ProxyConfig"], ["webdriver.logging.Preferences"]);
        88goog.addDependency("../webdriver/command.js", ["webdriver.Command","webdriver.CommandExecutor","webdriver.CommandName"], []);
        89goog.addDependency("../webdriver/webdriver.js", ["webdriver.Alert","webdriver.AlertPromise","webdriver.UnhandledAlertError","webdriver.WebDriver","webdriver.WebElement","webdriver.WebElementPromise"], ["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"]);
        90goog.addDependency("../atoms/response.js", ["bot.response","bot.response.ResponseObject"], ["bot.Error","bot.ErrorCode"]);
        91goog.addDependency("../webdriver/actionsequence.js", ["webdriver.ActionSequence"], ["goog.array","webdriver.Button","webdriver.Command","webdriver.CommandName","webdriver.Key"]);
        92goog.addDependency("../webdriver/button.js", ["webdriver.Button"], []);
        93goog.addDependency("../webdriver/key.js", ["webdriver.Key"], []);
        94goog.addDependency("../webdriver/session.js", ["webdriver.Session"], ["webdriver.Capabilities"]);
        95goog.addDependency("../webdriver/test/testutil_test.js", [], ["goog.testing.jsunit","webdriver.test.testutil"]);
        96goog.addDependency("../webdriver/test/capabilities_test.js", [], ["goog.testing.jsunit","webdriver.Capabilities"]);
        97goog.addDependency("../webdriver/test/stacktrace_test.js", [], ["bot.Error","bot.ErrorCode","goog.string","goog.testing.JsUnitException","goog.testing.PropertyReplacer","goog.testing.StrictMock","goog.testing.jsunit","goog.testing.stacktrace","webdriver.stacktrace","webdriver.test.testutil"]);
        98goog.addDependency("../webdriver/test/http/http_test.js", [], ["bot.ErrorCode","goog.Uri","goog.json","goog.testing.MockControl","goog.testing.jsunit","webdriver.Command","webdriver.http.Client","webdriver.http.Executor","webdriver.promise","webdriver.test.testutil"]);
        99goog.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"]);
        100goog.addDependency("../webdriver/test/http/corsclient_test.js", [], ["goog.json","goog.testing.MockControl","goog.testing.PropertyReplacer","goog.testing.jsunit","webdriver.http.CorsClient","webdriver.http.Request","webdriver.test.testutil"]);
        101goog.addDependency("../webdriver/http/corsclient.js", ["webdriver.http.CorsClient"], ["goog.json","webdriver.http.Response"]);
        102goog.addDependency("../webdriver/test/http/xhrclient_test.js", [], ["goog.json","goog.testing.MockControl","goog.testing.PropertyReplacer","goog.testing.jsunit","webdriver.http.Request","webdriver.http.XhrClient","webdriver.promise","webdriver.test.testutil"]);
        103goog.addDependency("../webdriver/http/xhrclient.js", ["webdriver.http.XhrClient"], ["goog.json","goog.net.XmlHttp","webdriver.http.Response"]);
        104goog.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"]);
        105goog.addDependency("net/wrapperxmlhttpfactory.js", ["goog.net.WrapperXmlHttpFactory"], ["goog.net.XhrLike","goog.net.XmlHttpFactory"]);
        106goog.addDependency("net/xhrlike.js", ["goog.net.XhrLike"], []);
        107goog.addDependency("net/xmlhttpfactory.js", ["goog.net.XmlHttpFactory"], ["goog.net.XhrLike"]);
        108goog.addDependency("../webdriver/test/testing/client_test.js", [], ["goog.testing.MockControl","goog.testing.PropertyReplacer","goog.testing.jsunit","webdriver.testing.Client"]);
        109goog.addDependency("../webdriver/testing/client.js", ["webdriver.testing.Client"], ["goog.json","goog.net.XmlHttp"]);
        110goog.addDependency("../webdriver/test/testing/flowtester_test.js", [], ["goog.testing.MockControl","goog.testing.jsunit","webdriver.promise","webdriver.testing.Clock","webdriver.testing.promise.FlowTester"]);
        111goog.addDependency("../webdriver/test/testing/testcase_test.js", [], ["goog.testing.MockControl","goog.testing.PropertyReplacer","goog.testing.mockmatchers","goog.testing.jsunit","goog.testing.recordFunction","webdriver.test.testutil","webdriver.testing.TestCase","webdriver.testing.promise.FlowTester"]);
        112goog.addDependency("../webdriver/testing/testcase.js", ["webdriver.testing.TestCase"], ["goog.testing.TestCase","webdriver.promise.ControlFlow","webdriver.testing.asserts"]);
        113goog.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"]);
        114goog.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"]);
        115goog.addDependency("labs/testing/matcher.js", ["goog.labs.testing.Matcher"], []);
        116goog.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"]);
        117goog.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"]);
        118goog.addDependency("labs/testing/logicmatcher.js", ["goog.labs.testing.AllOfMatcher","goog.labs.testing.AnyOfMatcher","goog.labs.testing.IsNotMatcher"], ["goog.array","goog.labs.testing.Matcher"]);
        119goog.addDependency("labs/testing/assertthat.js", ["goog.labs.testing.MatcherError","goog.labs.testing.assertThat"], ["goog.asserts","goog.debug.Error","goog.labs.testing.Matcher"]);
        120goog.addDependency("../webdriver/test/testing/asserts_test.js", [], ["goog.testing.jsunit","webdriver.test.testutil","webdriver.testing.assert","webdriver.testing.asserts"]);
        121goog.addDependency("../atoms/json.js", ["bot.json"], ["bot.userAgent","goog.json","goog.userAgent"]);
        122goog.addDependency("../atoms/userAgent.js", ["bot.userAgent"], ["goog.string","goog.userAgent","goog.userAgent.product","goog.userAgent.product.isVersion"]);
        123goog.addDependency("useragent/product.js", ["goog.userAgent.product"], ["goog.userAgent"]);
        124goog.addDependency("useragent/product_isversion.js", ["goog.userAgent.product.isVersion"], ["goog.userAgent.product"]);
        125goog.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"]);
        126goog.addDependency("../webdriver/abstractbuilder.js", ["webdriver.AbstractBuilder"], ["webdriver.Capabilities","webdriver.process"]);
        127goog.addDependency("../webdriver/firefoxdomexecutor.js", ["webdriver.FirefoxDomExecutor"], ["bot.response","goog.json","goog.userAgent.product","webdriver.Command","webdriver.CommandName"]);
        128goog.addDependency("../webdriver/testing/window.js", ["webdriver.testing.Window"], ["goog.string","webdriver.promise.Promise"]);
        129goog.addDependency("../webdriver/testing/jsunit.js", ["webdriver.testing.jsunit","webdriver.testing.jsunit.TestRunner"], ["goog.testing.TestRunner","webdriver.testing.Client","webdriver.testing.TestCase"]);
        130goog.addDependency("../webdriver/test/webdriver_generator_test.js", ["webdriver.test.WebDriver.generator.test"], ["goog.testing.AsyncTestCase","goog.testing.jsunit","webdriver.Session","webdriver.WebDriver"]);
        131goog.addDependency("testing/asynctestcase.js", ["goog.testing.AsyncTestCase","goog.testing.AsyncTestCase.ControlBreakingException"], ["goog.testing.TestCase","goog.testing.TestCase.Test","goog.testing.asserts"]);
        132goog.addDependency("../webdriver/test/promise_generator_test.js", ["webdriver.test.promise.generator.test"], ["goog.testing.AsyncTestCase","goog.testing.jsunit","webdriver.promise"]);
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/disposable/disposable.js.src.html b/docs/api/javascript/source/lib/goog/disposable/disposable.js.src.html new file mode 100644 index 0000000000000..903e8b2601829 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/disposable/disposable.js.src.html @@ -0,0 +1 @@ +disposable.js

        lib/goog/disposable/disposable.js

        1// Copyright 2005 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 Implements the disposable interface. The dispose method is used
        17 * to clean up references and resources.
        18 * @author arv@google.com (Erik Arvidsson)
        19 */
        20
        21
        22goog.provide('goog.Disposable');
        23/** @suppress {extraProvide} */
        24goog.provide('goog.dispose');
        25/** @suppress {extraProvide} */
        26goog.provide('goog.disposeAll');
        27
        28goog.require('goog.disposable.IDisposable');
        29
        30
        31
        32/**
        33 * Class that provides the basic implementation for disposable objects. If your
        34 * class holds one or more references to COM objects, DOM nodes, or other
        35 * disposable objects, it should extend this class or implement the disposable
        36 * interface (defined in goog.disposable.IDisposable).
        37 * @constructor
        38 * @implements {goog.disposable.IDisposable}
        39 */
        40goog.Disposable = function() {
        41 if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {
        42 if (goog.Disposable.INCLUDE_STACK_ON_CREATION) {
        43 this.creationStack = new Error().stack;
        44 }
        45 goog.Disposable.instances_[goog.getUid(this)] = this;
        46 }
        47 // Support sealing
        48 this.disposed_ = this.disposed_;
        49 this.onDisposeCallbacks_ = this.onDisposeCallbacks_;
        50};
        51
        52
        53/**
        54 * @enum {number} Different monitoring modes for Disposable.
        55 */
        56goog.Disposable.MonitoringMode = {
        57 /**
        58 * No monitoring.
        59 */
        60 OFF: 0,
        61 /**
        62 * Creating and disposing the goog.Disposable instances is monitored. All
        63 * disposable objects need to call the {@code goog.Disposable} base
        64 * constructor. The PERMANENT mode must be switched on before creating any
        65 * goog.Disposable instances.
        66 */
        67 PERMANENT: 1,
        68 /**
        69 * INTERACTIVE mode can be switched on and off on the fly without producing
        70 * errors. It also doesn't warn if the disposable objects don't call the
        71 * {@code goog.Disposable} base constructor.
        72 */
        73 INTERACTIVE: 2
        74};
        75
        76
        77/**
        78 * @define {number} The monitoring mode of the goog.Disposable
        79 * instances. Default is OFF. Switching on the monitoring is only
        80 * recommended for debugging because it has a significant impact on
        81 * performance and memory usage. If switched off, the monitoring code
        82 * compiles down to 0 bytes.
        83 */
        84goog.define('goog.Disposable.MONITORING_MODE', 0);
        85
        86
        87/**
        88 * @define {boolean} Whether to attach creation stack to each created disposable
        89 * instance; This is only relevant for when MonitoringMode != OFF.
        90 */
        91goog.define('goog.Disposable.INCLUDE_STACK_ON_CREATION', true);
        92
        93
        94/**
        95 * Maps the unique ID of every undisposed {@code goog.Disposable} object to
        96 * the object itself.
        97 * @type {!Object.<number, !goog.Disposable>}
        98 * @private
        99 */
        100goog.Disposable.instances_ = {};
        101
        102
        103/**
        104 * @return {!Array.<!goog.Disposable>} All {@code goog.Disposable} objects that
        105 * haven't been disposed of.
        106 */
        107goog.Disposable.getUndisposedObjects = function() {
        108 var ret = [];
        109 for (var id in goog.Disposable.instances_) {
        110 if (goog.Disposable.instances_.hasOwnProperty(id)) {
        111 ret.push(goog.Disposable.instances_[Number(id)]);
        112 }
        113 }
        114 return ret;
        115};
        116
        117
        118/**
        119 * Clears the registry of undisposed objects but doesn't dispose of them.
        120 */
        121goog.Disposable.clearUndisposedObjects = function() {
        122 goog.Disposable.instances_ = {};
        123};
        124
        125
        126/**
        127 * Whether the object has been disposed of.
        128 * @type {boolean}
        129 * @private
        130 */
        131goog.Disposable.prototype.disposed_ = false;
        132
        133
        134/**
        135 * Callbacks to invoke when this object is disposed.
        136 * @type {Array.<!Function>}
        137 * @private
        138 */
        139goog.Disposable.prototype.onDisposeCallbacks_;
        140
        141
        142/**
        143 * If monitoring the goog.Disposable instances is enabled, stores the creation
        144 * stack trace of the Disposable instance.
        145 * @const {string}
        146 */
        147goog.Disposable.prototype.creationStack;
        148
        149
        150/**
        151 * @return {boolean} Whether the object has been disposed of.
        152 * @override
        153 */
        154goog.Disposable.prototype.isDisposed = function() {
        155 return this.disposed_;
        156};
        157
        158
        159/**
        160 * @return {boolean} Whether the object has been disposed of.
        161 * @deprecated Use {@link #isDisposed} instead.
        162 */
        163goog.Disposable.prototype.getDisposed = goog.Disposable.prototype.isDisposed;
        164
        165
        166/**
        167 * Disposes of the object. If the object hasn't already been disposed of, calls
        168 * {@link #disposeInternal}. Classes that extend {@code goog.Disposable} should
        169 * override {@link #disposeInternal} in order to delete references to COM
        170 * objects, DOM nodes, and other disposable objects. Reentrant.
        171 *
        172 * @return {void} Nothing.
        173 * @override
        174 */
        175goog.Disposable.prototype.dispose = function() {
        176 if (!this.disposed_) {
        177 // Set disposed_ to true first, in case during the chain of disposal this
        178 // gets disposed recursively.
        179 this.disposed_ = true;
        180 this.disposeInternal();
        181 if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {
        182 var uid = goog.getUid(this);
        183 if (goog.Disposable.MONITORING_MODE ==
        184 goog.Disposable.MonitoringMode.PERMANENT &&
        185 !goog.Disposable.instances_.hasOwnProperty(uid)) {
        186 throw Error(this + ' did not call the goog.Disposable base ' +
        187 'constructor or was disposed of after a clearUndisposedObjects ' +
        188 'call');
        189 }
        190 delete goog.Disposable.instances_[uid];
        191 }
        192 }
        193};
        194
        195
        196/**
        197 * Associates a disposable object with this object so that they will be disposed
        198 * together.
        199 * @param {goog.disposable.IDisposable} disposable that will be disposed when
        200 * this object is disposed.
        201 */
        202goog.Disposable.prototype.registerDisposable = function(disposable) {
        203 this.addOnDisposeCallback(goog.partial(goog.dispose, disposable));
        204};
        205
        206
        207/**
        208 * Invokes a callback function when this object is disposed. Callbacks are
        209 * invoked in the order in which they were added.
        210 * @param {function(this:T):?} callback The callback function.
        211 * @param {T=} opt_scope An optional scope to call the callback in.
        212 * @template T
        213 */
        214goog.Disposable.prototype.addOnDisposeCallback = function(callback, opt_scope) {
        215 if (!this.onDisposeCallbacks_) {
        216 this.onDisposeCallbacks_ = [];
        217 }
        218
        219 this.onDisposeCallbacks_.push(
        220 goog.isDef(opt_scope) ? goog.bind(callback, opt_scope) : callback);
        221};
        222
        223
        224/**
        225 * Deletes or nulls out any references to COM objects, DOM nodes, or other
        226 * disposable objects. Classes that extend {@code goog.Disposable} should
        227 * override this method.
        228 * Not reentrant. To avoid calling it twice, it must only be called from the
        229 * subclass' {@code disposeInternal} method. Everywhere else the public
        230 * {@code dispose} method must be used.
        231 * For example:
        232 * <pre>
        233 * mypackage.MyClass = function() {
        234 * mypackage.MyClass.base(this, 'constructor');
        235 * // Constructor logic specific to MyClass.
        236 * ...
        237 * };
        238 * goog.inherits(mypackage.MyClass, goog.Disposable);
        239 *
        240 * mypackage.MyClass.prototype.disposeInternal = function() {
        241 * // Dispose logic specific to MyClass.
        242 * ...
        243 * // Call superclass's disposeInternal at the end of the subclass's, like
        244 * // in C++, to avoid hard-to-catch issues.
        245 * mypackage.MyClass.base(this, 'disposeInternal');
        246 * };
        247 * </pre>
        248 * @protected
        249 */
        250goog.Disposable.prototype.disposeInternal = function() {
        251 if (this.onDisposeCallbacks_) {
        252 while (this.onDisposeCallbacks_.length) {
        253 this.onDisposeCallbacks_.shift()();
        254 }
        255 }
        256};
        257
        258
        259/**
        260 * Returns True if we can verify the object is disposed.
        261 * Calls {@code isDisposed} on the argument if it supports it. If obj
        262 * is not an object with an isDisposed() method, return false.
        263 * @param {*} obj The object to investigate.
        264 * @return {boolean} True if we can verify the object is disposed.
        265 */
        266goog.Disposable.isDisposed = function(obj) {
        267 if (obj && typeof obj.isDisposed == 'function') {
        268 return obj.isDisposed();
        269 }
        270 return false;
        271};
        272
        273
        274/**
        275 * Calls {@code dispose} on the argument if it supports it. If obj is not an
        276 * object with a dispose() method, this is a no-op.
        277 * @param {*} obj The object to dispose of.
        278 */
        279goog.dispose = function(obj) {
        280 if (obj && typeof obj.dispose == 'function') {
        281 obj.dispose();
        282 }
        283};
        284
        285
        286/**
        287 * Calls {@code dispose} on each member of the list that supports it. (If the
        288 * member is an ArrayLike, then {@code goog.disposeAll()} will be called
        289 * recursively on each of its members.) If the member is not an object with a
        290 * {@code dispose()} method, then it is ignored.
        291 * @param {...*} var_args The list.
        292 */
        293goog.disposeAll = function(var_args) {
        294 for (var i = 0, len = arguments.length; i < len; ++i) {
        295 var disposable = arguments[i];
        296 if (goog.isArrayLike(disposable)) {
        297 goog.disposeAll.apply(null, disposable);
        298 } else {
        299 goog.dispose(disposable);
        300 }
        301 }
        302};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/disposable/idisposable.js.src.html b/docs/api/javascript/source/lib/goog/disposable/idisposable.js.src.html new file mode 100644 index 0000000000000..0964c46a4d955 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/disposable/idisposable.js.src.html @@ -0,0 +1 @@ +idisposable.js

        lib/goog/disposable/idisposable.js

        1// Copyright 2011 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 the disposable interface. A disposable object
        17 * has a dispose method to to clean up references and resources.
        18 * @author nnaze@google.com (Nathan Naze)
        19 */
        20
        21
        22goog.provide('goog.disposable.IDisposable');
        23
        24
        25
        26/**
        27 * Interface for a disposable object. If a instance requires cleanup
        28 * (references COM objects, DOM notes, or other disposable objects), it should
        29 * implement this interface (it may subclass goog.Disposable).
        30 * @interface
        31 */
        32goog.disposable.IDisposable = function() {};
        33
        34
        35/**
        36 * Disposes of the object and its resources.
        37 * @return {void} Nothing.
        38 */
        39goog.disposable.IDisposable.prototype.dispose = goog.abstractMethod;
        40
        41
        42/**
        43 * @return {boolean} Whether the object has been disposed of.
        44 */
        45goog.disposable.IDisposable.prototype.isDisposed = goog.abstractMethod;
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/dom/browserfeature.js.src.html b/docs/api/javascript/source/lib/goog/dom/browserfeature.js.src.html new file mode 100644 index 0000000000000..0430c08003b0b --- /dev/null +++ b/docs/api/javascript/source/lib/goog/dom/browserfeature.js.src.html @@ -0,0 +1 @@ +browserfeature.js

        lib/goog/dom/browserfeature.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 Browser capability checks for the dom package.
        17 *
        18 */
        19
        20
        21goog.provide('goog.dom.BrowserFeature');
        22
        23goog.require('goog.userAgent');
        24
        25
        26/**
        27 * Enum of browser capabilities.
        28 * @enum {boolean}
        29 */
        30goog.dom.BrowserFeature = {
        31 /**
        32 * Whether attributes 'name' and 'type' can be added to an element after it's
        33 * created. False in Internet Explorer prior to version 9.
        34 */
        35 CAN_ADD_NAME_OR_TYPE_ATTRIBUTES: !goog.userAgent.IE ||
        36 goog.userAgent.isDocumentModeOrHigher(9),
        37
        38 /**
        39 * Whether we can use element.children to access an element's Element
        40 * children. Available since Gecko 1.9.1, IE 9. (IE<9 also includes comment
        41 * nodes in the collection.)
        42 */
        43 CAN_USE_CHILDREN_ATTRIBUTE: !goog.userAgent.GECKO && !goog.userAgent.IE ||
        44 goog.userAgent.IE && goog.userAgent.isDocumentModeOrHigher(9) ||
        45 goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9.1'),
        46
        47 /**
        48 * Opera, Safari 3, and Internet Explorer 9 all support innerText but they
        49 * include text nodes in script and style tags. Not document-mode-dependent.
        50 */
        51 CAN_USE_INNER_TEXT: (
        52 goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9')),
        53
        54 /**
        55 * MSIE, Opera, and Safari>=4 support element.parentElement to access an
        56 * element's parent if it is an Element.
        57 */
        58 CAN_USE_PARENT_ELEMENT_PROPERTY: goog.userAgent.IE || goog.userAgent.OPERA ||
        59 goog.userAgent.WEBKIT,
        60
        61 /**
        62 * Whether NoScope elements need a scoped element written before them in
        63 * innerHTML.
        64 * MSDN: http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx#1
        65 */
        66 INNER_HTML_NEEDS_SCOPED_ELEMENT: goog.userAgent.IE,
        67
        68 /**
        69 * Whether we use legacy IE range API.
        70 */
        71 LEGACY_IE_RANGES: goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)
        72};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/dom/dom.js.src.html b/docs/api/javascript/source/lib/goog/dom/dom.js.src.html new file mode 100644 index 0000000000000..521ebfcf74011 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/dom/dom.js.src.html @@ -0,0 +1 @@ +dom.js

        lib/goog/dom/dom.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 the browser's Document Object Model
        17 * Inspiration taken *heavily* from mochikit (http://mochikit.com/).
        18 *
        19 * You can use {@link goog.dom.DomHelper} to create new dom helpers that refer
        20 * to a different document object. This is useful if you are working with
        21 * frames or multiple windows.
        22 *
        23 */
        24
        25
        26// TODO(arv): Rename/refactor getTextContent and getRawTextContent. The problem
        27// is that getTextContent should mimic the DOM3 textContent. We should add a
        28// getInnerText (or getText) which tries to return the visible text, innerText.
        29
        30
        31goog.provide('goog.dom');
        32goog.provide('goog.dom.Appendable');
        33goog.provide('goog.dom.DomHelper');
        34
        35goog.require('goog.array');
        36goog.require('goog.asserts');
        37goog.require('goog.dom.BrowserFeature');
        38goog.require('goog.dom.NodeType');
        39goog.require('goog.dom.TagName');
        40goog.require('goog.math.Coordinate');
        41goog.require('goog.math.Size');
        42goog.require('goog.object');
        43goog.require('goog.string');
        44goog.require('goog.userAgent');
        45
        46
        47/**
        48 * @define {boolean} Whether we know at compile time that the browser is in
        49 * quirks mode.
        50 */
        51goog.define('goog.dom.ASSUME_QUIRKS_MODE', false);
        52
        53
        54/**
        55 * @define {boolean} Whether we know at compile time that the browser is in
        56 * standards compliance mode.
        57 */
        58goog.define('goog.dom.ASSUME_STANDARDS_MODE', false);
        59
        60
        61/**
        62 * Whether we know the compatibility mode at compile time.
        63 * @type {boolean}
        64 * @private
        65 */
        66goog.dom.COMPAT_MODE_KNOWN_ =
        67 goog.dom.ASSUME_QUIRKS_MODE || goog.dom.ASSUME_STANDARDS_MODE;
        68
        69
        70/**
        71 * Gets the DomHelper object for the document where the element resides.
        72 * @param {(Node|Window)=} opt_element If present, gets the DomHelper for this
        73 * element.
        74 * @return {!goog.dom.DomHelper} The DomHelper.
        75 */
        76goog.dom.getDomHelper = function(opt_element) {
        77 return opt_element ?
        78 new goog.dom.DomHelper(goog.dom.getOwnerDocument(opt_element)) :
        79 (goog.dom.defaultDomHelper_ ||
        80 (goog.dom.defaultDomHelper_ = new goog.dom.DomHelper()));
        81};
        82
        83
        84/**
        85 * Cached default DOM helper.
        86 * @type {goog.dom.DomHelper}
        87 * @private
        88 */
        89goog.dom.defaultDomHelper_;
        90
        91
        92/**
        93 * Gets the document object being used by the dom library.
        94 * @return {!Document} Document object.
        95 */
        96goog.dom.getDocument = function() {
        97 return document;
        98};
        99
        100
        101/**
        102 * Gets an element from the current document by element id.
        103 *
        104 * If an Element is passed in, it is returned.
        105 *
        106 * @param {string|Element} element Element ID or a DOM node.
        107 * @return {Element} The element with the given ID, or the node passed in.
        108 */
        109goog.dom.getElement = function(element) {
        110 return goog.dom.getElementHelper_(document, element);
        111};
        112
        113
        114/**
        115 * Gets an element by id from the given document (if present).
        116 * If an element is given, it is returned.
        117 * @param {!Document} doc
        118 * @param {string|Element} element Element ID or a DOM node.
        119 * @return {Element} The resulting element.
        120 * @private
        121 */
        122goog.dom.getElementHelper_ = function(doc, element) {
        123 return goog.isString(element) ?
        124 doc.getElementById(element) :
        125 element;
        126};
        127
        128
        129/**
        130 * Gets an element by id, asserting that the element is found.
        131 *
        132 * This is used when an element is expected to exist, and should fail with
        133 * an assertion error if it does not (if assertions are enabled).
        134 *
        135 * @param {string} id Element ID.
        136 * @return {!Element} The element with the given ID, if it exists.
        137 */
        138goog.dom.getRequiredElement = function(id) {
        139 return goog.dom.getRequiredElementHelper_(document, id);
        140};
        141
        142
        143/**
        144 * Helper function for getRequiredElementHelper functions, both static and
        145 * on DomHelper. Asserts the element with the given id exists.
        146 * @param {!Document} doc
        147 * @param {string} id
        148 * @return {!Element} The element with the given ID, if it exists.
        149 * @private
        150 */
        151goog.dom.getRequiredElementHelper_ = function(doc, id) {
        152 // To prevent users passing in Elements as is permitted in getElement().
        153 goog.asserts.assertString(id);
        154 var element = goog.dom.getElementHelper_(doc, id);
        155 element = goog.asserts.assertElement(element,
        156 'No element found with id: ' + id);
        157 return element;
        158};
        159
        160
        161/**
        162 * Alias for getElement.
        163 * @param {string|Element} element Element ID or a DOM node.
        164 * @return {Element} The element with the given ID, or the node passed in.
        165 * @deprecated Use {@link goog.dom.getElement} instead.
        166 */
        167goog.dom.$ = goog.dom.getElement;
        168
        169
        170/**
        171 * Looks up elements by both tag and class name, using browser native functions
        172 * ({@code querySelectorAll}, {@code getElementsByTagName} or
        173 * {@code getElementsByClassName}) where possible. This function
        174 * is a useful, if limited, way of collecting a list of DOM elements
        175 * with certain characteristics. {@code goog.dom.query} offers a
        176 * more powerful and general solution which allows matching on CSS3
        177 * selector expressions, but at increased cost in code size. If all you
        178 * need is particular tags belonging to a single class, this function
        179 * is fast and sleek.
        180 *
        181 * Note that tag names are case sensitive in the SVG namespace, and this
        182 * function converts opt_tag to uppercase for comparisons. For queries in the
        183 * SVG namespace you should use querySelector or querySelectorAll instead.
        184 * https://bugzilla.mozilla.org/show_bug.cgi?id=963870
        185 * https://bugs.webkit.org/show_bug.cgi?id=83438
        186 *
        187 * @see {goog.dom.query}
        188 *
        189 * @param {?string=} opt_tag Element tag name.
        190 * @param {?string=} opt_class Optional class name.
        191 * @param {(Document|Element)=} opt_el Optional element to look in.
        192 * @return { {length: number} } Array-like list of elements (only a length
        193 * property and numerical indices are guaranteed to exist).
        194 */
        195goog.dom.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) {
        196 return goog.dom.getElementsByTagNameAndClass_(document, opt_tag, opt_class,
        197 opt_el);
        198};
        199
        200
        201/**
        202 * Returns a static, array-like list of the elements with the provided
        203 * className.
        204 * @see {goog.dom.query}
        205 * @param {string} className the name of the class to look for.
        206 * @param {(Document|Element)=} opt_el Optional element to look in.
        207 * @return { {length: number} } The items found with the class name provided.
        208 */
        209goog.dom.getElementsByClass = function(className, opt_el) {
        210 var parent = opt_el || document;
        211 if (goog.dom.canUseQuerySelector_(parent)) {
        212 return parent.querySelectorAll('.' + className);
        213 }
        214 return goog.dom.getElementsByTagNameAndClass_(
        215 document, '*', className, opt_el);
        216};
        217
        218
        219/**
        220 * Returns the first element with the provided className.
        221 * @see {goog.dom.query}
        222 * @param {string} className the name of the class to look for.
        223 * @param {Element|Document=} opt_el Optional element to look in.
        224 * @return {Element} The first item with the class name provided.
        225 */
        226goog.dom.getElementByClass = function(className, opt_el) {
        227 var parent = opt_el || document;
        228 var retVal = null;
        229 if (goog.dom.canUseQuerySelector_(parent)) {
        230 retVal = parent.querySelector('.' + className);
        231 } else {
        232 retVal = goog.dom.getElementsByTagNameAndClass_(
        233 document, '*', className, opt_el)[0];
        234 }
        235 return retVal || null;
        236};
        237
        238
        239/**
        240 * Ensures an element with the given className exists, and then returns the
        241 * first element with the provided className.
        242 * @see {goog.dom.query}
        243 * @param {string} className the name of the class to look for.
        244 * @param {!Element|!Document=} opt_root Optional element or document to look
        245 * in.
        246 * @return {!Element} The first item with the class name provided.
        247 * @throws {goog.asserts.AssertionError} Thrown if no element is found.
        248 */
        249goog.dom.getRequiredElementByClass = function(className, opt_root) {
        250 var retValue = goog.dom.getElementByClass(className, opt_root);
        251 return goog.asserts.assert(retValue,
        252 'No element found with className: ' + className);
        253};
        254
        255
        256/**
        257 * Prefer the standardized (http://www.w3.org/TR/selectors-api/), native and
        258 * fast W3C Selectors API.
        259 * @param {!(Element|Document)} parent The parent document object.
        260 * @return {boolean} whether or not we can use parent.querySelector* APIs.
        261 * @private
        262 */
        263goog.dom.canUseQuerySelector_ = function(parent) {
        264 return !!(parent.querySelectorAll && parent.querySelector);
        265};
        266
        267
        268/**
        269 * Helper for {@code getElementsByTagNameAndClass}.
        270 * @param {!Document} doc The document to get the elements in.
        271 * @param {?string=} opt_tag Element tag name.
        272 * @param {?string=} opt_class Optional class name.
        273 * @param {(Document|Element)=} opt_el Optional element to look in.
        274 * @return { {length: number} } Array-like list of elements (only a length
        275 * property and numerical indices are guaranteed to exist).
        276 * @private
        277 */
        278goog.dom.getElementsByTagNameAndClass_ = function(doc, opt_tag, opt_class,
        279 opt_el) {
        280 var parent = opt_el || doc;
        281 var tagName = (opt_tag && opt_tag != '*') ? opt_tag.toUpperCase() : '';
        282
        283 if (goog.dom.canUseQuerySelector_(parent) &&
        284 (tagName || opt_class)) {
        285 var query = tagName + (opt_class ? '.' + opt_class : '');
        286 return parent.querySelectorAll(query);
        287 }
        288
        289 // Use the native getElementsByClassName if available, under the assumption
        290 // that even when the tag name is specified, there will be fewer elements to
        291 // filter through when going by class than by tag name
        292 if (opt_class && parent.getElementsByClassName) {
        293 var els = parent.getElementsByClassName(opt_class);
        294
        295 if (tagName) {
        296 var arrayLike = {};
        297 var len = 0;
        298
        299 // Filter for specific tags if requested.
        300 for (var i = 0, el; el = els[i]; i++) {
        301 if (tagName == el.nodeName) {
        302 arrayLike[len++] = el;
        303 }
        304 }
        305 arrayLike.length = len;
        306
        307 return arrayLike;
        308 } else {
        309 return els;
        310 }
        311 }
        312
        313 var els = parent.getElementsByTagName(tagName || '*');
        314
        315 if (opt_class) {
        316 var arrayLike = {};
        317 var len = 0;
        318 for (var i = 0, el; el = els[i]; i++) {
        319 var className = el.className;
        320 // Check if className has a split function since SVG className does not.
        321 if (typeof className.split == 'function' &&
        322 goog.array.contains(className.split(/\s+/), opt_class)) {
        323 arrayLike[len++] = el;
        324 }
        325 }
        326 arrayLike.length = len;
        327 return arrayLike;
        328 } else {
        329 return els;
        330 }
        331};
        332
        333
        334/**
        335 * Alias for {@code getElementsByTagNameAndClass}.
        336 * @param {?string=} opt_tag Element tag name.
        337 * @param {?string=} opt_class Optional class name.
        338 * @param {Element=} opt_el Optional element to look in.
        339 * @return { {length: number} } Array-like list of elements (only a length
        340 * property and numerical indices are guaranteed to exist).
        341 * @deprecated Use {@link goog.dom.getElementsByTagNameAndClass} instead.
        342 */
        343goog.dom.$$ = goog.dom.getElementsByTagNameAndClass;
        344
        345
        346/**
        347 * Sets multiple properties on a node.
        348 * @param {Element} element DOM node to set properties on.
        349 * @param {Object} properties Hash of property:value pairs.
        350 */
        351goog.dom.setProperties = function(element, properties) {
        352 goog.object.forEach(properties, function(val, key) {
        353 if (key == 'style') {
        354 element.style.cssText = val;
        355 } else if (key == 'class') {
        356 element.className = val;
        357 } else if (key == 'for') {
        358 element.htmlFor = val;
        359 } else if (key in goog.dom.DIRECT_ATTRIBUTE_MAP_) {
        360 element.setAttribute(goog.dom.DIRECT_ATTRIBUTE_MAP_[key], val);
        361 } else if (goog.string.startsWith(key, 'aria-') ||
        362 goog.string.startsWith(key, 'data-')) {
        363 element.setAttribute(key, val);
        364 } else {
        365 element[key] = val;
        366 }
        367 });
        368};
        369
        370
        371/**
        372 * Map of attributes that should be set using
        373 * element.setAttribute(key, val) instead of element[key] = val. Used
        374 * by goog.dom.setProperties.
        375 *
        376 * @type {Object}
        377 * @private
        378 */
        379goog.dom.DIRECT_ATTRIBUTE_MAP_ = {
        380 'cellpadding': 'cellPadding',
        381 'cellspacing': 'cellSpacing',
        382 'colspan': 'colSpan',
        383 'frameborder': 'frameBorder',
        384 'height': 'height',
        385 'maxlength': 'maxLength',
        386 'role': 'role',
        387 'rowspan': 'rowSpan',
        388 'type': 'type',
        389 'usemap': 'useMap',
        390 'valign': 'vAlign',
        391 'width': 'width'
        392};
        393
        394
        395/**
        396 * Gets the dimensions of the viewport.
        397 *
        398 * Gecko Standards mode:
        399 * docEl.clientWidth Width of viewport excluding scrollbar.
        400 * win.innerWidth Width of viewport including scrollbar.
        401 * body.clientWidth Width of body element.
        402 *
        403 * docEl.clientHeight Height of viewport excluding scrollbar.
        404 * win.innerHeight Height of viewport including scrollbar.
        405 * body.clientHeight Height of document.
        406 *
        407 * Gecko Backwards compatible mode:
        408 * docEl.clientWidth Width of viewport excluding scrollbar.
        409 * win.innerWidth Width of viewport including scrollbar.
        410 * body.clientWidth Width of viewport excluding scrollbar.
        411 *
        412 * docEl.clientHeight Height of document.
        413 * win.innerHeight Height of viewport including scrollbar.
        414 * body.clientHeight Height of viewport excluding scrollbar.
        415 *
        416 * IE6/7 Standards mode:
        417 * docEl.clientWidth Width of viewport excluding scrollbar.
        418 * win.innerWidth Undefined.
        419 * body.clientWidth Width of body element.
        420 *
        421 * docEl.clientHeight Height of viewport excluding scrollbar.
        422 * win.innerHeight Undefined.
        423 * body.clientHeight Height of document element.
        424 *
        425 * IE5 + IE6/7 Backwards compatible mode:
        426 * docEl.clientWidth 0.
        427 * win.innerWidth Undefined.
        428 * body.clientWidth Width of viewport excluding scrollbar.
        429 *
        430 * docEl.clientHeight 0.
        431 * win.innerHeight Undefined.
        432 * body.clientHeight Height of viewport excluding scrollbar.
        433 *
        434 * Opera 9 Standards and backwards compatible mode:
        435 * docEl.clientWidth Width of viewport excluding scrollbar.
        436 * win.innerWidth Width of viewport including scrollbar.
        437 * body.clientWidth Width of viewport excluding scrollbar.
        438 *
        439 * docEl.clientHeight Height of document.
        440 * win.innerHeight Height of viewport including scrollbar.
        441 * body.clientHeight Height of viewport excluding scrollbar.
        442 *
        443 * WebKit:
        444 * Safari 2
        445 * docEl.clientHeight Same as scrollHeight.
        446 * docEl.clientWidth Same as innerWidth.
        447 * win.innerWidth Width of viewport excluding scrollbar.
        448 * win.innerHeight Height of the viewport including scrollbar.
        449 * frame.innerHeight Height of the viewport exluding scrollbar.
        450 *
        451 * Safari 3 (tested in 522)
        452 *
        453 * docEl.clientWidth Width of viewport excluding scrollbar.
        454 * docEl.clientHeight Height of viewport excluding scrollbar in strict mode.
        455 * body.clientHeight Height of viewport excluding scrollbar in quirks mode.
        456 *
        457 * @param {Window=} opt_window Optional window element to test.
        458 * @return {!goog.math.Size} Object with values 'width' and 'height'.
        459 */
        460goog.dom.getViewportSize = function(opt_window) {
        461 // TODO(arv): This should not take an argument
        462 return goog.dom.getViewportSize_(opt_window || window);
        463};
        464
        465
        466/**
        467 * Helper for {@code getViewportSize}.
        468 * @param {Window} win The window to get the view port size for.
        469 * @return {!goog.math.Size} Object with values 'width' and 'height'.
        470 * @private
        471 */
        472goog.dom.getViewportSize_ = function(win) {
        473 var doc = win.document;
        474 var el = goog.dom.isCss1CompatMode_(doc) ? doc.documentElement : doc.body;
        475 return new goog.math.Size(el.clientWidth, el.clientHeight);
        476};
        477
        478
        479/**
        480 * Calculates the height of the document.
        481 *
        482 * @return {number} The height of the current document.
        483 */
        484goog.dom.getDocumentHeight = function() {
        485 return goog.dom.getDocumentHeight_(window);
        486};
        487
        488
        489/**
        490 * Calculates the height of the document of the given window.
        491 *
        492 * Function code copied from the opensocial gadget api:
        493 * gadgets.window.adjustHeight(opt_height)
        494 *
        495 * @private
        496 * @param {Window} win The window whose document height to retrieve.
        497 * @return {number} The height of the document of the given window.
        498 */
        499goog.dom.getDocumentHeight_ = function(win) {
        500 // NOTE(eae): This method will return the window size rather than the document
        501 // size in webkit quirks mode.
        502 var doc = win.document;
        503 var height = 0;
        504
        505 if (doc) {
        506 // Calculating inner content height is hard and different between
        507 // browsers rendering in Strict vs. Quirks mode. We use a combination of
        508 // three properties within document.body and document.documentElement:
        509 // - scrollHeight
        510 // - offsetHeight
        511 // - clientHeight
        512 // These values differ significantly between browsers and rendering modes.
        513 // But there are patterns. It just takes a lot of time and persistence
        514 // to figure out.
        515
        516 var body = doc.body;
        517 var docEl = doc.documentElement;
        518 if (!(docEl && body)) {
        519 return 0;
        520 }
        521
        522 // Get the height of the viewport
        523 var vh = goog.dom.getViewportSize_(win).height;
        524 if (goog.dom.isCss1CompatMode_(doc) && docEl.scrollHeight) {
        525 // In Strict mode:
        526 // The inner content height is contained in either:
        527 // document.documentElement.scrollHeight
        528 // document.documentElement.offsetHeight
        529 // Based on studying the values output by different browsers,
        530 // use the value that's NOT equal to the viewport height found above.
        531 height = docEl.scrollHeight != vh ?
        532 docEl.scrollHeight : docEl.offsetHeight;
        533 } else {
        534 // In Quirks mode:
        535 // documentElement.clientHeight is equal to documentElement.offsetHeight
        536 // except in IE. In most browsers, document.documentElement can be used
        537 // to calculate the inner content height.
        538 // However, in other browsers (e.g. IE), document.body must be used
        539 // instead. How do we know which one to use?
        540 // If document.documentElement.clientHeight does NOT equal
        541 // document.documentElement.offsetHeight, then use document.body.
        542 var sh = docEl.scrollHeight;
        543 var oh = docEl.offsetHeight;
        544 if (docEl.clientHeight != oh) {
        545 sh = body.scrollHeight;
        546 oh = body.offsetHeight;
        547 }
        548
        549 // Detect whether the inner content height is bigger or smaller
        550 // than the bounding box (viewport). If bigger, take the larger
        551 // value. If smaller, take the smaller value.
        552 if (sh > vh) {
        553 // Content is larger
        554 height = sh > oh ? sh : oh;
        555 } else {
        556 // Content is smaller
        557 height = sh < oh ? sh : oh;
        558 }
        559 }
        560 }
        561
        562 return height;
        563};
        564
        565
        566/**
        567 * Gets the page scroll distance as a coordinate object.
        568 *
        569 * @param {Window=} opt_window Optional window element to test.
        570 * @return {!goog.math.Coordinate} Object with values 'x' and 'y'.
        571 * @deprecated Use {@link goog.dom.getDocumentScroll} instead.
        572 */
        573goog.dom.getPageScroll = function(opt_window) {
        574 var win = opt_window || goog.global || window;
        575 return goog.dom.getDomHelper(win.document).getDocumentScroll();
        576};
        577
        578
        579/**
        580 * Gets the document scroll distance as a coordinate object.
        581 *
        582 * @return {!goog.math.Coordinate} Object with values 'x' and 'y'.
        583 */
        584goog.dom.getDocumentScroll = function() {
        585 return goog.dom.getDocumentScroll_(document);
        586};
        587
        588
        589/**
        590 * Helper for {@code getDocumentScroll}.
        591 *
        592 * @param {!Document} doc The document to get the scroll for.
        593 * @return {!goog.math.Coordinate} Object with values 'x' and 'y'.
        594 * @private
        595 */
        596goog.dom.getDocumentScroll_ = function(doc) {
        597 var el = goog.dom.getDocumentScrollElement_(doc);
        598 var win = goog.dom.getWindow_(doc);
        599 if (goog.userAgent.IE && goog.userAgent.isVersionOrHigher('10') &&
        600 win.pageYOffset != el.scrollTop) {
        601 // The keyboard on IE10 touch devices shifts the page using the pageYOffset
        602 // without modifying scrollTop. For this case, we want the body scroll
        603 // offsets.
        604 return new goog.math.Coordinate(el.scrollLeft, el.scrollTop);
        605 }
        606 return new goog.math.Coordinate(win.pageXOffset || el.scrollLeft,
        607 win.pageYOffset || el.scrollTop);
        608};
        609
        610
        611/**
        612 * Gets the document scroll element.
        613 * @return {!Element} Scrolling element.
        614 */
        615goog.dom.getDocumentScrollElement = function() {
        616 return goog.dom.getDocumentScrollElement_(document);
        617};
        618
        619
        620/**
        621 * Helper for {@code getDocumentScrollElement}.
        622 * @param {!Document} doc The document to get the scroll element for.
        623 * @return {!Element} Scrolling element.
        624 * @private
        625 */
        626goog.dom.getDocumentScrollElement_ = function(doc) {
        627 // WebKit needs body.scrollLeft in both quirks mode and strict mode. We also
        628 // default to the documentElement if the document does not have a body (e.g.
        629 // a SVG document).
        630 if (!goog.userAgent.WEBKIT && goog.dom.isCss1CompatMode_(doc)) {
        631 return doc.documentElement;
        632 }
        633 return doc.body || doc.documentElement;
        634};
        635
        636
        637/**
        638 * Gets the window object associated with the given document.
        639 *
        640 * @param {Document=} opt_doc Document object to get window for.
        641 * @return {!Window} The window associated with the given document.
        642 */
        643goog.dom.getWindow = function(opt_doc) {
        644 // TODO(arv): This should not take an argument.
        645 return opt_doc ? goog.dom.getWindow_(opt_doc) : window;
        646};
        647
        648
        649/**
        650 * Helper for {@code getWindow}.
        651 *
        652 * @param {!Document} doc Document object to get window for.
        653 * @return {!Window} The window associated with the given document.
        654 * @private
        655 */
        656goog.dom.getWindow_ = function(doc) {
        657 return doc.parentWindow || doc.defaultView;
        658};
        659
        660
        661/**
        662 * Returns a dom node with a set of attributes. This function accepts varargs
        663 * for subsequent nodes to be added. Subsequent nodes will be added to the
        664 * first node as childNodes.
        665 *
        666 * So:
        667 * <code>createDom('div', null, createDom('p'), createDom('p'));</code>
        668 * would return a div with two child paragraphs
        669 *
        670 * @param {string} tagName Tag to create.
        671 * @param {(Object|Array.<string>|string)=} opt_attributes If object, then a map
        672 * of name-value pairs for attributes. If a string, then this is the
        673 * className of the new element. If an array, the elements will be joined
        674 * together as the className of the new element.
        675 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
        676 * strings for text nodes. If one of the var_args is an array or NodeList,i
        677 * its elements will be added as childNodes instead.
        678 * @return {!Element} Reference to a DOM node.
        679 */
        680goog.dom.createDom = function(tagName, opt_attributes, var_args) {
        681 return goog.dom.createDom_(document, arguments);
        682};
        683
        684
        685/**
        686 * Helper for {@code createDom}.
        687 * @param {!Document} doc The document to create the DOM in.
        688 * @param {!Arguments} args Argument object passed from the callers. See
        689 * {@code goog.dom.createDom} for details.
        690 * @return {!Element} Reference to a DOM node.
        691 * @private
        692 */
        693goog.dom.createDom_ = function(doc, args) {
        694 var tagName = args[0];
        695 var attributes = args[1];
        696
        697 // Internet Explorer is dumb: http://msdn.microsoft.com/workshop/author/
        698 // dhtml/reference/properties/name_2.asp
        699 // Also does not allow setting of 'type' attribute on 'input' or 'button'.
        700 if (!goog.dom.BrowserFeature.CAN_ADD_NAME_OR_TYPE_ATTRIBUTES && attributes &&
        701 (attributes.name || attributes.type)) {
        702 var tagNameArr = ['<', tagName];
        703 if (attributes.name) {
        704 tagNameArr.push(' name="', goog.string.htmlEscape(attributes.name),
        705 '"');
        706 }
        707 if (attributes.type) {
        708 tagNameArr.push(' type="', goog.string.htmlEscape(attributes.type),
        709 '"');
        710
        711 // Clone attributes map to remove 'type' without mutating the input.
        712 var clone = {};
        713 goog.object.extend(clone, attributes);
        714
        715 // JSCompiler can't see how goog.object.extend added this property,
        716 // because it was essentially added by reflection.
        717 // So it needs to be quoted.
        718 delete clone['type'];
        719
        720 attributes = clone;
        721 }
        722 tagNameArr.push('>');
        723 tagName = tagNameArr.join('');
        724 }
        725
        726 var element = doc.createElement(tagName);
        727
        728 if (attributes) {
        729 if (goog.isString(attributes)) {
        730 element.className = attributes;
        731 } else if (goog.isArray(attributes)) {
        732 element.className = attributes.join(' ');
        733 } else {
        734 goog.dom.setProperties(element, attributes);
        735 }
        736 }
        737
        738 if (args.length > 2) {
        739 goog.dom.append_(doc, element, args, 2);
        740 }
        741
        742 return element;
        743};
        744
        745
        746/**
        747 * Appends a node with text or other nodes.
        748 * @param {!Document} doc The document to create new nodes in.
        749 * @param {!Node} parent The node to append nodes to.
        750 * @param {!Arguments} args The values to add. See {@code goog.dom.append}.
        751 * @param {number} startIndex The index of the array to start from.
        752 * @private
        753 */
        754goog.dom.append_ = function(doc, parent, args, startIndex) {
        755 function childHandler(child) {
        756 // TODO(user): More coercion, ala MochiKit?
        757 if (child) {
        758 parent.appendChild(goog.isString(child) ?
        759 doc.createTextNode(child) : child);
        760 }
        761 }
        762
        763 for (var i = startIndex; i < args.length; i++) {
        764 var arg = args[i];
        765 // TODO(attila): Fix isArrayLike to return false for a text node.
        766 if (goog.isArrayLike(arg) && !goog.dom.isNodeLike(arg)) {
        767 // If the argument is a node list, not a real array, use a clone,
        768 // because forEach can't be used to mutate a NodeList.
        769 goog.array.forEach(goog.dom.isNodeList(arg) ?
        770 goog.array.toArray(arg) : arg,
        771 childHandler);
        772 } else {
        773 childHandler(arg);
        774 }
        775 }
        776};
        777
        778
        779/**
        780 * Alias for {@code createDom}.
        781 * @param {string} tagName Tag to create.
        782 * @param {(string|Object)=} opt_attributes If object, then a map of name-value
        783 * pairs for attributes. If a string, then this is the className of the new
        784 * element.
        785 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
        786 * strings for text nodes. If one of the var_args is an array, its
        787 * children will be added as childNodes instead.
        788 * @return {!Element} Reference to a DOM node.
        789 * @deprecated Use {@link goog.dom.createDom} instead.
        790 */
        791goog.dom.$dom = goog.dom.createDom;
        792
        793
        794/**
        795 * Creates a new element.
        796 * @param {string} name Tag name.
        797 * @return {!Element} The new element.
        798 */
        799goog.dom.createElement = function(name) {
        800 return document.createElement(name);
        801};
        802
        803
        804/**
        805 * Creates a new text node.
        806 * @param {number|string} content Content.
        807 * @return {!Text} The new text node.
        808 */
        809goog.dom.createTextNode = function(content) {
        810 return document.createTextNode(String(content));
        811};
        812
        813
        814/**
        815 * Create a table.
        816 * @param {number} rows The number of rows in the table. Must be >= 1.
        817 * @param {number} columns The number of columns in the table. Must be >= 1.
        818 * @param {boolean=} opt_fillWithNbsp If true, fills table entries with nsbps.
        819 * @return {!Element} The created table.
        820 */
        821goog.dom.createTable = function(rows, columns, opt_fillWithNbsp) {
        822 return goog.dom.createTable_(document, rows, columns, !!opt_fillWithNbsp);
        823};
        824
        825
        826/**
        827 * Create a table.
        828 * @param {!Document} doc Document object to use to create the table.
        829 * @param {number} rows The number of rows in the table. Must be >= 1.
        830 * @param {number} columns The number of columns in the table. Must be >= 1.
        831 * @param {boolean} fillWithNbsp If true, fills table entries with nsbps.
        832 * @return {!Element} The created table.
        833 * @private
        834 */
        835goog.dom.createTable_ = function(doc, rows, columns, fillWithNbsp) {
        836 var rowHtml = ['<tr>'];
        837 for (var i = 0; i < columns; i++) {
        838 rowHtml.push(fillWithNbsp ? '<td>&nbsp;</td>' : '<td></td>');
        839 }
        840 rowHtml.push('</tr>');
        841 rowHtml = rowHtml.join('');
        842 var totalHtml = ['<table>'];
        843 for (i = 0; i < rows; i++) {
        844 totalHtml.push(rowHtml);
        845 }
        846 totalHtml.push('</table>');
        847
        848 var elem = doc.createElement(goog.dom.TagName.DIV);
        849 elem.innerHTML = totalHtml.join('');
        850 return /** @type {!Element} */ (elem.removeChild(elem.firstChild));
        851};
        852
        853
        854/**
        855 * Converts an HTML string into a document fragment. The string must be
        856 * sanitized in order to avoid cross-site scripting. For example
        857 * {@code goog.dom.htmlToDocumentFragment('&lt;img src=x onerror=alert(0)&gt;')}
        858 * triggers an alert in all browsers, even if the returned document fragment
        859 * is thrown away immediately.
        860 *
        861 * @param {string} htmlString The HTML string to convert.
        862 * @return {!Node} The resulting document fragment.
        863 */
        864goog.dom.htmlToDocumentFragment = function(htmlString) {
        865 return goog.dom.htmlToDocumentFragment_(document, htmlString);
        866};
        867
        868
        869/**
        870 * Helper for {@code htmlToDocumentFragment}.
        871 *
        872 * @param {!Document} doc The document.
        873 * @param {string} htmlString The HTML string to convert.
        874 * @return {!Node} The resulting document fragment.
        875 * @private
        876 */
        877goog.dom.htmlToDocumentFragment_ = function(doc, htmlString) {
        878 var tempDiv = doc.createElement('div');
        879 if (goog.dom.BrowserFeature.INNER_HTML_NEEDS_SCOPED_ELEMENT) {
        880 tempDiv.innerHTML = '<br>' + htmlString;
        881 tempDiv.removeChild(tempDiv.firstChild);
        882 } else {
        883 tempDiv.innerHTML = htmlString;
        884 }
        885 if (tempDiv.childNodes.length == 1) {
        886 return /** @type {!Node} */ (tempDiv.removeChild(tempDiv.firstChild));
        887 } else {
        888 var fragment = doc.createDocumentFragment();
        889 while (tempDiv.firstChild) {
        890 fragment.appendChild(tempDiv.firstChild);
        891 }
        892 return fragment;
        893 }
        894};
        895
        896
        897/**
        898 * Returns true if the browser is in "CSS1-compatible" (standards-compliant)
        899 * mode, false otherwise.
        900 * @return {boolean} True if in CSS1-compatible mode.
        901 */
        902goog.dom.isCss1CompatMode = function() {
        903 return goog.dom.isCss1CompatMode_(document);
        904};
        905
        906
        907/**
        908 * Returns true if the browser is in "CSS1-compatible" (standards-compliant)
        909 * mode, false otherwise.
        910 * @param {Document} doc The document to check.
        911 * @return {boolean} True if in CSS1-compatible mode.
        912 * @private
        913 */
        914goog.dom.isCss1CompatMode_ = function(doc) {
        915 if (goog.dom.COMPAT_MODE_KNOWN_) {
        916 return goog.dom.ASSUME_STANDARDS_MODE;
        917 }
        918
        919 return doc.compatMode == 'CSS1Compat';
        920};
        921
        922
        923/**
        924 * Determines if the given node can contain children, intended to be used for
        925 * HTML generation.
        926 *
        927 * IE natively supports node.canHaveChildren but has inconsistent behavior.
        928 * Prior to IE8 the base tag allows children and in IE9 all nodes return true
        929 * for canHaveChildren.
        930 *
        931 * In practice all non-IE browsers allow you to add children to any node, but
        932 * the behavior is inconsistent:
        933 *
        934 * <pre>
        935 * var a = document.createElement('br');
        936 * a.appendChild(document.createTextNode('foo'));
        937 * a.appendChild(document.createTextNode('bar'));
        938 * console.log(a.childNodes.length); // 2
        939 * console.log(a.innerHTML); // Chrome: "", IE9: "foobar", FF3.5: "foobar"
        940 * </pre>
        941 *
        942 * For more information, see:
        943 * http://dev.w3.org/html5/markup/syntax.html#syntax-elements
        944 *
        945 * TODO(user): Rename shouldAllowChildren() ?
        946 *
        947 * @param {Node} node The node to check.
        948 * @return {boolean} Whether the node can contain children.
        949 */
        950goog.dom.canHaveChildren = function(node) {
        951 if (node.nodeType != goog.dom.NodeType.ELEMENT) {
        952 return false;
        953 }
        954 switch (node.tagName) {
        955 case goog.dom.TagName.APPLET:
        956 case goog.dom.TagName.AREA:
        957 case goog.dom.TagName.BASE:
        958 case goog.dom.TagName.BR:
        959 case goog.dom.TagName.COL:
        960 case goog.dom.TagName.COMMAND:
        961 case goog.dom.TagName.EMBED:
        962 case goog.dom.TagName.FRAME:
        963 case goog.dom.TagName.HR:
        964 case goog.dom.TagName.IMG:
        965 case goog.dom.TagName.INPUT:
        966 case goog.dom.TagName.IFRAME:
        967 case goog.dom.TagName.ISINDEX:
        968 case goog.dom.TagName.KEYGEN:
        969 case goog.dom.TagName.LINK:
        970 case goog.dom.TagName.NOFRAMES:
        971 case goog.dom.TagName.NOSCRIPT:
        972 case goog.dom.TagName.META:
        973 case goog.dom.TagName.OBJECT:
        974 case goog.dom.TagName.PARAM:
        975 case goog.dom.TagName.SCRIPT:
        976 case goog.dom.TagName.SOURCE:
        977 case goog.dom.TagName.STYLE:
        978 case goog.dom.TagName.TRACK:
        979 case goog.dom.TagName.WBR:
        980 return false;
        981 }
        982 return true;
        983};
        984
        985
        986/**
        987 * Appends a child to a node.
        988 * @param {Node} parent Parent.
        989 * @param {Node} child Child.
        990 */
        991goog.dom.appendChild = function(parent, child) {
        992 parent.appendChild(child);
        993};
        994
        995
        996/**
        997 * Appends a node with text or other nodes.
        998 * @param {!Node} parent The node to append nodes to.
        999 * @param {...goog.dom.Appendable} var_args The things to append to the node.
        1000 * If this is a Node it is appended as is.
        1001 * If this is a string then a text node is appended.
        1002 * If this is an array like object then fields 0 to length - 1 are appended.
        1003 */
        1004goog.dom.append = function(parent, var_args) {
        1005 goog.dom.append_(goog.dom.getOwnerDocument(parent), parent, arguments, 1);
        1006};
        1007
        1008
        1009/**
        1010 * Removes all the child nodes on a DOM node.
        1011 * @param {Node} node Node to remove children from.
        1012 */
        1013goog.dom.removeChildren = function(node) {
        1014 // Note: Iterations over live collections can be slow, this is the fastest
        1015 // we could find. The double parenthesis are used to prevent JsCompiler and
        1016 // strict warnings.
        1017 var child;
        1018 while ((child = node.firstChild)) {
        1019 node.removeChild(child);
        1020 }
        1021};
        1022
        1023
        1024/**
        1025 * Inserts a new node before an existing reference node (i.e. as the previous
        1026 * sibling). If the reference node has no parent, then does nothing.
        1027 * @param {Node} newNode Node to insert.
        1028 * @param {Node} refNode Reference node to insert before.
        1029 */
        1030goog.dom.insertSiblingBefore = function(newNode, refNode) {
        1031 if (refNode.parentNode) {
        1032 refNode.parentNode.insertBefore(newNode, refNode);
        1033 }
        1034};
        1035
        1036
        1037/**
        1038 * Inserts a new node after an existing reference node (i.e. as the next
        1039 * sibling). If the reference node has no parent, then does nothing.
        1040 * @param {Node} newNode Node to insert.
        1041 * @param {Node} refNode Reference node to insert after.
        1042 */
        1043goog.dom.insertSiblingAfter = function(newNode, refNode) {
        1044 if (refNode.parentNode) {
        1045 refNode.parentNode.insertBefore(newNode, refNode.nextSibling);
        1046 }
        1047};
        1048
        1049
        1050/**
        1051 * Insert a child at a given index. If index is larger than the number of child
        1052 * nodes that the parent currently has, the node is inserted as the last child
        1053 * node.
        1054 * @param {Element} parent The element into which to insert the child.
        1055 * @param {Node} child The element to insert.
        1056 * @param {number} index The index at which to insert the new child node. Must
        1057 * not be negative.
        1058 */
        1059goog.dom.insertChildAt = function(parent, child, index) {
        1060 // Note that if the second argument is null, insertBefore
        1061 // will append the child at the end of the list of children.
        1062 parent.insertBefore(child, parent.childNodes[index] || null);
        1063};
        1064
        1065
        1066/**
        1067 * Removes a node from its parent.
        1068 * @param {Node} node The node to remove.
        1069 * @return {Node} The node removed if removed; else, null.
        1070 */
        1071goog.dom.removeNode = function(node) {
        1072 return node && node.parentNode ? node.parentNode.removeChild(node) : null;
        1073};
        1074
        1075
        1076/**
        1077 * Replaces a node in the DOM tree. Will do nothing if {@code oldNode} has no
        1078 * parent.
        1079 * @param {Node} newNode Node to insert.
        1080 * @param {Node} oldNode Node to replace.
        1081 */
        1082goog.dom.replaceNode = function(newNode, oldNode) {
        1083 var parent = oldNode.parentNode;
        1084 if (parent) {
        1085 parent.replaceChild(newNode, oldNode);
        1086 }
        1087};
        1088
        1089
        1090/**
        1091 * Flattens an element. That is, removes it and replace it with its children.
        1092 * Does nothing if the element is not in the document.
        1093 * @param {Element} element The element to flatten.
        1094 * @return {Element|undefined} The original element, detached from the document
        1095 * tree, sans children; or undefined, if the element was not in the document
        1096 * to begin with.
        1097 */
        1098goog.dom.flattenElement = function(element) {
        1099 var child, parent = element.parentNode;
        1100 if (parent && parent.nodeType != goog.dom.NodeType.DOCUMENT_FRAGMENT) {
        1101 // Use IE DOM method (supported by Opera too) if available
        1102 if (element.removeNode) {
        1103 return /** @type {Element} */ (element.removeNode(false));
        1104 } else {
        1105 // Move all children of the original node up one level.
        1106 while ((child = element.firstChild)) {
        1107 parent.insertBefore(child, element);
        1108 }
        1109
        1110 // Detach the original element.
        1111 return /** @type {Element} */ (goog.dom.removeNode(element));
        1112 }
        1113 }
        1114};
        1115
        1116
        1117/**
        1118 * Returns an array containing just the element children of the given element.
        1119 * @param {Element} element The element whose element children we want.
        1120 * @return {!(Array|NodeList)} An array or array-like list of just the element
        1121 * children of the given element.
        1122 */
        1123goog.dom.getChildren = function(element) {
        1124 // We check if the children attribute is supported for child elements
        1125 // since IE8 misuses the attribute by also including comments.
        1126 if (goog.dom.BrowserFeature.CAN_USE_CHILDREN_ATTRIBUTE &&
        1127 element.children != undefined) {
        1128 return element.children;
        1129 }
        1130 // Fall back to manually filtering the element's child nodes.
        1131 return goog.array.filter(element.childNodes, function(node) {
        1132 return node.nodeType == goog.dom.NodeType.ELEMENT;
        1133 });
        1134};
        1135
        1136
        1137/**
        1138 * Returns the first child node that is an element.
        1139 * @param {Node} node The node to get the first child element of.
        1140 * @return {Element} The first child node of {@code node} that is an element.
        1141 */
        1142goog.dom.getFirstElementChild = function(node) {
        1143 if (node.firstElementChild != undefined) {
        1144 return /** @type {Element} */(node).firstElementChild;
        1145 }
        1146 return goog.dom.getNextElementNode_(node.firstChild, true);
        1147};
        1148
        1149
        1150/**
        1151 * Returns the last child node that is an element.
        1152 * @param {Node} node The node to get the last child element of.
        1153 * @return {Element} The last child node of {@code node} that is an element.
        1154 */
        1155goog.dom.getLastElementChild = function(node) {
        1156 if (node.lastElementChild != undefined) {
        1157 return /** @type {Element} */(node).lastElementChild;
        1158 }
        1159 return goog.dom.getNextElementNode_(node.lastChild, false);
        1160};
        1161
        1162
        1163/**
        1164 * Returns the first next sibling that is an element.
        1165 * @param {Node} node The node to get the next sibling element of.
        1166 * @return {Element} The next sibling of {@code node} that is an element.
        1167 */
        1168goog.dom.getNextElementSibling = function(node) {
        1169 if (node.nextElementSibling != undefined) {
        1170 return /** @type {Element} */(node).nextElementSibling;
        1171 }
        1172 return goog.dom.getNextElementNode_(node.nextSibling, true);
        1173};
        1174
        1175
        1176/**
        1177 * Returns the first previous sibling that is an element.
        1178 * @param {Node} node The node to get the previous sibling element of.
        1179 * @return {Element} The first previous sibling of {@code node} that is
        1180 * an element.
        1181 */
        1182goog.dom.getPreviousElementSibling = function(node) {
        1183 if (node.previousElementSibling != undefined) {
        1184 return /** @type {Element} */(node).previousElementSibling;
        1185 }
        1186 return goog.dom.getNextElementNode_(node.previousSibling, false);
        1187};
        1188
        1189
        1190/**
        1191 * Returns the first node that is an element in the specified direction,
        1192 * starting with {@code node}.
        1193 * @param {Node} node The node to get the next element from.
        1194 * @param {boolean} forward Whether to look forwards or backwards.
        1195 * @return {Element} The first element.
        1196 * @private
        1197 */
        1198goog.dom.getNextElementNode_ = function(node, forward) {
        1199 while (node && node.nodeType != goog.dom.NodeType.ELEMENT) {
        1200 node = forward ? node.nextSibling : node.previousSibling;
        1201 }
        1202
        1203 return /** @type {Element} */ (node);
        1204};
        1205
        1206
        1207/**
        1208 * Returns the next node in source order from the given node.
        1209 * @param {Node} node The node.
        1210 * @return {Node} The next node in the DOM tree, or null if this was the last
        1211 * node.
        1212 */
        1213goog.dom.getNextNode = function(node) {
        1214 if (!node) {
        1215 return null;
        1216 }
        1217
        1218 if (node.firstChild) {
        1219 return node.firstChild;
        1220 }
        1221
        1222 while (node && !node.nextSibling) {
        1223 node = node.parentNode;
        1224 }
        1225
        1226 return node ? node.nextSibling : null;
        1227};
        1228
        1229
        1230/**
        1231 * Returns the previous node in source order from the given node.
        1232 * @param {Node} node The node.
        1233 * @return {Node} The previous node in the DOM tree, or null if this was the
        1234 * first node.
        1235 */
        1236goog.dom.getPreviousNode = function(node) {
        1237 if (!node) {
        1238 return null;
        1239 }
        1240
        1241 if (!node.previousSibling) {
        1242 return node.parentNode;
        1243 }
        1244
        1245 node = node.previousSibling;
        1246 while (node && node.lastChild) {
        1247 node = node.lastChild;
        1248 }
        1249
        1250 return node;
        1251};
        1252
        1253
        1254/**
        1255 * Whether the object looks like a DOM node.
        1256 * @param {?} obj The object being tested for node likeness.
        1257 * @return {boolean} Whether the object looks like a DOM node.
        1258 */
        1259goog.dom.isNodeLike = function(obj) {
        1260 return goog.isObject(obj) && obj.nodeType > 0;
        1261};
        1262
        1263
        1264/**
        1265 * Whether the object looks like an Element.
        1266 * @param {?} obj The object being tested for Element likeness.
        1267 * @return {boolean} Whether the object looks like an Element.
        1268 */
        1269goog.dom.isElement = function(obj) {
        1270 return goog.isObject(obj) && obj.nodeType == goog.dom.NodeType.ELEMENT;
        1271};
        1272
        1273
        1274/**
        1275 * Returns true if the specified value is a Window object. This includes the
        1276 * global window for HTML pages, and iframe windows.
        1277 * @param {?} obj Variable to test.
        1278 * @return {boolean} Whether the variable is a window.
        1279 */
        1280goog.dom.isWindow = function(obj) {
        1281 return goog.isObject(obj) && obj['window'] == obj;
        1282};
        1283
        1284
        1285/**
        1286 * Returns an element's parent, if it's an Element.
        1287 * @param {Element} element The DOM element.
        1288 * @return {Element} The parent, or null if not an Element.
        1289 */
        1290goog.dom.getParentElement = function(element) {
        1291 var parent;
        1292 if (goog.dom.BrowserFeature.CAN_USE_PARENT_ELEMENT_PROPERTY) {
        1293 var isIe9 = goog.userAgent.IE &&
        1294 goog.userAgent.isVersionOrHigher('9') &&
        1295 !goog.userAgent.isVersionOrHigher('10');
        1296 // SVG elements in IE9 can't use the parentElement property.
        1297 // goog.global['SVGElement'] is not defined in IE9 quirks mode.
        1298 if (!(isIe9 && goog.global['SVGElement'] &&
        1299 element instanceof goog.global['SVGElement'])) {
        1300 parent = element.parentElement;
        1301 if (parent) {
        1302 return parent;
        1303 }
        1304 }
        1305 }
        1306 parent = element.parentNode;
        1307 return goog.dom.isElement(parent) ? /** @type {!Element} */ (parent) : null;
        1308};
        1309
        1310
        1311/**
        1312 * Whether a node contains another node.
        1313 * @param {Node} parent The node that should contain the other node.
        1314 * @param {Node} descendant The node to test presence of.
        1315 * @return {boolean} Whether the parent node contains the descendent node.
        1316 */
        1317goog.dom.contains = function(parent, descendant) {
        1318 // We use browser specific methods for this if available since it is faster
        1319 // that way.
        1320
        1321 // IE DOM
        1322 if (parent.contains && descendant.nodeType == goog.dom.NodeType.ELEMENT) {
        1323 return parent == descendant || parent.contains(descendant);
        1324 }
        1325
        1326 // W3C DOM Level 3
        1327 if (typeof parent.compareDocumentPosition != 'undefined') {
        1328 return parent == descendant ||
        1329 Boolean(parent.compareDocumentPosition(descendant) & 16);
        1330 }
        1331
        1332 // W3C DOM Level 1
        1333 while (descendant && parent != descendant) {
        1334 descendant = descendant.parentNode;
        1335 }
        1336 return descendant == parent;
        1337};
        1338
        1339
        1340/**
        1341 * Compares the document order of two nodes, returning 0 if they are the same
        1342 * node, a negative number if node1 is before node2, and a positive number if
        1343 * node2 is before node1. Note that we compare the order the tags appear in the
        1344 * document so in the tree <b><i>text</i></b> the B node is considered to be
        1345 * before the I node.
        1346 *
        1347 * @param {Node} node1 The first node to compare.
        1348 * @param {Node} node2 The second node to compare.
        1349 * @return {number} 0 if the nodes are the same node, a negative number if node1
        1350 * is before node2, and a positive number if node2 is before node1.
        1351 */
        1352goog.dom.compareNodeOrder = function(node1, node2) {
        1353 // Fall out quickly for equality.
        1354 if (node1 == node2) {
        1355 return 0;
        1356 }
        1357
        1358 // Use compareDocumentPosition where available
        1359 if (node1.compareDocumentPosition) {
        1360 // 4 is the bitmask for FOLLOWS.
        1361 return node1.compareDocumentPosition(node2) & 2 ? 1 : -1;
        1362 }
        1363
        1364 // Special case for document nodes on IE 7 and 8.
        1365 if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) {
        1366 if (node1.nodeType == goog.dom.NodeType.DOCUMENT) {
        1367 return -1;
        1368 }
        1369 if (node2.nodeType == goog.dom.NodeType.DOCUMENT) {
        1370 return 1;
        1371 }
        1372 }
        1373
        1374 // Process in IE using sourceIndex - we check to see if the first node has
        1375 // a source index or if its parent has one.
        1376 if ('sourceIndex' in node1 ||
        1377 (node1.parentNode && 'sourceIndex' in node1.parentNode)) {
        1378 var isElement1 = node1.nodeType == goog.dom.NodeType.ELEMENT;
        1379 var isElement2 = node2.nodeType == goog.dom.NodeType.ELEMENT;
        1380
        1381 if (isElement1 && isElement2) {
        1382 return node1.sourceIndex - node2.sourceIndex;
        1383 } else {
        1384 var parent1 = node1.parentNode;
        1385 var parent2 = node2.parentNode;
        1386
        1387 if (parent1 == parent2) {
        1388 return goog.dom.compareSiblingOrder_(node1, node2);
        1389 }
        1390
        1391 if (!isElement1 && goog.dom.contains(parent1, node2)) {
        1392 return -1 * goog.dom.compareParentsDescendantNodeIe_(node1, node2);
        1393 }
        1394
        1395
        1396 if (!isElement2 && goog.dom.contains(parent2, node1)) {
        1397 return goog.dom.compareParentsDescendantNodeIe_(node2, node1);
        1398 }
        1399
        1400 return (isElement1 ? node1.sourceIndex : parent1.sourceIndex) -
        1401 (isElement2 ? node2.sourceIndex : parent2.sourceIndex);
        1402 }
        1403 }
        1404
        1405 // For Safari, we compare ranges.
        1406 var doc = goog.dom.getOwnerDocument(node1);
        1407
        1408 var range1, range2;
        1409 range1 = doc.createRange();
        1410 range1.selectNode(node1);
        1411 range1.collapse(true);
        1412
        1413 range2 = doc.createRange();
        1414 range2.selectNode(node2);
        1415 range2.collapse(true);
        1416
        1417 return range1.compareBoundaryPoints(goog.global['Range'].START_TO_END,
        1418 range2);
        1419};
        1420
        1421
        1422/**
        1423 * Utility function to compare the position of two nodes, when
        1424 * {@code textNode}'s parent is an ancestor of {@code node}. If this entry
        1425 * condition is not met, this function will attempt to reference a null object.
        1426 * @param {Node} textNode The textNode to compare.
        1427 * @param {Node} node The node to compare.
        1428 * @return {number} -1 if node is before textNode, +1 otherwise.
        1429 * @private
        1430 */
        1431goog.dom.compareParentsDescendantNodeIe_ = function(textNode, node) {
        1432 var parent = textNode.parentNode;
        1433 if (parent == node) {
        1434 // If textNode is a child of node, then node comes first.
        1435 return -1;
        1436 }
        1437 var sibling = node;
        1438 while (sibling.parentNode != parent) {
        1439 sibling = sibling.parentNode;
        1440 }
        1441 return goog.dom.compareSiblingOrder_(sibling, textNode);
        1442};
        1443
        1444
        1445/**
        1446 * Utility function to compare the position of two nodes known to be non-equal
        1447 * siblings.
        1448 * @param {Node} node1 The first node to compare.
        1449 * @param {Node} node2 The second node to compare.
        1450 * @return {number} -1 if node1 is before node2, +1 otherwise.
        1451 * @private
        1452 */
        1453goog.dom.compareSiblingOrder_ = function(node1, node2) {
        1454 var s = node2;
        1455 while ((s = s.previousSibling)) {
        1456 if (s == node1) {
        1457 // We just found node1 before node2.
        1458 return -1;
        1459 }
        1460 }
        1461
        1462 // Since we didn't find it, node1 must be after node2.
        1463 return 1;
        1464};
        1465
        1466
        1467/**
        1468 * Find the deepest common ancestor of the given nodes.
        1469 * @param {...Node} var_args The nodes to find a common ancestor of.
        1470 * @return {Node} The common ancestor of the nodes, or null if there is none.
        1471 * null will only be returned if two or more of the nodes are from different
        1472 * documents.
        1473 */
        1474goog.dom.findCommonAncestor = function(var_args) {
        1475 var i, count = arguments.length;
        1476 if (!count) {
        1477 return null;
        1478 } else if (count == 1) {
        1479 return arguments[0];
        1480 }
        1481
        1482 var paths = [];
        1483 var minLength = Infinity;
        1484 for (i = 0; i < count; i++) {
        1485 // Compute the list of ancestors.
        1486 var ancestors = [];
        1487 var node = arguments[i];
        1488 while (node) {
        1489 ancestors.unshift(node);
        1490 node = node.parentNode;
        1491 }
        1492
        1493 // Save the list for comparison.
        1494 paths.push(ancestors);
        1495 minLength = Math.min(minLength, ancestors.length);
        1496 }
        1497 var output = null;
        1498 for (i = 0; i < minLength; i++) {
        1499 var first = paths[0][i];
        1500 for (var j = 1; j < count; j++) {
        1501 if (first != paths[j][i]) {
        1502 return output;
        1503 }
        1504 }
        1505 output = first;
        1506 }
        1507 return output;
        1508};
        1509
        1510
        1511/**
        1512 * Returns the owner document for a node.
        1513 * @param {Node|Window} node The node to get the document for.
        1514 * @return {!Document} The document owning the node.
        1515 */
        1516goog.dom.getOwnerDocument = function(node) {
        1517 // TODO(nnaze): Update param signature to be non-nullable.
        1518 goog.asserts.assert(node, 'Node cannot be null or undefined.');
        1519 return /** @type {!Document} */ (
        1520 node.nodeType == goog.dom.NodeType.DOCUMENT ? node :
        1521 node.ownerDocument || node.document);
        1522};
        1523
        1524
        1525/**
        1526 * Cross-browser function for getting the document element of a frame or iframe.
        1527 * @param {Element} frame Frame element.
        1528 * @return {!Document} The frame content document.
        1529 */
        1530goog.dom.getFrameContentDocument = function(frame) {
        1531 var doc = frame.contentDocument || frame.contentWindow.document;
        1532 return doc;
        1533};
        1534
        1535
        1536/**
        1537 * Cross-browser function for getting the window of a frame or iframe.
        1538 * @param {Element} frame Frame element.
        1539 * @return {Window} The window associated with the given frame.
        1540 */
        1541goog.dom.getFrameContentWindow = function(frame) {
        1542 return frame.contentWindow ||
        1543 goog.dom.getWindow(goog.dom.getFrameContentDocument(frame));
        1544};
        1545
        1546
        1547/**
        1548 * Sets the text content of a node, with cross-browser support.
        1549 * @param {Node} node The node to change the text content of.
        1550 * @param {string|number} text The value that should replace the node's content.
        1551 */
        1552goog.dom.setTextContent = function(node, text) {
        1553 goog.asserts.assert(node != null,
        1554 'goog.dom.setTextContent expects a non-null value for node');
        1555
        1556 if ('textContent' in node) {
        1557 node.textContent = text;
        1558 } else if (node.nodeType == goog.dom.NodeType.TEXT) {
        1559 node.data = text;
        1560 } else if (node.firstChild &&
        1561 node.firstChild.nodeType == goog.dom.NodeType.TEXT) {
        1562 // If the first child is a text node we just change its data and remove the
        1563 // rest of the children.
        1564 while (node.lastChild != node.firstChild) {
        1565 node.removeChild(node.lastChild);
        1566 }
        1567 node.firstChild.data = text;
        1568 } else {
        1569 goog.dom.removeChildren(node);
        1570 var doc = goog.dom.getOwnerDocument(node);
        1571 node.appendChild(doc.createTextNode(String(text)));
        1572 }
        1573};
        1574
        1575
        1576/**
        1577 * Gets the outerHTML of a node, which islike innerHTML, except that it
        1578 * actually contains the HTML of the node itself.
        1579 * @param {Element} element The element to get the HTML of.
        1580 * @return {string} The outerHTML of the given element.
        1581 */
        1582goog.dom.getOuterHtml = function(element) {
        1583 // IE, Opera and WebKit all have outerHTML.
        1584 if ('outerHTML' in element) {
        1585 return element.outerHTML;
        1586 } else {
        1587 var doc = goog.dom.getOwnerDocument(element);
        1588 var div = doc.createElement('div');
        1589 div.appendChild(element.cloneNode(true));
        1590 return div.innerHTML;
        1591 }
        1592};
        1593
        1594
        1595/**
        1596 * Finds the first descendant node that matches the filter function, using
        1597 * a depth first search. This function offers the most general purpose way
        1598 * of finding a matching element. You may also wish to consider
        1599 * {@code goog.dom.query} which can express many matching criteria using
        1600 * CSS selector expressions. These expressions often result in a more
        1601 * compact representation of the desired result.
        1602 * @see goog.dom.query
        1603 *
        1604 * @param {Node} root The root of the tree to search.
        1605 * @param {function(Node) : boolean} p The filter function.
        1606 * @return {Node|undefined} The found node or undefined if none is found.
        1607 */
        1608goog.dom.findNode = function(root, p) {
        1609 var rv = [];
        1610 var found = goog.dom.findNodes_(root, p, rv, true);
        1611 return found ? rv[0] : undefined;
        1612};
        1613
        1614
        1615/**
        1616 * Finds all the descendant nodes that match the filter function, using a
        1617 * a depth first search. This function offers the most general-purpose way
        1618 * of finding a set of matching elements. You may also wish to consider
        1619 * {@code goog.dom.query} which can express many matching criteria using
        1620 * CSS selector expressions. These expressions often result in a more
        1621 * compact representation of the desired result.
        1622
        1623 * @param {Node} root The root of the tree to search.
        1624 * @param {function(Node) : boolean} p The filter function.
        1625 * @return {!Array.<!Node>} The found nodes or an empty array if none are found.
        1626 */
        1627goog.dom.findNodes = function(root, p) {
        1628 var rv = [];
        1629 goog.dom.findNodes_(root, p, rv, false);
        1630 return rv;
        1631};
        1632
        1633
        1634/**
        1635 * Finds the first or all the descendant nodes that match the filter function,
        1636 * using a depth first search.
        1637 * @param {Node} root The root of the tree to search.
        1638 * @param {function(Node) : boolean} p The filter function.
        1639 * @param {!Array.<!Node>} rv The found nodes are added to this array.
        1640 * @param {boolean} findOne If true we exit after the first found node.
        1641 * @return {boolean} Whether the search is complete or not. True in case findOne
        1642 * is true and the node is found. False otherwise.
        1643 * @private
        1644 */
        1645goog.dom.findNodes_ = function(root, p, rv, findOne) {
        1646 if (root != null) {
        1647 var child = root.firstChild;
        1648 while (child) {
        1649 if (p(child)) {
        1650 rv.push(child);
        1651 if (findOne) {
        1652 return true;
        1653 }
        1654 }
        1655 if (goog.dom.findNodes_(child, p, rv, findOne)) {
        1656 return true;
        1657 }
        1658 child = child.nextSibling;
        1659 }
        1660 }
        1661 return false;
        1662};
        1663
        1664
        1665/**
        1666 * Map of tags whose content to ignore when calculating text length.
        1667 * @type {Object}
        1668 * @private
        1669 */
        1670goog.dom.TAGS_TO_IGNORE_ = {
        1671 'SCRIPT': 1,
        1672 'STYLE': 1,
        1673 'HEAD': 1,
        1674 'IFRAME': 1,
        1675 'OBJECT': 1
        1676};
        1677
        1678
        1679/**
        1680 * Map of tags which have predefined values with regard to whitespace.
        1681 * @type {Object}
        1682 * @private
        1683 */
        1684goog.dom.PREDEFINED_TAG_VALUES_ = {'IMG': ' ', 'BR': '\n'};
        1685
        1686
        1687/**
        1688 * Returns true if the element has a tab index that allows it to receive
        1689 * keyboard focus (tabIndex >= 0), false otherwise. Note that some elements
        1690 * natively support keyboard focus, even if they have no tab index.
        1691 * @param {Element} element Element to check.
        1692 * @return {boolean} Whether the element has a tab index that allows keyboard
        1693 * focus.
        1694 * @see http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
        1695 */
        1696goog.dom.isFocusableTabIndex = function(element) {
        1697 return goog.dom.hasSpecifiedTabIndex_(element) &&
        1698 goog.dom.isTabIndexFocusable_(element);
        1699};
        1700
        1701
        1702/**
        1703 * Enables or disables keyboard focus support on the element via its tab index.
        1704 * Only elements for which {@link goog.dom.isFocusableTabIndex} returns true
        1705 * (or elements that natively support keyboard focus, like form elements) can
        1706 * receive keyboard focus. See http://go/tabindex for more info.
        1707 * @param {Element} element Element whose tab index is to be changed.
        1708 * @param {boolean} enable Whether to set or remove a tab index on the element
        1709 * that supports keyboard focus.
        1710 */
        1711goog.dom.setFocusableTabIndex = function(element, enable) {
        1712 if (enable) {
        1713 element.tabIndex = 0;
        1714 } else {
        1715 // Set tabIndex to -1 first, then remove it. This is a workaround for
        1716 // Safari (confirmed in version 4 on Windows). When removing the attribute
        1717 // without setting it to -1 first, the element remains keyboard focusable
        1718 // despite not having a tabIndex attribute anymore.
        1719 element.tabIndex = -1;
        1720 element.removeAttribute('tabIndex'); // Must be camelCase!
        1721 }
        1722};
        1723
        1724
        1725/**
        1726 * Returns true if the element can be focused, i.e. it has a tab index that
        1727 * allows it to receive keyboard focus (tabIndex >= 0), or it is an element
        1728 * that natively supports keyboard focus.
        1729 * @param {Element} element Element to check.
        1730 * @return {boolean} Whether the element allows keyboard focus.
        1731 */
        1732goog.dom.isFocusable = function(element) {
        1733 var focusable;
        1734 // Some elements can have unspecified tab index and still receive focus.
        1735 if (goog.dom.nativelySupportsFocus_(element)) {
        1736 // Make sure the element is not disabled ...
        1737 focusable = !element.disabled &&
        1738 // ... and if a tab index is specified, it allows focus.
        1739 (!goog.dom.hasSpecifiedTabIndex_(element) ||
        1740 goog.dom.isTabIndexFocusable_(element));
        1741 } else {
        1742 focusable = goog.dom.isFocusableTabIndex(element);
        1743 }
        1744
        1745 // IE requires elements to be visible in order to focus them.
        1746 return focusable && goog.userAgent.IE ?
        1747 goog.dom.hasNonZeroBoundingRect_(element) : focusable;
        1748};
        1749
        1750
        1751/**
        1752 * Returns true if the element has a specified tab index.
        1753 * @param {Element} element Element to check.
        1754 * @return {boolean} Whether the element has a specified tab index.
        1755 * @private
        1756 */
        1757goog.dom.hasSpecifiedTabIndex_ = function(element) {
        1758 // IE returns 0 for an unset tabIndex, so we must use getAttributeNode(),
        1759 // which returns an object with a 'specified' property if tabIndex is
        1760 // specified. This works on other browsers, too.
        1761 var attrNode = element.getAttributeNode('tabindex'); // Must be lowercase!
        1762 return goog.isDefAndNotNull(attrNode) && attrNode.specified;
        1763};
        1764
        1765
        1766/**
        1767 * Returns true if the element's tab index allows the element to be focused.
        1768 * @param {Element} element Element to check.
        1769 * @return {boolean} Whether the element's tab index allows focus.
        1770 * @private
        1771 */
        1772goog.dom.isTabIndexFocusable_ = function(element) {
        1773 var index = element.tabIndex;
        1774 // NOTE: IE9 puts tabIndex in 16-bit int, e.g. -2 is 65534.
        1775 return goog.isNumber(index) && index >= 0 && index < 32768;
        1776};
        1777
        1778
        1779/**
        1780 * Returns true if the element is focusable even when tabIndex is not set.
        1781 * @param {Element} element Element to check.
        1782 * @return {boolean} Whether the element natively supports focus.
        1783 * @private
        1784 */
        1785goog.dom.nativelySupportsFocus_ = function(element) {
        1786 return element.tagName == goog.dom.TagName.A ||
        1787 element.tagName == goog.dom.TagName.INPUT ||
        1788 element.tagName == goog.dom.TagName.TEXTAREA ||
        1789 element.tagName == goog.dom.TagName.SELECT ||
        1790 element.tagName == goog.dom.TagName.BUTTON;
        1791};
        1792
        1793
        1794/**
        1795 * Returns true if the element has a bounding rectangle that would be visible
        1796 * (i.e. its width and height are greater than zero).
        1797 * @param {Element} element Element to check.
        1798 * @return {boolean} Whether the element has a non-zero bounding rectangle.
        1799 * @private
        1800 */
        1801goog.dom.hasNonZeroBoundingRect_ = function(element) {
        1802 var rect = goog.isFunction(element['getBoundingClientRect']) ?
        1803 element.getBoundingClientRect() :
        1804 {'height': element.offsetHeight, 'width': element.offsetWidth};
        1805 return goog.isDefAndNotNull(rect) && rect.height > 0 && rect.width > 0;
        1806};
        1807
        1808
        1809/**
        1810 * Returns the text content of the current node, without markup and invisible
        1811 * symbols. New lines are stripped and whitespace is collapsed,
        1812 * such that each character would be visible.
        1813 *
        1814 * In browsers that support it, innerText is used. Other browsers attempt to
        1815 * simulate it via node traversal. Line breaks are canonicalized in IE.
        1816 *
        1817 * @param {Node} node The node from which we are getting content.
        1818 * @return {string} The text content.
        1819 */
        1820goog.dom.getTextContent = function(node) {
        1821 var textContent;
        1822 // Note(arv): IE9, Opera, and Safari 3 support innerText but they include
        1823 // text nodes in script tags. So we revert to use a user agent test here.
        1824 if (goog.dom.BrowserFeature.CAN_USE_INNER_TEXT && ('innerText' in node)) {
        1825 textContent = goog.string.canonicalizeNewlines(node.innerText);
        1826 // Unfortunately .innerText() returns text with &shy; symbols
        1827 // We need to filter it out and then remove duplicate whitespaces
        1828 } else {
        1829 var buf = [];
        1830 goog.dom.getTextContent_(node, buf, true);
        1831 textContent = buf.join('');
        1832 }
        1833
        1834 // Strip &shy; entities. goog.format.insertWordBreaks inserts them in Opera.
        1835 textContent = textContent.replace(/ \xAD /g, ' ').replace(/\xAD/g, '');
        1836 // Strip &#8203; entities. goog.format.insertWordBreaks inserts them in IE8.
        1837 textContent = textContent.replace(/\u200B/g, '');
        1838
        1839 // Skip this replacement on old browsers with working innerText, which
        1840 // automatically turns &nbsp; into ' ' and / +/ into ' ' when reading
        1841 // innerText.
        1842 if (!goog.dom.BrowserFeature.CAN_USE_INNER_TEXT) {
        1843 textContent = textContent.replace(/ +/g, ' ');
        1844 }
        1845 if (textContent != ' ') {
        1846 textContent = textContent.replace(/^\s*/, '');
        1847 }
        1848
        1849 return textContent;
        1850};
        1851
        1852
        1853/**
        1854 * Returns the text content of the current node, without markup.
        1855 *
        1856 * Unlike {@code getTextContent} this method does not collapse whitespaces
        1857 * or normalize lines breaks.
        1858 *
        1859 * @param {Node} node The node from which we are getting content.
        1860 * @return {string} The raw text content.
        1861 */
        1862goog.dom.getRawTextContent = function(node) {
        1863 var buf = [];
        1864 goog.dom.getTextContent_(node, buf, false);
        1865
        1866 return buf.join('');
        1867};
        1868
        1869
        1870/**
        1871 * Recursive support function for text content retrieval.
        1872 *
        1873 * @param {Node} node The node from which we are getting content.
        1874 * @param {Array} buf string buffer.
        1875 * @param {boolean} normalizeWhitespace Whether to normalize whitespace.
        1876 * @private
        1877 */
        1878goog.dom.getTextContent_ = function(node, buf, normalizeWhitespace) {
        1879 if (node.nodeName in goog.dom.TAGS_TO_IGNORE_) {
        1880 // ignore certain tags
        1881 } else if (node.nodeType == goog.dom.NodeType.TEXT) {
        1882 if (normalizeWhitespace) {
        1883 buf.push(String(node.nodeValue).replace(/(\r\n|\r|\n)/g, ''));
        1884 } else {
        1885 buf.push(node.nodeValue);
        1886 }
        1887 } else if (node.nodeName in goog.dom.PREDEFINED_TAG_VALUES_) {
        1888 buf.push(goog.dom.PREDEFINED_TAG_VALUES_[node.nodeName]);
        1889 } else {
        1890 var child = node.firstChild;
        1891 while (child) {
        1892 goog.dom.getTextContent_(child, buf, normalizeWhitespace);
        1893 child = child.nextSibling;
        1894 }
        1895 }
        1896};
        1897
        1898
        1899/**
        1900 * Returns the text length of the text contained in a node, without markup. This
        1901 * is equivalent to the selection length if the node was selected, or the number
        1902 * of cursor movements to traverse the node. Images & BRs take one space. New
        1903 * lines are ignored.
        1904 *
        1905 * @param {Node} node The node whose text content length is being calculated.
        1906 * @return {number} The length of {@code node}'s text content.
        1907 */
        1908goog.dom.getNodeTextLength = function(node) {
        1909 return goog.dom.getTextContent(node).length;
        1910};
        1911
        1912
        1913/**
        1914 * Returns the text offset of a node relative to one of its ancestors. The text
        1915 * length is the same as the length calculated by goog.dom.getNodeTextLength.
        1916 *
        1917 * @param {Node} node The node whose offset is being calculated.
        1918 * @param {Node=} opt_offsetParent The node relative to which the offset will
        1919 * be calculated. Defaults to the node's owner document's body.
        1920 * @return {number} The text offset.
        1921 */
        1922goog.dom.getNodeTextOffset = function(node, opt_offsetParent) {
        1923 var root = opt_offsetParent || goog.dom.getOwnerDocument(node).body;
        1924 var buf = [];
        1925 while (node && node != root) {
        1926 var cur = node;
        1927 while ((cur = cur.previousSibling)) {
        1928 buf.unshift(goog.dom.getTextContent(cur));
        1929 }
        1930 node = node.parentNode;
        1931 }
        1932 // Trim left to deal with FF cases when there might be line breaks and empty
        1933 // nodes at the front of the text
        1934 return goog.string.trimLeft(buf.join('')).replace(/ +/g, ' ').length;
        1935};
        1936
        1937
        1938/**
        1939 * Returns the node at a given offset in a parent node. If an object is
        1940 * provided for the optional third parameter, the node and the remainder of the
        1941 * offset will stored as properties of this object.
        1942 * @param {Node} parent The parent node.
        1943 * @param {number} offset The offset into the parent node.
        1944 * @param {Object=} opt_result Object to be used to store the return value. The
        1945 * return value will be stored in the form {node: Node, remainder: number}
        1946 * if this object is provided.
        1947 * @return {Node} The node at the given offset.
        1948 */
        1949goog.dom.getNodeAtOffset = function(parent, offset, opt_result) {
        1950 var stack = [parent], pos = 0, cur = null;
        1951 while (stack.length > 0 && pos < offset) {
        1952 cur = stack.pop();
        1953 if (cur.nodeName in goog.dom.TAGS_TO_IGNORE_) {
        1954 // ignore certain tags
        1955 } else if (cur.nodeType == goog.dom.NodeType.TEXT) {
        1956 var text = cur.nodeValue.replace(/(\r\n|\r|\n)/g, '').replace(/ +/g, ' ');
        1957 pos += text.length;
        1958 } else if (cur.nodeName in goog.dom.PREDEFINED_TAG_VALUES_) {
        1959 pos += goog.dom.PREDEFINED_TAG_VALUES_[cur.nodeName].length;
        1960 } else {
        1961 for (var i = cur.childNodes.length - 1; i >= 0; i--) {
        1962 stack.push(cur.childNodes[i]);
        1963 }
        1964 }
        1965 }
        1966 if (goog.isObject(opt_result)) {
        1967 opt_result.remainder = cur ? cur.nodeValue.length + offset - pos - 1 : 0;
        1968 opt_result.node = cur;
        1969 }
        1970
        1971 return cur;
        1972};
        1973
        1974
        1975/**
        1976 * Returns true if the object is a {@code NodeList}. To qualify as a NodeList,
        1977 * the object must have a numeric length property and an item function (which
        1978 * has type 'string' on IE for some reason).
        1979 * @param {Object} val Object to test.
        1980 * @return {boolean} Whether the object is a NodeList.
        1981 */
        1982goog.dom.isNodeList = function(val) {
        1983 // TODO(attila): Now the isNodeList is part of goog.dom we can use
        1984 // goog.userAgent to make this simpler.
        1985 // A NodeList must have a length property of type 'number' on all platforms.
        1986 if (val && typeof val.length == 'number') {
        1987 // A NodeList is an object everywhere except Safari, where it's a function.
        1988 if (goog.isObject(val)) {
        1989 // A NodeList must have an item function (on non-IE platforms) or an item
        1990 // property of type 'string' (on IE).
        1991 return typeof val.item == 'function' || typeof val.item == 'string';
        1992 } else if (goog.isFunction(val)) {
        1993 // On Safari, a NodeList is a function with an item property that is also
        1994 // a function.
        1995 return typeof val.item == 'function';
        1996 }
        1997 }
        1998
        1999 // Not a NodeList.
        2000 return false;
        2001};
        2002
        2003
        2004/**
        2005 * Walks up the DOM hierarchy returning the first ancestor that has the passed
        2006 * tag name and/or class name. If the passed element matches the specified
        2007 * criteria, the element itself is returned.
        2008 * @param {Node} element The DOM node to start with.
        2009 * @param {?(goog.dom.TagName|string)=} opt_tag The tag name to match (or
        2010 * null/undefined to match only based on class name).
        2011 * @param {?string=} opt_class The class name to match (or null/undefined to
        2012 * match only based on tag name).
        2013 * @return {Element} The first ancestor that matches the passed criteria, or
        2014 * null if no match is found.
        2015 */
        2016goog.dom.getAncestorByTagNameAndClass = function(element, opt_tag, opt_class) {
        2017 if (!opt_tag && !opt_class) {
        2018 return null;
        2019 }
        2020 var tagName = opt_tag ? opt_tag.toUpperCase() : null;
        2021 return /** @type {Element} */ (goog.dom.getAncestor(element,
        2022 function(node) {
        2023 return (!tagName || node.nodeName == tagName) &&
        2024 (!opt_class || goog.isString(node.className) &&
        2025 goog.array.contains(node.className.split(/\s+/), opt_class));
        2026 }, true));
        2027};
        2028
        2029
        2030/**
        2031 * Walks up the DOM hierarchy returning the first ancestor that has the passed
        2032 * class name. If the passed element matches the specified criteria, the
        2033 * element itself is returned.
        2034 * @param {Node} element The DOM node to start with.
        2035 * @param {string} className The class name to match.
        2036 * @return {Element} The first ancestor that matches the passed criteria, or
        2037 * null if none match.
        2038 */
        2039goog.dom.getAncestorByClass = function(element, className) {
        2040 return goog.dom.getAncestorByTagNameAndClass(element, null, className);
        2041};
        2042
        2043
        2044/**
        2045 * Walks up the DOM hierarchy returning the first ancestor that passes the
        2046 * matcher function.
        2047 * @param {Node} element The DOM node to start with.
        2048 * @param {function(Node) : boolean} matcher A function that returns true if the
        2049 * passed node matches the desired criteria.
        2050 * @param {boolean=} opt_includeNode If true, the node itself is included in
        2051 * the search (the first call to the matcher will pass startElement as
        2052 * the node to test).
        2053 * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the
        2054 * dom.
        2055 * @return {Node} DOM node that matched the matcher, or null if there was
        2056 * no match.
        2057 */
        2058goog.dom.getAncestor = function(
        2059 element, matcher, opt_includeNode, opt_maxSearchSteps) {
        2060 if (!opt_includeNode) {
        2061 element = element.parentNode;
        2062 }
        2063 var ignoreSearchSteps = opt_maxSearchSteps == null;
        2064 var steps = 0;
        2065 while (element && (ignoreSearchSteps || steps <= opt_maxSearchSteps)) {
        2066 if (matcher(element)) {
        2067 return element;
        2068 }
        2069 element = element.parentNode;
        2070 steps++;
        2071 }
        2072 // Reached the root of the DOM without a match
        2073 return null;
        2074};
        2075
        2076
        2077/**
        2078 * Determines the active element in the given document.
        2079 * @param {Document} doc The document to look in.
        2080 * @return {Element} The active element.
        2081 */
        2082goog.dom.getActiveElement = function(doc) {
        2083 try {
        2084 return doc && doc.activeElement;
        2085 } catch (e) {
        2086 // NOTE(nicksantos): Sometimes, evaluating document.activeElement in IE
        2087 // throws an exception. I'm not 100% sure why, but I suspect it chokes
        2088 // on document.activeElement if the activeElement has been recently
        2089 // removed from the DOM by a JS operation.
        2090 //
        2091 // We assume that an exception here simply means
        2092 // "there is no active element."
        2093 }
        2094
        2095 return null;
        2096};
        2097
        2098
        2099/**
        2100 * Gives the current devicePixelRatio.
        2101 *
        2102 * By default, this is the value of window.devicePixelRatio (which should be
        2103 * preferred if present).
        2104 *
        2105 * If window.devicePixelRatio is not present, the ratio is calculated with
        2106 * window.matchMedia, if present. Otherwise, gives 1.0.
        2107 *
        2108 * Some browsers (including Chrome) consider the browser zoom level in the pixel
        2109 * ratio, so the value may change across multiple calls.
        2110 *
        2111 * @return {number} The number of actual pixels per virtual pixel.
        2112 */
        2113goog.dom.getPixelRatio = function() {
        2114 var win = goog.dom.getWindow();
        2115
        2116 // devicePixelRatio does not work on Mobile firefox.
        2117 // TODO(user): Enable this check on a known working mobile Gecko version.
        2118 // Filed a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=896804
        2119 var isFirefoxMobile = goog.userAgent.GECKO && goog.userAgent.MOBILE;
        2120
        2121 if (goog.isDef(win.devicePixelRatio) && !isFirefoxMobile) {
        2122 return win.devicePixelRatio;
        2123 } else if (win.matchMedia) {
        2124 return goog.dom.matchesPixelRatio_(.75) ||
        2125 goog.dom.matchesPixelRatio_(1.5) ||
        2126 goog.dom.matchesPixelRatio_(2) ||
        2127 goog.dom.matchesPixelRatio_(3) || 1;
        2128 }
        2129 return 1;
        2130};
        2131
        2132
        2133/**
        2134 * Calculates a mediaQuery to check if the current device supports the
        2135 * given actual to virtual pixel ratio.
        2136 * @param {number} pixelRatio The ratio of actual pixels to virtual pixels.
        2137 * @return {number} pixelRatio if applicable, otherwise 0.
        2138 * @private
        2139 */
        2140goog.dom.matchesPixelRatio_ = function(pixelRatio) {
        2141 var win = goog.dom.getWindow();
        2142 var query = ('(-webkit-min-device-pixel-ratio: ' + pixelRatio + '),' +
        2143 '(min--moz-device-pixel-ratio: ' + pixelRatio + '),' +
        2144 '(min-resolution: ' + pixelRatio + 'dppx)');
        2145 return win.matchMedia(query).matches ? pixelRatio : 0;
        2146};
        2147
        2148
        2149
        2150/**
        2151 * Create an instance of a DOM helper with a new document object.
        2152 * @param {Document=} opt_document Document object to associate with this
        2153 * DOM helper.
        2154 * @constructor
        2155 */
        2156goog.dom.DomHelper = function(opt_document) {
        2157 /**
        2158 * Reference to the document object to use
        2159 * @type {!Document}
        2160 * @private
        2161 */
        2162 this.document_ = opt_document || goog.global.document || document;
        2163};
        2164
        2165
        2166/**
        2167 * Gets the dom helper object for the document where the element resides.
        2168 * @param {Node=} opt_node If present, gets the DomHelper for this node.
        2169 * @return {!goog.dom.DomHelper} The DomHelper.
        2170 */
        2171goog.dom.DomHelper.prototype.getDomHelper = goog.dom.getDomHelper;
        2172
        2173
        2174/**
        2175 * Sets the document object.
        2176 * @param {!Document} document Document object.
        2177 */
        2178goog.dom.DomHelper.prototype.setDocument = function(document) {
        2179 this.document_ = document;
        2180};
        2181
        2182
        2183/**
        2184 * Gets the document object being used by the dom library.
        2185 * @return {!Document} Document object.
        2186 */
        2187goog.dom.DomHelper.prototype.getDocument = function() {
        2188 return this.document_;
        2189};
        2190
        2191
        2192/**
        2193 * Alias for {@code getElementById}. If a DOM node is passed in then we just
        2194 * return that.
        2195 * @param {string|Element} element Element ID or a DOM node.
        2196 * @return {Element} The element with the given ID, or the node passed in.
        2197 */
        2198goog.dom.DomHelper.prototype.getElement = function(element) {
        2199 return goog.dom.getElementHelper_(this.document_, element);
        2200};
        2201
        2202
        2203/**
        2204 * Gets an element by id, asserting that the element is found.
        2205 *
        2206 * This is used when an element is expected to exist, and should fail with
        2207 * an assertion error if it does not (if assertions are enabled).
        2208 *
        2209 * @param {string} id Element ID.
        2210 * @return {!Element} The element with the given ID, if it exists.
        2211 */
        2212goog.dom.DomHelper.prototype.getRequiredElement = function(id) {
        2213 return goog.dom.getRequiredElementHelper_(this.document_, id);
        2214};
        2215
        2216
        2217/**
        2218 * Alias for {@code getElement}.
        2219 * @param {string|Element} element Element ID or a DOM node.
        2220 * @return {Element} The element with the given ID, or the node passed in.
        2221 * @deprecated Use {@link goog.dom.DomHelper.prototype.getElement} instead.
        2222 */
        2223goog.dom.DomHelper.prototype.$ = goog.dom.DomHelper.prototype.getElement;
        2224
        2225
        2226/**
        2227 * Looks up elements by both tag and class name, using browser native functions
        2228 * ({@code querySelectorAll}, {@code getElementsByTagName} or
        2229 * {@code getElementsByClassName}) where possible. The returned array is a live
        2230 * NodeList or a static list depending on the code path taken.
        2231 *
        2232 * @see goog.dom.query
        2233 *
        2234 * @param {?string=} opt_tag Element tag name or * for all tags.
        2235 * @param {?string=} opt_class Optional class name.
        2236 * @param {(Document|Element)=} opt_el Optional element to look in.
        2237 * @return { {length: number} } Array-like list of elements (only a length
        2238 * property and numerical indices are guaranteed to exist).
        2239 */
        2240goog.dom.DomHelper.prototype.getElementsByTagNameAndClass = function(opt_tag,
        2241 opt_class,
        2242 opt_el) {
        2243 return goog.dom.getElementsByTagNameAndClass_(this.document_, opt_tag,
        2244 opt_class, opt_el);
        2245};
        2246
        2247
        2248/**
        2249 * Returns an array of all the elements with the provided className.
        2250 * @see {goog.dom.query}
        2251 * @param {string} className the name of the class to look for.
        2252 * @param {Element|Document=} opt_el Optional element to look in.
        2253 * @return { {length: number} } The items found with the class name provided.
        2254 */
        2255goog.dom.DomHelper.prototype.getElementsByClass = function(className, opt_el) {
        2256 var doc = opt_el || this.document_;
        2257 return goog.dom.getElementsByClass(className, doc);
        2258};
        2259
        2260
        2261/**
        2262 * Returns the first element we find matching the provided class name.
        2263 * @see {goog.dom.query}
        2264 * @param {string} className the name of the class to look for.
        2265 * @param {(Element|Document)=} opt_el Optional element to look in.
        2266 * @return {Element} The first item found with the class name provided.
        2267 */
        2268goog.dom.DomHelper.prototype.getElementByClass = function(className, opt_el) {
        2269 var doc = opt_el || this.document_;
        2270 return goog.dom.getElementByClass(className, doc);
        2271};
        2272
        2273
        2274/**
        2275 * Ensures an element with the given className exists, and then returns the
        2276 * first element with the provided className.
        2277 * @see {goog.dom.query}
        2278 * @param {string} className the name of the class to look for.
        2279 * @param {(!Element|!Document)=} opt_root Optional element or document to look
        2280 * in.
        2281 * @return {!Element} The first item found with the class name provided.
        2282 * @throws {goog.asserts.AssertionError} Thrown if no element is found.
        2283 */
        2284goog.dom.DomHelper.prototype.getRequiredElementByClass = function(className,
        2285 opt_root) {
        2286 var root = opt_root || this.document_;
        2287 return goog.dom.getRequiredElementByClass(className, root);
        2288};
        2289
        2290
        2291/**
        2292 * Alias for {@code getElementsByTagNameAndClass}.
        2293 * @deprecated Use DomHelper getElementsByTagNameAndClass.
        2294 * @see goog.dom.query
        2295 *
        2296 * @param {?string=} opt_tag Element tag name.
        2297 * @param {?string=} opt_class Optional class name.
        2298 * @param {Element=} opt_el Optional element to look in.
        2299 * @return { {length: number} } Array-like list of elements (only a length
        2300 * property and numerical indices are guaranteed to exist).
        2301 */
        2302goog.dom.DomHelper.prototype.$$ =
        2303 goog.dom.DomHelper.prototype.getElementsByTagNameAndClass;
        2304
        2305
        2306/**
        2307 * Sets a number of properties on a node.
        2308 * @param {Element} element DOM node to set properties on.
        2309 * @param {Object} properties Hash of property:value pairs.
        2310 */
        2311goog.dom.DomHelper.prototype.setProperties = goog.dom.setProperties;
        2312
        2313
        2314/**
        2315 * Gets the dimensions of the viewport.
        2316 * @param {Window=} opt_window Optional window element to test. Defaults to
        2317 * the window of the Dom Helper.
        2318 * @return {!goog.math.Size} Object with values 'width' and 'height'.
        2319 */
        2320goog.dom.DomHelper.prototype.getViewportSize = function(opt_window) {
        2321 // TODO(arv): This should not take an argument. That breaks the rule of a
        2322 // a DomHelper representing a single frame/window/document.
        2323 return goog.dom.getViewportSize(opt_window || this.getWindow());
        2324};
        2325
        2326
        2327/**
        2328 * Calculates the height of the document.
        2329 *
        2330 * @return {number} The height of the document.
        2331 */
        2332goog.dom.DomHelper.prototype.getDocumentHeight = function() {
        2333 return goog.dom.getDocumentHeight_(this.getWindow());
        2334};
        2335
        2336
        2337/**
        2338 * Typedef for use with goog.dom.createDom and goog.dom.append.
        2339 * @typedef {Object|string|Array|NodeList}
        2340 */
        2341goog.dom.Appendable;
        2342
        2343
        2344/**
        2345 * Returns a dom node with a set of attributes. This function accepts varargs
        2346 * for subsequent nodes to be added. Subsequent nodes will be added to the
        2347 * first node as childNodes.
        2348 *
        2349 * So:
        2350 * <code>createDom('div', null, createDom('p'), createDom('p'));</code>
        2351 * would return a div with two child paragraphs
        2352 *
        2353 * An easy way to move all child nodes of an existing element to a new parent
        2354 * element is:
        2355 * <code>createDom('div', null, oldElement.childNodes);</code>
        2356 * which will remove all child nodes from the old element and add them as
        2357 * child nodes of the new DIV.
        2358 *
        2359 * @param {string} tagName Tag to create.
        2360 * @param {Object|string=} opt_attributes If object, then a map of name-value
        2361 * pairs for attributes. If a string, then this is the className of the new
        2362 * element.
        2363 * @param {...goog.dom.Appendable} var_args Further DOM nodes or
        2364 * strings for text nodes. If one of the var_args is an array or
        2365 * NodeList, its elements will be added as childNodes instead.
        2366 * @return {!Element} Reference to a DOM node.
        2367 */
        2368goog.dom.DomHelper.prototype.createDom = function(tagName,
        2369 opt_attributes,
        2370 var_args) {
        2371 return goog.dom.createDom_(this.document_, arguments);
        2372};
        2373
        2374
        2375/**
        2376 * Alias for {@code createDom}.
        2377 * @param {string} tagName Tag to create.
        2378 * @param {(Object|string)=} opt_attributes If object, then a map of name-value
        2379 * pairs for attributes. If a string, then this is the className of the new
        2380 * element.
        2381 * @param {...goog.dom.Appendable} var_args Further DOM nodes or strings for
        2382 * text nodes. If one of the var_args is an array, its children will be
        2383 * added as childNodes instead.
        2384 * @return {!Element} Reference to a DOM node.
        2385 * @deprecated Use {@link goog.dom.DomHelper.prototype.createDom} instead.
        2386 */
        2387goog.dom.DomHelper.prototype.$dom = goog.dom.DomHelper.prototype.createDom;
        2388
        2389
        2390/**
        2391 * Creates a new element.
        2392 * @param {string} name Tag name.
        2393 * @return {!Element} The new element.
        2394 */
        2395goog.dom.DomHelper.prototype.createElement = function(name) {
        2396 return this.document_.createElement(name);
        2397};
        2398
        2399
        2400/**
        2401 * Creates a new text node.
        2402 * @param {number|string} content Content.
        2403 * @return {!Text} The new text node.
        2404 */
        2405goog.dom.DomHelper.prototype.createTextNode = function(content) {
        2406 return this.document_.createTextNode(String(content));
        2407};
        2408
        2409
        2410/**
        2411 * Create a table.
        2412 * @param {number} rows The number of rows in the table. Must be >= 1.
        2413 * @param {number} columns The number of columns in the table. Must be >= 1.
        2414 * @param {boolean=} opt_fillWithNbsp If true, fills table entries with nsbps.
        2415 * @return {!Element} The created table.
        2416 */
        2417goog.dom.DomHelper.prototype.createTable = function(rows, columns,
        2418 opt_fillWithNbsp) {
        2419 return goog.dom.createTable_(this.document_, rows, columns,
        2420 !!opt_fillWithNbsp);
        2421};
        2422
        2423
        2424/**
        2425 * Converts an HTML string into a node or a document fragment. A single Node
        2426 * is used if the {@code htmlString} only generates a single node. If the
        2427 * {@code htmlString} generates multiple nodes then these are put inside a
        2428 * {@code DocumentFragment}.
        2429 *
        2430 * @param {string} htmlString The HTML string to convert.
        2431 * @return {!Node} The resulting node.
        2432 */
        2433goog.dom.DomHelper.prototype.htmlToDocumentFragment = function(htmlString) {
        2434 return goog.dom.htmlToDocumentFragment_(this.document_, htmlString);
        2435};
        2436
        2437
        2438/**
        2439 * Returns true if the browser is in "CSS1-compatible" (standards-compliant)
        2440 * mode, false otherwise.
        2441 * @return {boolean} True if in CSS1-compatible mode.
        2442 */
        2443goog.dom.DomHelper.prototype.isCss1CompatMode = function() {
        2444 return goog.dom.isCss1CompatMode_(this.document_);
        2445};
        2446
        2447
        2448/**
        2449 * Gets the window object associated with the document.
        2450 * @return {!Window} The window associated with the given document.
        2451 */
        2452goog.dom.DomHelper.prototype.getWindow = function() {
        2453 return goog.dom.getWindow_(this.document_);
        2454};
        2455
        2456
        2457/**
        2458 * Gets the document scroll element.
        2459 * @return {!Element} Scrolling element.
        2460 */
        2461goog.dom.DomHelper.prototype.getDocumentScrollElement = function() {
        2462 return goog.dom.getDocumentScrollElement_(this.document_);
        2463};
        2464
        2465
        2466/**
        2467 * Gets the document scroll distance as a coordinate object.
        2468 * @return {!goog.math.Coordinate} Object with properties 'x' and 'y'.
        2469 */
        2470goog.dom.DomHelper.prototype.getDocumentScroll = function() {
        2471 return goog.dom.getDocumentScroll_(this.document_);
        2472};
        2473
        2474
        2475/**
        2476 * Determines the active element in the given document.
        2477 * @param {Document=} opt_doc The document to look in.
        2478 * @return {Element} The active element.
        2479 */
        2480goog.dom.DomHelper.prototype.getActiveElement = function(opt_doc) {
        2481 return goog.dom.getActiveElement(opt_doc || this.document_);
        2482};
        2483
        2484
        2485/**
        2486 * Appends a child to a node.
        2487 * @param {Node} parent Parent.
        2488 * @param {Node} child Child.
        2489 */
        2490goog.dom.DomHelper.prototype.appendChild = goog.dom.appendChild;
        2491
        2492
        2493/**
        2494 * Appends a node with text or other nodes.
        2495 * @param {!Node} parent The node to append nodes to.
        2496 * @param {...goog.dom.Appendable} var_args The things to append to the node.
        2497 * If this is a Node it is appended as is.
        2498 * If this is a string then a text node is appended.
        2499 * If this is an array like object then fields 0 to length - 1 are appended.
        2500 */
        2501goog.dom.DomHelper.prototype.append = goog.dom.append;
        2502
        2503
        2504/**
        2505 * Determines if the given node can contain children, intended to be used for
        2506 * HTML generation.
        2507 *
        2508 * @param {Node} node The node to check.
        2509 * @return {boolean} Whether the node can contain children.
        2510 */
        2511goog.dom.DomHelper.prototype.canHaveChildren = goog.dom.canHaveChildren;
        2512
        2513
        2514/**
        2515 * Removes all the child nodes on a DOM node.
        2516 * @param {Node} node Node to remove children from.
        2517 */
        2518goog.dom.DomHelper.prototype.removeChildren = goog.dom.removeChildren;
        2519
        2520
        2521/**
        2522 * Inserts a new node before an existing reference node (i.e., as the previous
        2523 * sibling). If the reference node has no parent, then does nothing.
        2524 * @param {Node} newNode Node to insert.
        2525 * @param {Node} refNode Reference node to insert before.
        2526 */
        2527goog.dom.DomHelper.prototype.insertSiblingBefore = goog.dom.insertSiblingBefore;
        2528
        2529
        2530/**
        2531 * Inserts a new node after an existing reference node (i.e., as the next
        2532 * sibling). If the reference node has no parent, then does nothing.
        2533 * @param {Node} newNode Node to insert.
        2534 * @param {Node} refNode Reference node to insert after.
        2535 */
        2536goog.dom.DomHelper.prototype.insertSiblingAfter = goog.dom.insertSiblingAfter;
        2537
        2538
        2539/**
        2540 * Insert a child at a given index. If index is larger than the number of child
        2541 * nodes that the parent currently has, the node is inserted as the last child
        2542 * node.
        2543 * @param {Element} parent The element into which to insert the child.
        2544 * @param {Node} child The element to insert.
        2545 * @param {number} index The index at which to insert the new child node. Must
        2546 * not be negative.
        2547 */
        2548goog.dom.DomHelper.prototype.insertChildAt = goog.dom.insertChildAt;
        2549
        2550
        2551/**
        2552 * Removes a node from its parent.
        2553 * @param {Node} node The node to remove.
        2554 * @return {Node} The node removed if removed; else, null.
        2555 */
        2556goog.dom.DomHelper.prototype.removeNode = goog.dom.removeNode;
        2557
        2558
        2559/**
        2560 * Replaces a node in the DOM tree. Will do nothing if {@code oldNode} has no
        2561 * parent.
        2562 * @param {Node} newNode Node to insert.
        2563 * @param {Node} oldNode Node to replace.
        2564 */
        2565goog.dom.DomHelper.prototype.replaceNode = goog.dom.replaceNode;
        2566
        2567
        2568/**
        2569 * Flattens an element. That is, removes it and replace it with its children.
        2570 * @param {Element} element The element to flatten.
        2571 * @return {Element|undefined} The original element, detached from the document
        2572 * tree, sans children, or undefined if the element was already not in the
        2573 * document.
        2574 */
        2575goog.dom.DomHelper.prototype.flattenElement = goog.dom.flattenElement;
        2576
        2577
        2578/**
        2579 * Returns an array containing just the element children of the given element.
        2580 * @param {Element} element The element whose element children we want.
        2581 * @return {!(Array|NodeList)} An array or array-like list of just the element
        2582 * children of the given element.
        2583 */
        2584goog.dom.DomHelper.prototype.getChildren = goog.dom.getChildren;
        2585
        2586
        2587/**
        2588 * Returns the first child node that is an element.
        2589 * @param {Node} node The node to get the first child element of.
        2590 * @return {Element} The first child node of {@code node} that is an element.
        2591 */
        2592goog.dom.DomHelper.prototype.getFirstElementChild =
        2593 goog.dom.getFirstElementChild;
        2594
        2595
        2596/**
        2597 * Returns the last child node that is an element.
        2598 * @param {Node} node The node to get the last child element of.
        2599 * @return {Element} The last child node of {@code node} that is an element.
        2600 */
        2601goog.dom.DomHelper.prototype.getLastElementChild = goog.dom.getLastElementChild;
        2602
        2603
        2604/**
        2605 * Returns the first next sibling that is an element.
        2606 * @param {Node} node The node to get the next sibling element of.
        2607 * @return {Element} The next sibling of {@code node} that is an element.
        2608 */
        2609goog.dom.DomHelper.prototype.getNextElementSibling =
        2610 goog.dom.getNextElementSibling;
        2611
        2612
        2613/**
        2614 * Returns the first previous sibling that is an element.
        2615 * @param {Node} node The node to get the previous sibling element of.
        2616 * @return {Element} The first previous sibling of {@code node} that is
        2617 * an element.
        2618 */
        2619goog.dom.DomHelper.prototype.getPreviousElementSibling =
        2620 goog.dom.getPreviousElementSibling;
        2621
        2622
        2623/**
        2624 * Returns the next node in source order from the given node.
        2625 * @param {Node} node The node.
        2626 * @return {Node} The next node in the DOM tree, or null if this was the last
        2627 * node.
        2628 */
        2629goog.dom.DomHelper.prototype.getNextNode = goog.dom.getNextNode;
        2630
        2631
        2632/**
        2633 * Returns the previous node in source order from the given node.
        2634 * @param {Node} node The node.
        2635 * @return {Node} The previous node in the DOM tree, or null if this was the
        2636 * first node.
        2637 */
        2638goog.dom.DomHelper.prototype.getPreviousNode = goog.dom.getPreviousNode;
        2639
        2640
        2641/**
        2642 * Whether the object looks like a DOM node.
        2643 * @param {?} obj The object being tested for node likeness.
        2644 * @return {boolean} Whether the object looks like a DOM node.
        2645 */
        2646goog.dom.DomHelper.prototype.isNodeLike = goog.dom.isNodeLike;
        2647
        2648
        2649/**
        2650 * Whether the object looks like an Element.
        2651 * @param {?} obj The object being tested for Element likeness.
        2652 * @return {boolean} Whether the object looks like an Element.
        2653 */
        2654goog.dom.DomHelper.prototype.isElement = goog.dom.isElement;
        2655
        2656
        2657/**
        2658 * Returns true if the specified value is a Window object. This includes the
        2659 * global window for HTML pages, and iframe windows.
        2660 * @param {?} obj Variable to test.
        2661 * @return {boolean} Whether the variable is a window.
        2662 */
        2663goog.dom.DomHelper.prototype.isWindow = goog.dom.isWindow;
        2664
        2665
        2666/**
        2667 * Returns an element's parent, if it's an Element.
        2668 * @param {Element} element The DOM element.
        2669 * @return {Element} The parent, or null if not an Element.
        2670 */
        2671goog.dom.DomHelper.prototype.getParentElement = goog.dom.getParentElement;
        2672
        2673
        2674/**
        2675 * Whether a node contains another node.
        2676 * @param {Node} parent The node that should contain the other node.
        2677 * @param {Node} descendant The node to test presence of.
        2678 * @return {boolean} Whether the parent node contains the descendent node.
        2679 */
        2680goog.dom.DomHelper.prototype.contains = goog.dom.contains;
        2681
        2682
        2683/**
        2684 * Compares the document order of two nodes, returning 0 if they are the same
        2685 * node, a negative number if node1 is before node2, and a positive number if
        2686 * node2 is before node1. Note that we compare the order the tags appear in the
        2687 * document so in the tree <b><i>text</i></b> the B node is considered to be
        2688 * before the I node.
        2689 *
        2690 * @param {Node} node1 The first node to compare.
        2691 * @param {Node} node2 The second node to compare.
        2692 * @return {number} 0 if the nodes are the same node, a negative number if node1
        2693 * is before node2, and a positive number if node2 is before node1.
        2694 */
        2695goog.dom.DomHelper.prototype.compareNodeOrder = goog.dom.compareNodeOrder;
        2696
        2697
        2698/**
        2699 * Find the deepest common ancestor of the given nodes.
        2700 * @param {...Node} var_args The nodes to find a common ancestor of.
        2701 * @return {Node} The common ancestor of the nodes, or null if there is none.
        2702 * null will only be returned if two or more of the nodes are from different
        2703 * documents.
        2704 */
        2705goog.dom.DomHelper.prototype.findCommonAncestor = goog.dom.findCommonAncestor;
        2706
        2707
        2708/**
        2709 * Returns the owner document for a node.
        2710 * @param {Node} node The node to get the document for.
        2711 * @return {!Document} The document owning the node.
        2712 */
        2713goog.dom.DomHelper.prototype.getOwnerDocument = goog.dom.getOwnerDocument;
        2714
        2715
        2716/**
        2717 * Cross browser function for getting the document element of an iframe.
        2718 * @param {Element} iframe Iframe element.
        2719 * @return {!Document} The frame content document.
        2720 */
        2721goog.dom.DomHelper.prototype.getFrameContentDocument =
        2722 goog.dom.getFrameContentDocument;
        2723
        2724
        2725/**
        2726 * Cross browser function for getting the window of a frame or iframe.
        2727 * @param {Element} frame Frame element.
        2728 * @return {Window} The window associated with the given frame.
        2729 */
        2730goog.dom.DomHelper.prototype.getFrameContentWindow =
        2731 goog.dom.getFrameContentWindow;
        2732
        2733
        2734/**
        2735 * Sets the text content of a node, with cross-browser support.
        2736 * @param {Node} node The node to change the text content of.
        2737 * @param {string|number} text The value that should replace the node's content.
        2738 */
        2739goog.dom.DomHelper.prototype.setTextContent = goog.dom.setTextContent;
        2740
        2741
        2742/**
        2743 * Gets the outerHTML of a node, which islike innerHTML, except that it
        2744 * actually contains the HTML of the node itself.
        2745 * @param {Element} element The element to get the HTML of.
        2746 * @return {string} The outerHTML of the given element.
        2747 */
        2748goog.dom.DomHelper.prototype.getOuterHtml = goog.dom.getOuterHtml;
        2749
        2750
        2751/**
        2752 * Finds the first descendant node that matches the filter function. This does
        2753 * a depth first search.
        2754 * @param {Node} root The root of the tree to search.
        2755 * @param {function(Node) : boolean} p The filter function.
        2756 * @return {Node|undefined} The found node or undefined if none is found.
        2757 */
        2758goog.dom.DomHelper.prototype.findNode = goog.dom.findNode;
        2759
        2760
        2761/**
        2762 * Finds all the descendant nodes that matches the filter function. This does a
        2763 * depth first search.
        2764 * @param {Node} root The root of the tree to search.
        2765 * @param {function(Node) : boolean} p The filter function.
        2766 * @return {Array.<Node>} The found nodes or an empty array if none are found.
        2767 */
        2768goog.dom.DomHelper.prototype.findNodes = goog.dom.findNodes;
        2769
        2770
        2771/**
        2772 * Returns true if the element has a tab index that allows it to receive
        2773 * keyboard focus (tabIndex >= 0), false otherwise. Note that some elements
        2774 * natively support keyboard focus, even if they have no tab index.
        2775 * @param {Element} element Element to check.
        2776 * @return {boolean} Whether the element has a tab index that allows keyboard
        2777 * focus.
        2778 */
        2779goog.dom.DomHelper.prototype.isFocusableTabIndex = goog.dom.isFocusableTabIndex;
        2780
        2781
        2782/**
        2783 * Enables or disables keyboard focus support on the element via its tab index.
        2784 * Only elements for which {@link goog.dom.isFocusableTabIndex} returns true
        2785 * (or elements that natively support keyboard focus, like form elements) can
        2786 * receive keyboard focus. See http://go/tabindex for more info.
        2787 * @param {Element} element Element whose tab index is to be changed.
        2788 * @param {boolean} enable Whether to set or remove a tab index on the element
        2789 * that supports keyboard focus.
        2790 */
        2791goog.dom.DomHelper.prototype.setFocusableTabIndex =
        2792 goog.dom.setFocusableTabIndex;
        2793
        2794
        2795/**
        2796 * Returns true if the element can be focused, i.e. it has a tab index that
        2797 * allows it to receive keyboard focus (tabIndex >= 0), or it is an element
        2798 * that natively supports keyboard focus.
        2799 * @param {Element} element Element to check.
        2800 * @return {boolean} Whether the element allows keyboard focus.
        2801 */
        2802goog.dom.DomHelper.prototype.isFocusable = goog.dom.isFocusable;
        2803
        2804
        2805/**
        2806 * Returns the text contents of the current node, without markup. New lines are
        2807 * stripped and whitespace is collapsed, such that each character would be
        2808 * visible.
        2809 *
        2810 * In browsers that support it, innerText is used. Other browsers attempt to
        2811 * simulate it via node traversal. Line breaks are canonicalized in IE.
        2812 *
        2813 * @param {Node} node The node from which we are getting content.
        2814 * @return {string} The text content.
        2815 */
        2816goog.dom.DomHelper.prototype.getTextContent = goog.dom.getTextContent;
        2817
        2818
        2819/**
        2820 * Returns the text length of the text contained in a node, without markup. This
        2821 * is equivalent to the selection length if the node was selected, or the number
        2822 * of cursor movements to traverse the node. Images & BRs take one space. New
        2823 * lines are ignored.
        2824 *
        2825 * @param {Node} node The node whose text content length is being calculated.
        2826 * @return {number} The length of {@code node}'s text content.
        2827 */
        2828goog.dom.DomHelper.prototype.getNodeTextLength = goog.dom.getNodeTextLength;
        2829
        2830
        2831/**
        2832 * Returns the text offset of a node relative to one of its ancestors. The text
        2833 * length is the same as the length calculated by
        2834 * {@code goog.dom.getNodeTextLength}.
        2835 *
        2836 * @param {Node} node The node whose offset is being calculated.
        2837 * @param {Node=} opt_offsetParent Defaults to the node's owner document's body.
        2838 * @return {number} The text offset.
        2839 */
        2840goog.dom.DomHelper.prototype.getNodeTextOffset = goog.dom.getNodeTextOffset;
        2841
        2842
        2843/**
        2844 * Returns the node at a given offset in a parent node. If an object is
        2845 * provided for the optional third parameter, the node and the remainder of the
        2846 * offset will stored as properties of this object.
        2847 * @param {Node} parent The parent node.
        2848 * @param {number} offset The offset into the parent node.
        2849 * @param {Object=} opt_result Object to be used to store the return value. The
        2850 * return value will be stored in the form {node: Node, remainder: number}
        2851 * if this object is provided.
        2852 * @return {Node} The node at the given offset.
        2853 */
        2854goog.dom.DomHelper.prototype.getNodeAtOffset = goog.dom.getNodeAtOffset;
        2855
        2856
        2857/**
        2858 * Returns true if the object is a {@code NodeList}. To qualify as a NodeList,
        2859 * the object must have a numeric length property and an item function (which
        2860 * has type 'string' on IE for some reason).
        2861 * @param {Object} val Object to test.
        2862 * @return {boolean} Whether the object is a NodeList.
        2863 */
        2864goog.dom.DomHelper.prototype.isNodeList = goog.dom.isNodeList;
        2865
        2866
        2867/**
        2868 * Walks up the DOM hierarchy returning the first ancestor that has the passed
        2869 * tag name and/or class name. If the passed element matches the specified
        2870 * criteria, the element itself is returned.
        2871 * @param {Node} element The DOM node to start with.
        2872 * @param {?(goog.dom.TagName|string)=} opt_tag The tag name to match (or
        2873 * null/undefined to match only based on class name).
        2874 * @param {?string=} opt_class The class name to match (or null/undefined to
        2875 * match only based on tag name).
        2876 * @return {Element} The first ancestor that matches the passed criteria, or
        2877 * null if no match is found.
        2878 */
        2879goog.dom.DomHelper.prototype.getAncestorByTagNameAndClass =
        2880 goog.dom.getAncestorByTagNameAndClass;
        2881
        2882
        2883/**
        2884 * Walks up the DOM hierarchy returning the first ancestor that has the passed
        2885 * class name. If the passed element matches the specified criteria, the
        2886 * element itself is returned.
        2887 * @param {Node} element The DOM node to start with.
        2888 * @param {string} class The class name to match.
        2889 * @return {Element} The first ancestor that matches the passed criteria, or
        2890 * null if none match.
        2891 */
        2892goog.dom.DomHelper.prototype.getAncestorByClass =
        2893 goog.dom.getAncestorByClass;
        2894
        2895
        2896/**
        2897 * Walks up the DOM hierarchy returning the first ancestor that passes the
        2898 * matcher function.
        2899 * @param {Node} element The DOM node to start with.
        2900 * @param {function(Node) : boolean} matcher A function that returns true if the
        2901 * passed node matches the desired criteria.
        2902 * @param {boolean=} opt_includeNode If true, the node itself is included in
        2903 * the search (the first call to the matcher will pass startElement as
        2904 * the node to test).
        2905 * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the
        2906 * dom.
        2907 * @return {Node} DOM node that matched the matcher, or null if there was
        2908 * no match.
        2909 */
        2910goog.dom.DomHelper.prototype.getAncestor = goog.dom.getAncestor;
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/dom/nodetype.js.src.html b/docs/api/javascript/source/lib/goog/dom/nodetype.js.src.html index 732b4ef186465..f6c86b9a8f0e2 100644 --- a/docs/api/javascript/source/lib/goog/dom/nodetype.js.src.html +++ b/docs/api/javascript/source/lib/goog/dom/nodetype.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/dom/tagname.js.src.html b/docs/api/javascript/source/lib/goog/dom/tagname.js.src.html new file mode 100644 index 0000000000000..d4aae790a4032 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/dom/tagname.js.src.html @@ -0,0 +1 @@ +tagname.js

        lib/goog/dom/tagname.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 Defines the goog.dom.TagName enum. This enumerates
        17 * all HTML tag names specified in either the the W3C HTML 4.01 index of
        18 * elements or the HTML5 draft specification.
        19 *
        20 * References:
        21 * http://www.w3.org/TR/html401/index/elements.html
        22 * http://dev.w3.org/html5/spec/section-index.html
        23 *
        24 */
        25goog.provide('goog.dom.TagName');
        26
        27
        28/**
        29 * Enum of all html tag names specified by the W3C HTML4.01 and HTML5
        30 * specifications.
        31 * @enum {string}
        32 */
        33goog.dom.TagName = {
        34 A: 'A',
        35 ABBR: 'ABBR',
        36 ACRONYM: 'ACRONYM',
        37 ADDRESS: 'ADDRESS',
        38 APPLET: 'APPLET',
        39 AREA: 'AREA',
        40 ARTICLE: 'ARTICLE',
        41 ASIDE: 'ASIDE',
        42 AUDIO: 'AUDIO',
        43 B: 'B',
        44 BASE: 'BASE',
        45 BASEFONT: 'BASEFONT',
        46 BDI: 'BDI',
        47 BDO: 'BDO',
        48 BIG: 'BIG',
        49 BLOCKQUOTE: 'BLOCKQUOTE',
        50 BODY: 'BODY',
        51 BR: 'BR',
        52 BUTTON: 'BUTTON',
        53 CANVAS: 'CANVAS',
        54 CAPTION: 'CAPTION',
        55 CENTER: 'CENTER',
        56 CITE: 'CITE',
        57 CODE: 'CODE',
        58 COL: 'COL',
        59 COLGROUP: 'COLGROUP',
        60 COMMAND: 'COMMAND',
        61 DATA: 'DATA',
        62 DATALIST: 'DATALIST',
        63 DD: 'DD',
        64 DEL: 'DEL',
        65 DETAILS: 'DETAILS',
        66 DFN: 'DFN',
        67 DIALOG: 'DIALOG',
        68 DIR: 'DIR',
        69 DIV: 'DIV',
        70 DL: 'DL',
        71 DT: 'DT',
        72 EM: 'EM',
        73 EMBED: 'EMBED',
        74 FIELDSET: 'FIELDSET',
        75 FIGCAPTION: 'FIGCAPTION',
        76 FIGURE: 'FIGURE',
        77 FONT: 'FONT',
        78 FOOTER: 'FOOTER',
        79 FORM: 'FORM',
        80 FRAME: 'FRAME',
        81 FRAMESET: 'FRAMESET',
        82 H1: 'H1',
        83 H2: 'H2',
        84 H3: 'H3',
        85 H4: 'H4',
        86 H5: 'H5',
        87 H6: 'H6',
        88 HEAD: 'HEAD',
        89 HEADER: 'HEADER',
        90 HGROUP: 'HGROUP',
        91 HR: 'HR',
        92 HTML: 'HTML',
        93 I: 'I',
        94 IFRAME: 'IFRAME',
        95 IMG: 'IMG',
        96 INPUT: 'INPUT',
        97 INS: 'INS',
        98 ISINDEX: 'ISINDEX',
        99 KBD: 'KBD',
        100 KEYGEN: 'KEYGEN',
        101 LABEL: 'LABEL',
        102 LEGEND: 'LEGEND',
        103 LI: 'LI',
        104 LINK: 'LINK',
        105 MAP: 'MAP',
        106 MARK: 'MARK',
        107 MATH: 'MATH',
        108 MENU: 'MENU',
        109 META: 'META',
        110 METER: 'METER',
        111 NAV: 'NAV',
        112 NOFRAMES: 'NOFRAMES',
        113 NOSCRIPT: 'NOSCRIPT',
        114 OBJECT: 'OBJECT',
        115 OL: 'OL',
        116 OPTGROUP: 'OPTGROUP',
        117 OPTION: 'OPTION',
        118 OUTPUT: 'OUTPUT',
        119 P: 'P',
        120 PARAM: 'PARAM',
        121 PRE: 'PRE',
        122 PROGRESS: 'PROGRESS',
        123 Q: 'Q',
        124 RP: 'RP',
        125 RT: 'RT',
        126 RUBY: 'RUBY',
        127 S: 'S',
        128 SAMP: 'SAMP',
        129 SCRIPT: 'SCRIPT',
        130 SECTION: 'SECTION',
        131 SELECT: 'SELECT',
        132 SMALL: 'SMALL',
        133 SOURCE: 'SOURCE',
        134 SPAN: 'SPAN',
        135 STRIKE: 'STRIKE',
        136 STRONG: 'STRONG',
        137 STYLE: 'STYLE',
        138 SUB: 'SUB',
        139 SUMMARY: 'SUMMARY',
        140 SUP: 'SUP',
        141 SVG: 'SVG',
        142 TABLE: 'TABLE',
        143 TBODY: 'TBODY',
        144 TD: 'TD',
        145 TEXTAREA: 'TEXTAREA',
        146 TFOOT: 'TFOOT',
        147 TH: 'TH',
        148 THEAD: 'THEAD',
        149 TIME: 'TIME',
        150 TITLE: 'TITLE',
        151 TR: 'TR',
        152 TRACK: 'TRACK',
        153 TT: 'TT',
        154 U: 'U',
        155 UL: 'UL',
        156 VAR: 'VAR',
        157 VIDEO: 'VIDEO',
        158 WBR: 'WBR'
        159};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/dom/vendor.js.src.html b/docs/api/javascript/source/lib/goog/dom/vendor.js.src.html new file mode 100644 index 0000000000000..7a45ef7e74d8f --- /dev/null +++ b/docs/api/javascript/source/lib/goog/dom/vendor.js.src.html @@ -0,0 +1 @@ +vendor.js

        lib/goog/dom/vendor.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 Vendor prefix getters.
        17 */
        18
        19goog.provide('goog.dom.vendor');
        20
        21goog.require('goog.string');
        22goog.require('goog.userAgent');
        23
        24
        25/**
        26 * Returns the JS vendor prefix used in CSS properties. Different vendors
        27 * use different methods of changing the case of the property names.
        28 *
        29 * @return {?string} The JS vendor prefix or null if there is none.
        30 */
        31goog.dom.vendor.getVendorJsPrefix = function() {
        32 if (goog.userAgent.WEBKIT) {
        33 return 'Webkit';
        34 } else if (goog.userAgent.GECKO) {
        35 return 'Moz';
        36 } else if (goog.userAgent.IE) {
        37 return 'ms';
        38 } else if (goog.userAgent.OPERA) {
        39 return 'O';
        40 }
        41
        42 return null;
        43};
        44
        45
        46/**
        47 * Returns the vendor prefix used in CSS properties.
        48 *
        49 * @return {?string} The vendor prefix or null if there is none.
        50 */
        51goog.dom.vendor.getVendorPrefix = function() {
        52 if (goog.userAgent.WEBKIT) {
        53 return '-webkit';
        54 } else if (goog.userAgent.GECKO) {
        55 return '-moz';
        56 } else if (goog.userAgent.IE) {
        57 return '-ms';
        58 } else if (goog.userAgent.OPERA) {
        59 return '-o';
        60 }
        61
        62 return null;
        63};
        64
        65
        66/**
        67 * @param {string} propertyName A property name.
        68 * @param {!Object=} opt_object If provided, we verify if the property exists in
        69 * the object.
        70 * @return {?string} A vendor prefixed property name, or null if it does not
        71 * exist.
        72 */
        73goog.dom.vendor.getPrefixedPropertyName = function(propertyName, opt_object) {
        74 // We first check for a non-prefixed property, if available.
        75 if (opt_object && propertyName in opt_object) {
        76 return propertyName;
        77 }
        78 var prefix = goog.dom.vendor.getVendorJsPrefix();
        79 if (prefix) {
        80 prefix = prefix.toLowerCase();
        81 var prefixedPropertyName = prefix + goog.string.toTitleCase(propertyName);
        82 return (!goog.isDef(opt_object) || prefixedPropertyName in opt_object) ?
        83 prefixedPropertyName : null;
        84 }
        85 return null;
        86};
        87
        88
        89/**
        90 * @param {string} eventType An event type.
        91 * @return {string} A lower-cased vendor prefixed event type.
        92 */
        93goog.dom.vendor.getPrefixedEventType = function(eventType) {
        94 var prefix = goog.dom.vendor.getVendorJsPrefix() || '';
        95 return (prefix + eventType).toLowerCase();
        96};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/events/browserevent.js.src.html b/docs/api/javascript/source/lib/goog/events/browserevent.js.src.html new file mode 100644 index 0000000000000..da1a36b24fca5 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/events/browserevent.js.src.html @@ -0,0 +1 @@ +browserevent.js

        lib/goog/events/browserevent.js

        1// Copyright 2005 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 A patched, standardized event object for browser events.
        17 *
        18 * <pre>
        19 * The patched event object contains the following members:
        20 * - type {string} Event type, e.g. 'click'
        21 * - target {Object} The element that actually triggered the event
        22 * - currentTarget {Object} The element the listener is attached to
        23 * - relatedTarget {Object} For mouseover and mouseout, the previous object
        24 * - offsetX {number} X-coordinate relative to target
        25 * - offsetY {number} Y-coordinate relative to target
        26 * - clientX {number} X-coordinate relative to viewport
        27 * - clientY {number} Y-coordinate relative to viewport
        28 * - screenX {number} X-coordinate relative to the edge of the screen
        29 * - screenY {number} Y-coordinate relative to the edge of the screen
        30 * - button {number} Mouse button. Use isButton() to test.
        31 * - keyCode {number} Key-code
        32 * - ctrlKey {boolean} Was ctrl key depressed
        33 * - altKey {boolean} Was alt key depressed
        34 * - shiftKey {boolean} Was shift key depressed
        35 * - metaKey {boolean} Was meta key depressed
        36 * - defaultPrevented {boolean} Whether the default action has been prevented
        37 * - state {Object} History state object
        38 *
        39 * NOTE: The keyCode member contains the raw browser keyCode. For normalized
        40 * key and character code use {@link goog.events.KeyHandler}.
        41 * </pre>
        42 *
        43 */
        44
        45goog.provide('goog.events.BrowserEvent');
        46goog.provide('goog.events.BrowserEvent.MouseButton');
        47
        48goog.require('goog.events.BrowserFeature');
        49goog.require('goog.events.Event');
        50goog.require('goog.events.EventType');
        51goog.require('goog.reflect');
        52goog.require('goog.userAgent');
        53
        54
        55
        56/**
        57 * Accepts a browser event object and creates a patched, cross browser event
        58 * object.
        59 * The content of this object will not be initialized if no event object is
        60 * provided. If this is the case, init() needs to be invoked separately.
        61 * @param {Event=} opt_e Browser event object.
        62 * @param {EventTarget=} opt_currentTarget Current target for event.
        63 * @constructor
        64 * @extends {goog.events.Event}
        65 */
        66goog.events.BrowserEvent = function(opt_e, opt_currentTarget) {
        67 goog.events.BrowserEvent.base(this, 'constructor', opt_e ? opt_e.type : '');
        68
        69 /**
        70 * Target that fired the event.
        71 * @override
        72 * @type {Node}
        73 */
        74 this.target = null;
        75
        76 /**
        77 * Node that had the listener attached.
        78 * @override
        79 * @type {Node|undefined}
        80 */
        81 this.currentTarget = null;
        82
        83 /**
        84 * For mouseover and mouseout events, the related object for the event.
        85 * @type {Node}
        86 */
        87 this.relatedTarget = null;
        88
        89 /**
        90 * X-coordinate relative to target.
        91 * @type {number}
        92 */
        93 this.offsetX = 0;
        94
        95 /**
        96 * Y-coordinate relative to target.
        97 * @type {number}
        98 */
        99 this.offsetY = 0;
        100
        101 /**
        102 * X-coordinate relative to the window.
        103 * @type {number}
        104 */
        105 this.clientX = 0;
        106
        107 /**
        108 * Y-coordinate relative to the window.
        109 * @type {number}
        110 */
        111 this.clientY = 0;
        112
        113 /**
        114 * X-coordinate relative to the monitor.
        115 * @type {number}
        116 */
        117 this.screenX = 0;
        118
        119 /**
        120 * Y-coordinate relative to the monitor.
        121 * @type {number}
        122 */
        123 this.screenY = 0;
        124
        125 /**
        126 * Which mouse button was pressed.
        127 * @type {number}
        128 */
        129 this.button = 0;
        130
        131 /**
        132 * Keycode of key press.
        133 * @type {number}
        134 */
        135 this.keyCode = 0;
        136
        137 /**
        138 * Keycode of key press.
        139 * @type {number}
        140 */
        141 this.charCode = 0;
        142
        143 /**
        144 * Whether control was pressed at time of event.
        145 * @type {boolean}
        146 */
        147 this.ctrlKey = false;
        148
        149 /**
        150 * Whether alt was pressed at time of event.
        151 * @type {boolean}
        152 */
        153 this.altKey = false;
        154
        155 /**
        156 * Whether shift was pressed at time of event.
        157 * @type {boolean}
        158 */
        159 this.shiftKey = false;
        160
        161 /**
        162 * Whether the meta key was pressed at time of event.
        163 * @type {boolean}
        164 */
        165 this.metaKey = false;
        166
        167 /**
        168 * History state object, only set for PopState events where it's a copy of the
        169 * state object provided to pushState or replaceState.
        170 * @type {Object}
        171 */
        172 this.state = null;
        173
        174 /**
        175 * Whether the default platform modifier key was pressed at time of event.
        176 * (This is control for all platforms except Mac, where it's Meta.)
        177 * @type {boolean}
        178 */
        179 this.platformModifierKey = false;
        180
        181 /**
        182 * The browser event object.
        183 * @private {Event}
        184 */
        185 this.event_ = null;
        186
        187 if (opt_e) {
        188 this.init(opt_e, opt_currentTarget);
        189 }
        190};
        191goog.inherits(goog.events.BrowserEvent, goog.events.Event);
        192
        193
        194/**
        195 * Normalized button constants for the mouse.
        196 * @enum {number}
        197 */
        198goog.events.BrowserEvent.MouseButton = {
        199 LEFT: 0,
        200 MIDDLE: 1,
        201 RIGHT: 2
        202};
        203
        204
        205/**
        206 * Static data for mapping mouse buttons.
        207 * @type {!Array.<number>}
        208 */
        209goog.events.BrowserEvent.IEButtonMap = [
        210 1, // LEFT
        211 4, // MIDDLE
        212 2 // RIGHT
        213];
        214
        215
        216/**
        217 * Accepts a browser event object and creates a patched, cross browser event
        218 * object.
        219 * @param {Event} e Browser event object.
        220 * @param {EventTarget=} opt_currentTarget Current target for event.
        221 */
        222goog.events.BrowserEvent.prototype.init = function(e, opt_currentTarget) {
        223 var type = this.type = e.type;
        224
        225 // TODO(nicksantos): Change this.target to type EventTarget.
        226 this.target = /** @type {Node} */ (e.target) || e.srcElement;
        227
        228 // TODO(nicksantos): Change this.currentTarget to type EventTarget.
        229 this.currentTarget = /** @type {Node} */ (opt_currentTarget);
        230
        231 var relatedTarget = /** @type {Node} */ (e.relatedTarget);
        232 if (relatedTarget) {
        233 // There's a bug in FireFox where sometimes, relatedTarget will be a
        234 // chrome element, and accessing any property of it will get a permission
        235 // denied exception. See:
        236 // https://bugzilla.mozilla.org/show_bug.cgi?id=497780
        237 if (goog.userAgent.GECKO) {
        238 if (!goog.reflect.canAccessProperty(relatedTarget, 'nodeName')) {
        239 relatedTarget = null;
        240 }
        241 }
        242 // TODO(arv): Use goog.events.EventType when it has been refactored into its
        243 // own file.
        244 } else if (type == goog.events.EventType.MOUSEOVER) {
        245 relatedTarget = e.fromElement;
        246 } else if (type == goog.events.EventType.MOUSEOUT) {
        247 relatedTarget = e.toElement;
        248 }
        249
        250 this.relatedTarget = relatedTarget;
        251
        252 // Webkit emits a lame warning whenever layerX/layerY is accessed.
        253 // http://code.google.com/p/chromium/issues/detail?id=101733
        254 this.offsetX = (goog.userAgent.WEBKIT || e.offsetX !== undefined) ?
        255 e.offsetX : e.layerX;
        256 this.offsetY = (goog.userAgent.WEBKIT || e.offsetY !== undefined) ?
        257 e.offsetY : e.layerY;
        258
        259 this.clientX = e.clientX !== undefined ? e.clientX : e.pageX;
        260 this.clientY = e.clientY !== undefined ? e.clientY : e.pageY;
        261 this.screenX = e.screenX || 0;
        262 this.screenY = e.screenY || 0;
        263
        264 this.button = e.button;
        265
        266 this.keyCode = e.keyCode || 0;
        267 this.charCode = e.charCode || (type == 'keypress' ? e.keyCode : 0);
        268 this.ctrlKey = e.ctrlKey;
        269 this.altKey = e.altKey;
        270 this.shiftKey = e.shiftKey;
        271 this.metaKey = e.metaKey;
        272 this.platformModifierKey = goog.userAgent.MAC ? e.metaKey : e.ctrlKey;
        273 this.state = e.state;
        274 this.event_ = e;
        275 if (e.defaultPrevented) {
        276 this.preventDefault();
        277 }
        278};
        279
        280
        281/**
        282 * Tests to see which button was pressed during the event. This is really only
        283 * useful in IE and Gecko browsers. And in IE, it's only useful for
        284 * mousedown/mouseup events, because click only fires for the left mouse button.
        285 *
        286 * Safari 2 only reports the left button being clicked, and uses the value '1'
        287 * instead of 0. Opera only reports a mousedown event for the middle button, and
        288 * no mouse events for the right button. Opera has default behavior for left and
        289 * middle click that can only be overridden via a configuration setting.
        290 *
        291 * There's a nice table of this mess at http://www.unixpapa.com/js/mouse.html.
        292 *
        293 * @param {goog.events.BrowserEvent.MouseButton} button The button
        294 * to test for.
        295 * @return {boolean} True if button was pressed.
        296 */
        297goog.events.BrowserEvent.prototype.isButton = function(button) {
        298 if (!goog.events.BrowserFeature.HAS_W3C_BUTTON) {
        299 if (this.type == 'click') {
        300 return button == goog.events.BrowserEvent.MouseButton.LEFT;
        301 } else {
        302 return !!(this.event_.button &
        303 goog.events.BrowserEvent.IEButtonMap[button]);
        304 }
        305 } else {
        306 return this.event_.button == button;
        307 }
        308};
        309
        310
        311/**
        312 * Whether this has an "action"-producing mouse button.
        313 *
        314 * By definition, this includes left-click on windows/linux, and left-click
        315 * without the ctrl key on Macs.
        316 *
        317 * @return {boolean} The result.
        318 */
        319goog.events.BrowserEvent.prototype.isMouseActionButton = function() {
        320 // Webkit does not ctrl+click to be a right-click, so we
        321 // normalize it to behave like Gecko and Opera.
        322 return this.isButton(goog.events.BrowserEvent.MouseButton.LEFT) &&
        323 !(goog.userAgent.WEBKIT && goog.userAgent.MAC && this.ctrlKey);
        324};
        325
        326
        327/**
        328 * @override
        329 */
        330goog.events.BrowserEvent.prototype.stopPropagation = function() {
        331 goog.events.BrowserEvent.superClass_.stopPropagation.call(this);
        332 if (this.event_.stopPropagation) {
        333 this.event_.stopPropagation();
        334 } else {
        335 this.event_.cancelBubble = true;
        336 }
        337};
        338
        339
        340/**
        341 * @override
        342 */
        343goog.events.BrowserEvent.prototype.preventDefault = function() {
        344 goog.events.BrowserEvent.superClass_.preventDefault.call(this);
        345 var be = this.event_;
        346 if (!be.preventDefault) {
        347 be.returnValue = false;
        348 if (goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT) {
        349 /** @preserveTry */
        350 try {
        351 // Most keys can be prevented using returnValue. Some special keys
        352 // require setting the keyCode to -1 as well:
        353 //
        354 // In IE7:
        355 // F3, F5, F10, F11, Ctrl+P, Crtl+O, Ctrl+F (these are taken from IE6)
        356 //
        357 // In IE8:
        358 // Ctrl+P, Crtl+O, Ctrl+F (F1-F12 cannot be stopped through the event)
        359 //
        360 // We therefore do this for all function keys as well as when Ctrl key
        361 // is pressed.
        362 var VK_F1 = 112;
        363 var VK_F12 = 123;
        364 if (be.ctrlKey || be.keyCode >= VK_F1 && be.keyCode <= VK_F12) {
        365 be.keyCode = -1;
        366 }
        367 } catch (ex) {
        368 // IE throws an 'access denied' exception when trying to change
        369 // keyCode in some situations (e.g. srcElement is input[type=file],
        370 // or srcElement is an anchor tag rewritten by parent's innerHTML).
        371 // Do nothing in this case.
        372 }
        373 }
        374 } else {
        375 be.preventDefault();
        376 }
        377};
        378
        379
        380/**
        381 * @return {Event} The underlying browser event object.
        382 */
        383goog.events.BrowserEvent.prototype.getBrowserEvent = function() {
        384 return this.event_;
        385};
        386
        387
        388/** @override */
        389goog.events.BrowserEvent.prototype.disposeInternal = function() {
        390};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/events/browserfeature.js.src.html b/docs/api/javascript/source/lib/goog/events/browserfeature.js.src.html new file mode 100644 index 0000000000000..16c87d9f09fde --- /dev/null +++ b/docs/api/javascript/source/lib/goog/events/browserfeature.js.src.html @@ -0,0 +1 @@ +browserfeature.js

        lib/goog/events/browserfeature.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 Browser capability checks for the events package.
        17 *
        18 */
        19
        20
        21goog.provide('goog.events.BrowserFeature');
        22
        23goog.require('goog.userAgent');
        24
        25
        26/**
        27 * Enum of browser capabilities.
        28 * @enum {boolean}
        29 */
        30goog.events.BrowserFeature = {
        31 /**
        32 * Whether the button attribute of the event is W3C compliant. False in
        33 * Internet Explorer prior to version 9; document-version dependent.
        34 */
        35 HAS_W3C_BUTTON: !goog.userAgent.IE ||
        36 goog.userAgent.isDocumentModeOrHigher(9),
        37
        38 /**
        39 * Whether the browser supports full W3C event model.
        40 */
        41 HAS_W3C_EVENT_SUPPORT: !goog.userAgent.IE ||
        42 goog.userAgent.isDocumentModeOrHigher(9),
        43
        44 /**
        45 * To prevent default in IE7-8 for certain keydown events we need set the
        46 * keyCode to -1.
        47 */
        48 SET_KEY_CODE_TO_PREVENT_DEFAULT: goog.userAgent.IE &&
        49 !goog.userAgent.isVersionOrHigher('9'),
        50
        51 /**
        52 * Whether the {@code navigator.onLine} property is supported.
        53 */
        54 HAS_NAVIGATOR_ONLINE_PROPERTY: !goog.userAgent.WEBKIT ||
        55 goog.userAgent.isVersionOrHigher('528'),
        56
        57 /**
        58 * Whether HTML5 network online/offline events are supported.
        59 */
        60 HAS_HTML5_NETWORK_EVENT_SUPPORT:
        61 goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9b') ||
        62 goog.userAgent.IE && goog.userAgent.isVersionOrHigher('8') ||
        63 goog.userAgent.OPERA && goog.userAgent.isVersionOrHigher('9.5') ||
        64 goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('528'),
        65
        66 /**
        67 * Whether HTML5 network events fire on document.body, or otherwise the
        68 * window.
        69 */
        70 HTML5_NETWORK_EVENTS_FIRE_ON_BODY:
        71 goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('8') ||
        72 goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9'),
        73
        74 /**
        75 * Whether touch is enabled in the browser.
        76 */
        77 TOUCH_ENABLED:
        78 ('ontouchstart' in goog.global ||
        79 !!(goog.global['document'] &&
        80 document.documentElement &&
        81 'ontouchstart' in document.documentElement) ||
        82 // IE10 uses non-standard touch events, so it has a different check.
        83 !!(goog.global['navigator'] &&
        84 goog.global['navigator']['msMaxTouchPoints']))
        85};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/events/event.js.src.html b/docs/api/javascript/source/lib/goog/events/event.js.src.html new file mode 100644 index 0000000000000..d3142554f60e5 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/events/event.js.src.html @@ -0,0 +1 @@ +event.js

        lib/goog/events/event.js

        1// Copyright 2005 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 A base class for event objects.
        17 *
        18 */
        19
        20
        21goog.provide('goog.events.Event');
        22goog.provide('goog.events.EventLike');
        23
        24/**
        25 * goog.events.Event no longer depends on goog.Disposable. Keep requiring
        26 * goog.Disposable here to not break projects which assume this dependency.
        27 * @suppress {extraRequire}
        28 */
        29goog.require('goog.Disposable');
        30goog.require('goog.events.EventId');
        31
        32
        33/**
        34 * A typedef for event like objects that are dispatchable via the
        35 * goog.events.dispatchEvent function. strings are treated as the type for a
        36 * goog.events.Event. Objects are treated as an extension of a new
        37 * goog.events.Event with the type property of the object being used as the type
        38 * of the Event.
        39 * @typedef {string|Object|goog.events.Event|goog.events.EventId}
        40 */
        41goog.events.EventLike;
        42
        43
        44
        45/**
        46 * A base class for event objects, so that they can support preventDefault and
        47 * stopPropagation.
        48 *
        49 * @param {string|!goog.events.EventId} type Event Type.
        50 * @param {Object=} opt_target Reference to the object that is the target of
        51 * this event. It has to implement the {@code EventTarget} interface
        52 * declared at {@link http://developer.mozilla.org/en/DOM/EventTarget}.
        53 * @constructor
        54 */
        55goog.events.Event = function(type, opt_target) {
        56 /**
        57 * Event type.
        58 * @type {string}
        59 */
        60 this.type = type instanceof goog.events.EventId ? String(type) : type;
        61
        62 /**
        63 * TODO(user): The type should probably be
        64 * EventTarget|goog.events.EventTarget.
        65 *
        66 * Target of the event.
        67 * @type {Object|undefined}
        68 */
        69 this.target = opt_target;
        70
        71 /**
        72 * Object that had the listener attached.
        73 * @type {Object|undefined}
        74 */
        75 this.currentTarget = this.target;
        76
        77 /**
        78 * Whether to cancel the event in internal capture/bubble processing for IE.
        79 * @type {boolean}
        80 * @public
        81 * @suppress {underscore|visibility} Technically public, but referencing this
        82 * outside this package is strongly discouraged.
        83 */
        84 this.propagationStopped_ = false;
        85
        86 /**
        87 * Whether the default action has been prevented.
        88 * This is a property to match the W3C specification at
        89 * {@link http://www.w3.org/TR/DOM-Level-3-Events/
        90 * #events-event-type-defaultPrevented}.
        91 * Must be treated as read-only outside the class.
        92 * @type {boolean}
        93 */
        94 this.defaultPrevented = false;
        95
        96 /**
        97 * Return value for in internal capture/bubble processing for IE.
        98 * @type {boolean}
        99 * @public
        100 * @suppress {underscore|visibility} Technically public, but referencing this
        101 * outside this package is strongly discouraged.
        102 */
        103 this.returnValue_ = true;
        104};
        105
        106
        107/**
        108 * For backwards compatibility (goog.events.Event used to inherit
        109 * goog.Disposable).
        110 * @deprecated Events don't need to be disposed.
        111 */
        112goog.events.Event.prototype.disposeInternal = function() {
        113};
        114
        115
        116/**
        117 * For backwards compatibility (goog.events.Event used to inherit
        118 * goog.Disposable).
        119 * @deprecated Events don't need to be disposed.
        120 */
        121goog.events.Event.prototype.dispose = function() {
        122};
        123
        124
        125/**
        126 * Stops event propagation.
        127 */
        128goog.events.Event.prototype.stopPropagation = function() {
        129 this.propagationStopped_ = true;
        130};
        131
        132
        133/**
        134 * Prevents the default action, for example a link redirecting to a url.
        135 */
        136goog.events.Event.prototype.preventDefault = function() {
        137 this.defaultPrevented = true;
        138 this.returnValue_ = false;
        139};
        140
        141
        142/**
        143 * Stops the propagation of the event. It is equivalent to
        144 * {@code e.stopPropagation()}, but can be used as the callback argument of
        145 * {@link goog.events.listen} without declaring another function.
        146 * @param {!goog.events.Event} e An event.
        147 */
        148goog.events.Event.stopPropagation = function(e) {
        149 e.stopPropagation();
        150};
        151
        152
        153/**
        154 * Prevents the default action. It is equivalent to
        155 * {@code e.preventDefault()}, but can be used as the callback argument of
        156 * {@link goog.events.listen} without declaring another function.
        157 * @param {!goog.events.Event} e An event.
        158 */
        159goog.events.Event.preventDefault = function(e) {
        160 e.preventDefault();
        161};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/events/eventid.js.src.html b/docs/api/javascript/source/lib/goog/events/eventid.js.src.html new file mode 100644 index 0000000000000..7a5d3bc8ccded --- /dev/null +++ b/docs/api/javascript/source/lib/goog/events/eventid.js.src.html @@ -0,0 +1 @@ +eventid.js

        lib/goog/events/eventid.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.events.EventId');
        16
        17
        18
        19/**
        20 * A templated class that is used when registering for events. Typical usage:
        21 * <code>
        22 * /** @type {goog.events.EventId.<MyEventObj>}
        23 * var myEventId = new goog.events.EventId(
        24 * goog.events.getUniqueId(('someEvent'));
        25 *
        26 * // No need to cast or declare here since the compiler knows the correct
        27 * // type of 'evt' (MyEventObj).
        28 * something.listen(myEventId, function(evt) {});
        29 * </code>
        30 *
        31 * @param {string} eventId
        32 * @template T
        33 * @constructor
        34 * @struct
        35 * @final
        36 */
        37goog.events.EventId = function(eventId) {
        38 /** @const */ this.id = eventId;
        39};
        40
        41
        42/**
        43 * @override
        44 */
        45goog.events.EventId.prototype.toString = function() {
        46 return this.id;
        47};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/events/events.js.src.html b/docs/api/javascript/source/lib/goog/events/events.js.src.html new file mode 100644 index 0000000000000..2faec050c6fc3 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/events/events.js.src.html @@ -0,0 +1 @@ +events.js

        lib/goog/events/events.js

        1// Copyright 2005 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 An event manager for both native browser event
        17 * targets and custom JavaScript event targets
        18 * ({@code goog.events.Listenable}). This provides an abstraction
        19 * over browsers' event systems.
        20 *
        21 * It also provides a simulation of W3C event model's capture phase in
        22 * Internet Explorer (IE 8 and below). Caveat: the simulation does not
        23 * interact well with listeners registered directly on the elements
        24 * (bypassing goog.events) or even with listeners registered via
        25 * goog.events in a separate JS binary. In these cases, we provide
        26 * no ordering guarantees.
        27 *
        28 * The listeners will receive a "patched" event object. Such event object
        29 * contains normalized values for certain event properties that differs in
        30 * different browsers.
        31 *
        32 * Example usage:
        33 * <pre>
        34 * goog.events.listen(myNode, 'click', function(e) { alert('woo') });
        35 * goog.events.listen(myNode, 'mouseover', mouseHandler, true);
        36 * goog.events.unlisten(myNode, 'mouseover', mouseHandler, true);
        37 * goog.events.removeAll(myNode);
        38 * </pre>
        39 *
        40 * in IE and event object patching]
        41 *
        42 * @see ../demos/events.html
        43 * @see ../demos/event-propagation.html
        44 * @see ../demos/stopevent.html
        45 */
        46
        47// IMPLEMENTATION NOTES:
        48// goog.events stores an auxiliary data structure on each EventTarget
        49// source being listened on. This allows us to take advantage of GC,
        50// having the data structure GC'd when the EventTarget is GC'd. This
        51// GC behavior is equivalent to using W3C DOM Events directly.
        52
        53goog.provide('goog.events');
        54goog.provide('goog.events.CaptureSimulationMode');
        55goog.provide('goog.events.Key');
        56goog.provide('goog.events.ListenableType');
        57
        58goog.require('goog.asserts');
        59goog.require('goog.debug.entryPointRegistry');
        60goog.require('goog.events.BrowserEvent');
        61goog.require('goog.events.BrowserFeature');
        62goog.require('goog.events.Listenable');
        63goog.require('goog.events.ListenerMap');
        64
        65goog.forwardDeclare('goog.debug.ErrorHandler');
        66goog.forwardDeclare('goog.events.EventWrapper');
        67
        68
        69/**
        70 * @typedef {number|goog.events.ListenableKey}
        71 */
        72goog.events.Key;
        73
        74
        75/**
        76 * @typedef {EventTarget|goog.events.Listenable}
        77 */
        78goog.events.ListenableType;
        79
        80
        81/**
        82 * Property name on a native event target for the listener map
        83 * associated with the event target.
        84 * @private @const {string}
        85 */
        86goog.events.LISTENER_MAP_PROP_ = 'closure_lm_' + ((Math.random() * 1e6) | 0);
        87
        88
        89/**
        90 * String used to prepend to IE event types.
        91 * @const
        92 * @private
        93 */
        94goog.events.onString_ = 'on';
        95
        96
        97/**
        98 * Map of computed "on<eventname>" strings for IE event types. Caching
        99 * this removes an extra object allocation in goog.events.listen which
        100 * improves IE6 performance.
        101 * @const
        102 * @dict
        103 * @private
        104 */
        105goog.events.onStringMap_ = {};
        106
        107
        108/**
        109 * @enum {number} Different capture simulation mode for IE8-.
        110 */
        111goog.events.CaptureSimulationMode = {
        112 /**
        113 * Does not perform capture simulation. Will asserts in IE8- when you
        114 * add capture listeners.
        115 */
        116 OFF_AND_FAIL: 0,
        117
        118 /**
        119 * Does not perform capture simulation, silently ignore capture
        120 * listeners.
        121 */
        122 OFF_AND_SILENT: 1,
        123
        124 /**
        125 * Performs capture simulation.
        126 */
        127 ON: 2
        128};
        129
        130
        131/**
        132 * @define {number} The capture simulation mode for IE8-. By default,
        133 * this is ON.
        134 */
        135goog.define('goog.events.CAPTURE_SIMULATION_MODE', 2);
        136
        137
        138/**
        139 * Estimated count of total native listeners.
        140 * @private {number}
        141 */
        142goog.events.listenerCountEstimate_ = 0;
        143
        144
        145/**
        146 * Adds an event listener for a specific event on a native event
        147 * target (such as a DOM element) or an object that has implemented
        148 * {@link goog.events.Listenable}. A listener can only be added once
        149 * to an object and if it is added again the key for the listener is
        150 * returned. Note that if the existing listener is a one-off listener
        151 * (registered via listenOnce), it will no longer be a one-off
        152 * listener after a call to listen().
        153 *
        154 * @param {EventTarget|goog.events.Listenable} src The node to listen
        155 * to events on.
        156 * @param {string|Array.<string>|
        157 * !goog.events.EventId.<EVENTOBJ>|!Array.<!goog.events.EventId.<EVENTOBJ>>}
        158 * type Event type or array of event types.
        159 * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(?):?}|null}
        160 * listener Callback method, or an object with a handleEvent function.
        161 * WARNING: passing an Object is now softly deprecated.
        162 * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to
        163 * false).
        164 * @param {T=} opt_handler Element in whose scope to call the listener.
        165 * @return {goog.events.Key} Unique key for the listener.
        166 * @template T,EVENTOBJ
        167 */
        168goog.events.listen = function(src, type, listener, opt_capt, opt_handler) {
        169 if (goog.isArray(type)) {
        170 for (var i = 0; i < type.length; i++) {
        171 goog.events.listen(src, type[i], listener, opt_capt, opt_handler);
        172 }
        173 return null;
        174 }
        175
        176 listener = goog.events.wrapListener(listener);
        177 if (goog.events.Listenable.isImplementedBy(src)) {
        178 return src.listen(
        179 /** @type {string|!goog.events.EventId} */ (type),
        180 listener, opt_capt, opt_handler);
        181 } else {
        182 return goog.events.listen_(
        183 /** @type {EventTarget} */ (src),
        184 /** @type {string|!goog.events.EventId} */ (type),
        185 listener, /* callOnce */ false, opt_capt, opt_handler);
        186 }
        187};
        188
        189
        190/**
        191 * Adds an event listener for a specific event on a native event
        192 * target. A listener can only be added once to an object and if it
        193 * is added again the key for the listener is returned.
        194 *
        195 * Note that a one-off listener will not change an existing listener,
        196 * if any. On the other hand a normal listener will change existing
        197 * one-off listener to become a normal listener.
        198 *
        199 * @param {EventTarget} src The node to listen to events on.
        200 * @param {string|!goog.events.EventId} type Event type.
        201 * @param {!Function} listener Callback function.
        202 * @param {boolean} callOnce Whether the listener is a one-off
        203 * listener or otherwise.
        204 * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to
        205 * false).
        206 * @param {Object=} opt_handler Element in whose scope to call the listener.
        207 * @return {goog.events.ListenableKey} Unique key for the listener.
        208 * @private
        209 */
        210goog.events.listen_ = function(
        211 src, type, listener, callOnce, opt_capt, opt_handler) {
        212 if (!type) {
        213 throw Error('Invalid event type');
        214 }
        215
        216 var capture = !!opt_capt;
        217 if (capture && !goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) {
        218 if (goog.events.CAPTURE_SIMULATION_MODE ==
        219 goog.events.CaptureSimulationMode.OFF_AND_FAIL) {
        220 goog.asserts.fail('Can not register capture listener in IE8-.');
        221 return null;
        222 } else if (goog.events.CAPTURE_SIMULATION_MODE ==
        223 goog.events.CaptureSimulationMode.OFF_AND_SILENT) {
        224 return null;
        225 }
        226 }
        227
        228 var listenerMap = goog.events.getListenerMap_(src);
        229 if (!listenerMap) {
        230 src[goog.events.LISTENER_MAP_PROP_] = listenerMap =
        231 new goog.events.ListenerMap(src);
        232 }
        233
        234 var listenerObj = listenerMap.add(
        235 type, listener, callOnce, opt_capt, opt_handler);
        236
        237 // If the listenerObj already has a proxy, it has been set up
        238 // previously. We simply return.
        239 if (listenerObj.proxy) {
        240 return listenerObj;
        241 }
        242
        243 var proxy = goog.events.getProxy();
        244 listenerObj.proxy = proxy;
        245
        246 proxy.src = src;
        247 proxy.listener = listenerObj;
        248
        249 // Attach the proxy through the browser's API
        250 if (src.addEventListener) {
        251 src.addEventListener(type.toString(), proxy, capture);
        252 } else {
        253 // The else above used to be else if (src.attachEvent) and then there was
        254 // another else statement that threw an exception warning the developer
        255 // they made a mistake. This resulted in an extra object allocation in IE6
        256 // due to a wrapper object that had to be implemented around the element
        257 // and so was removed.
        258 src.attachEvent(goog.events.getOnString_(type.toString()), proxy);
        259 }
        260
        261 goog.events.listenerCountEstimate_++;
        262 return listenerObj;
        263};
        264
        265
        266/**
        267 * Helper function for returning a proxy function.
        268 * @return {!Function} A new or reused function object.
        269 */
        270goog.events.getProxy = function() {
        271 var proxyCallbackFunction = goog.events.handleBrowserEvent_;
        272 // Use a local var f to prevent one allocation.
        273 var f = goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT ?
        274 function(eventObject) {
        275 return proxyCallbackFunction.call(f.src, f.listener, eventObject);
        276 } :
        277 function(eventObject) {
        278 var v = proxyCallbackFunction.call(f.src, f.listener, eventObject);
        279 // NOTE(user): In IE, we hack in a capture phase. However, if
        280 // there is inline event handler which tries to prevent default (for
        281 // example <a href="..." onclick="return false">...</a>) in a
        282 // descendant element, the prevent default will be overridden
        283 // by this listener if this listener were to return true. Hence, we
        284 // return undefined.
        285 if (!v) return v;
        286 };
        287 return f;
        288};
        289
        290
        291/**
        292 * Adds an event listener for a specific event on a native event
        293 * target (such as a DOM element) or an object that has implemented
        294 * {@link goog.events.Listenable}. After the event has fired the event
        295 * listener is removed from the target.
        296 *
        297 * If an existing listener already exists, listenOnce will do
        298 * nothing. In particular, if the listener was previously registered
        299 * via listen(), listenOnce() will not turn the listener into a
        300 * one-off listener. Similarly, if there is already an existing
        301 * one-off listener, listenOnce does not modify the listeners (it is
        302 * still a once listener).
        303 *
        304 * @param {EventTarget|goog.events.Listenable} src The node to listen
        305 * to events on.
        306 * @param {string|Array.<string>|
        307 * !goog.events.EventId.<EVENTOBJ>|!Array.<!goog.events.EventId.<EVENTOBJ>>}
        308 * type Event type or array of event types.
        309 * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(?):?}|null}
        310 * listener Callback method.
        311 * @param {boolean=} opt_capt Fire in capture phase?.
        312 * @param {T=} opt_handler Element in whose scope to call the listener.
        313 * @return {goog.events.Key} Unique key for the listener.
        314 * @template T,EVENTOBJ
        315 */
        316goog.events.listenOnce = function(src, type, listener, opt_capt, opt_handler) {
        317 if (goog.isArray(type)) {
        318 for (var i = 0; i < type.length; i++) {
        319 goog.events.listenOnce(src, type[i], listener, opt_capt, opt_handler);
        320 }
        321 return null;
        322 }
        323
        324 listener = goog.events.wrapListener(listener);
        325 if (goog.events.Listenable.isImplementedBy(src)) {
        326 return src.listenOnce(
        327 /** @type {string|!goog.events.EventId} */ (type),
        328 listener, opt_capt, opt_handler);
        329 } else {
        330 return goog.events.listen_(
        331 /** @type {EventTarget} */ (src),
        332 /** @type {string|!goog.events.EventId} */ (type),
        333 listener, /* callOnce */ true, opt_capt, opt_handler);
        334 }
        335};
        336
        337
        338/**
        339 * Adds an event listener with a specific event wrapper on a DOM Node or an
        340 * object that has implemented {@link goog.events.Listenable}. A listener can
        341 * only be added once to an object.
        342 *
        343 * @param {EventTarget|goog.events.Listenable} src The target to
        344 * listen to events on.
        345 * @param {goog.events.EventWrapper} wrapper Event wrapper to use.
        346 * @param {function(this:T, ?):?|{handleEvent:function(?):?}|null} listener
        347 * Callback method, or an object with a handleEvent function.
        348 * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to
        349 * false).
        350 * @param {T=} opt_handler Element in whose scope to call the listener.
        351 * @template T
        352 */
        353goog.events.listenWithWrapper = function(src, wrapper, listener, opt_capt,
        354 opt_handler) {
        355 wrapper.listen(src, listener, opt_capt, opt_handler);
        356};
        357
        358
        359/**
        360 * Removes an event listener which was added with listen().
        361 *
        362 * @param {EventTarget|goog.events.Listenable} src The target to stop
        363 * listening to events on.
        364 * @param {string|Array.<string>|
        365 * !goog.events.EventId.<EVENTOBJ>|!Array.<!goog.events.EventId.<EVENTOBJ>>}
        366 * type Event type or array of event types to unlisten to.
        367 * @param {function(?):?|{handleEvent:function(?):?}|null} listener The
        368 * listener function to remove.
        369 * @param {boolean=} opt_capt In DOM-compliant browsers, this determines
        370 * whether the listener is fired during the capture or bubble phase of the
        371 * event.
        372 * @param {Object=} opt_handler Element in whose scope to call the listener.
        373 * @return {?boolean} indicating whether the listener was there to remove.
        374 * @template EVENTOBJ
        375 */
        376goog.events.unlisten = function(src, type, listener, opt_capt, opt_handler) {
        377 if (goog.isArray(type)) {
        378 for (var i = 0; i < type.length; i++) {
        379 goog.events.unlisten(src, type[i], listener, opt_capt, opt_handler);
        380 }
        381 return null;
        382 }
        383
        384 listener = goog.events.wrapListener(listener);
        385 if (goog.events.Listenable.isImplementedBy(src)) {
        386 return src.unlisten(
        387 /** @type {string|!goog.events.EventId} */ (type),
        388 listener, opt_capt, opt_handler);
        389 }
        390
        391 if (!src) {
        392 // TODO(user): We should tighten the API to only accept
        393 // non-null objects, or add an assertion here.
        394 return false;
        395 }
        396
        397 var capture = !!opt_capt;
        398 var listenerMap = goog.events.getListenerMap_(
        399 /** @type {EventTarget} */ (src));
        400 if (listenerMap) {
        401 var listenerObj = listenerMap.getListener(
        402 /** @type {string|!goog.events.EventId} */ (type),
        403 listener, capture, opt_handler);
        404 if (listenerObj) {
        405 return goog.events.unlistenByKey(listenerObj);
        406 }
        407 }
        408
        409 return false;
        410};
        411
        412
        413/**
        414 * Removes an event listener which was added with listen() by the key
        415 * returned by listen().
        416 *
        417 * @param {goog.events.Key} key The key returned by listen() for this
        418 * event listener.
        419 * @return {boolean} indicating whether the listener was there to remove.
        420 */
        421goog.events.unlistenByKey = function(key) {
        422 // TODO(user): Remove this check when tests that rely on this
        423 // are fixed.
        424 if (goog.isNumber(key)) {
        425 return false;
        426 }
        427
        428 var listener = /** @type {goog.events.ListenableKey} */ (key);
        429 if (!listener || listener.removed) {
        430 return false;
        431 }
        432
        433 var src = listener.src;
        434 if (goog.events.Listenable.isImplementedBy(src)) {
        435 return src.unlistenByKey(listener);
        436 }
        437
        438 var type = listener.type;
        439 var proxy = listener.proxy;
        440 if (src.removeEventListener) {
        441 src.removeEventListener(type, proxy, listener.capture);
        442 } else if (src.detachEvent) {
        443 src.detachEvent(goog.events.getOnString_(type), proxy);
        444 }
        445 goog.events.listenerCountEstimate_--;
        446
        447 var listenerMap = goog.events.getListenerMap_(
        448 /** @type {EventTarget} */ (src));
        449 // TODO(user): Try to remove this conditional and execute the
        450 // first branch always. This should be safe.
        451 if (listenerMap) {
        452 listenerMap.removeByKey(listener);
        453 if (listenerMap.getTypeCount() == 0) {
        454 // Null the src, just because this is simple to do (and useful
        455 // for IE <= 7).
        456 listenerMap.src = null;
        457 // We don't use delete here because IE does not allow delete
        458 // on a window object.
        459 src[goog.events.LISTENER_MAP_PROP_] = null;
        460 }
        461 } else {
        462 listener.markAsRemoved();
        463 }
        464
        465 return true;
        466};
        467
        468
        469/**
        470 * Removes an event listener which was added with listenWithWrapper().
        471 *
        472 * @param {EventTarget|goog.events.Listenable} src The target to stop
        473 * listening to events on.
        474 * @param {goog.events.EventWrapper} wrapper Event wrapper to use.
        475 * @param {function(?):?|{handleEvent:function(?):?}|null} listener The
        476 * listener function to remove.
        477 * @param {boolean=} opt_capt In DOM-compliant browsers, this determines
        478 * whether the listener is fired during the capture or bubble phase of the
        479 * event.
        480 * @param {Object=} opt_handler Element in whose scope to call the listener.
        481 */
        482goog.events.unlistenWithWrapper = function(src, wrapper, listener, opt_capt,
        483 opt_handler) {
        484 wrapper.unlisten(src, listener, opt_capt, opt_handler);
        485};
        486
        487
        488/**
        489 * Removes all listeners from an object. You can also optionally
        490 * remove listeners of a particular type.
        491 *
        492 * @param {Object|undefined} obj Object to remove listeners from. Must be an
        493 * EventTarget or a goog.events.Listenable.
        494 * @param {string|!goog.events.EventId=} opt_type Type of event to remove.
        495 * Default is all types.
        496 * @return {number} Number of listeners removed.
        497 */
        498goog.events.removeAll = function(obj, opt_type) {
        499 // TODO(user): Change the type of obj to
        500 // (!EventTarget|!goog.events.Listenable).
        501
        502 if (!obj) {
        503 return 0;
        504 }
        505
        506 if (goog.events.Listenable.isImplementedBy(obj)) {
        507 return obj.removeAllListeners(opt_type);
        508 }
        509
        510 var listenerMap = goog.events.getListenerMap_(
        511 /** @type {EventTarget} */ (obj));
        512 if (!listenerMap) {
        513 return 0;
        514 }
        515
        516 var count = 0;
        517 var typeStr = opt_type && opt_type.toString();
        518 for (var type in listenerMap.listeners) {
        519 if (!typeStr || type == typeStr) {
        520 // Clone so that we don't need to worry about unlistenByKey
        521 // changing the content of the ListenerMap.
        522 var listeners = listenerMap.listeners[type].concat();
        523 for (var i = 0; i < listeners.length; ++i) {
        524 if (goog.events.unlistenByKey(listeners[i])) {
        525 ++count;
        526 }
        527 }
        528 }
        529 }
        530 return count;
        531};
        532
        533
        534/**
        535 * Removes all native listeners registered via goog.events. Native
        536 * listeners are listeners on native browser objects (such as DOM
        537 * elements). In particular, goog.events.Listenable and
        538 * goog.events.EventTarget listeners will NOT be removed.
        539 * @return {number} Number of listeners removed.
        540 * @deprecated This doesn't do anything, now that Closure no longer
        541 * stores a central listener registry.
        542 */
        543goog.events.removeAllNativeListeners = function() {
        544 goog.events.listenerCountEstimate_ = 0;
        545 return 0;
        546};
        547
        548
        549/**
        550 * Gets the listeners for a given object, type and capture phase.
        551 *
        552 * @param {Object} obj Object to get listeners for.
        553 * @param {string|!goog.events.EventId} type Event type.
        554 * @param {boolean} capture Capture phase?.
        555 * @return {Array.<goog.events.Listener>} Array of listener objects.
        556 */
        557goog.events.getListeners = function(obj, type, capture) {
        558 if (goog.events.Listenable.isImplementedBy(obj)) {
        559 return obj.getListeners(type, capture);
        560 } else {
        561 if (!obj) {
        562 // TODO(user): We should tighten the API to accept
        563 // !EventTarget|goog.events.Listenable, and add an assertion here.
        564 return [];
        565 }
        566
        567 var listenerMap = goog.events.getListenerMap_(
        568 /** @type {EventTarget} */ (obj));
        569 return listenerMap ? listenerMap.getListeners(type, capture) : [];
        570 }
        571};
        572
        573
        574/**
        575 * Gets the goog.events.Listener for the event or null if no such listener is
        576 * in use.
        577 *
        578 * @param {EventTarget|goog.events.Listenable} src The target from
        579 * which to get listeners.
        580 * @param {?string|!goog.events.EventId.<EVENTOBJ>} type The type of the event.
        581 * @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null} listener The
        582 * listener function to get.
        583 * @param {boolean=} opt_capt In DOM-compliant browsers, this determines
        584 * whether the listener is fired during the
        585 * capture or bubble phase of the event.
        586 * @param {Object=} opt_handler Element in whose scope to call the listener.
        587 * @return {goog.events.ListenableKey} the found listener or null if not found.
        588 * @template EVENTOBJ
        589 */
        590goog.events.getListener = function(src, type, listener, opt_capt, opt_handler) {
        591 // TODO(user): Change type from ?string to string, or add assertion.
        592 type = /** @type {string} */ (type);
        593 listener = goog.events.wrapListener(listener);
        594 var capture = !!opt_capt;
        595 if (goog.events.Listenable.isImplementedBy(src)) {
        596 return src.getListener(type, listener, capture, opt_handler);
        597 }
        598
        599 if (!src) {
        600 // TODO(user): We should tighten the API to only accept
        601 // non-null objects, or add an assertion here.
        602 return null;
        603 }
        604
        605 var listenerMap = goog.events.getListenerMap_(
        606 /** @type {EventTarget} */ (src));
        607 if (listenerMap) {
        608 return listenerMap.getListener(type, listener, capture, opt_handler);
        609 }
        610 return null;
        611};
        612
        613
        614/**
        615 * Returns whether an event target has any active listeners matching the
        616 * specified signature. If either the type or capture parameters are
        617 * unspecified, the function will match on the remaining criteria.
        618 *
        619 * @param {EventTarget|goog.events.Listenable} obj Target to get
        620 * listeners for.
        621 * @param {string|!goog.events.EventId=} opt_type Event type.
        622 * @param {boolean=} opt_capture Whether to check for capture or bubble-phase
        623 * listeners.
        624 * @return {boolean} Whether an event target has one or more listeners matching
        625 * the requested type and/or capture phase.
        626 */
        627goog.events.hasListener = function(obj, opt_type, opt_capture) {
        628 if (goog.events.Listenable.isImplementedBy(obj)) {
        629 return obj.hasListener(opt_type, opt_capture);
        630 }
        631
        632 var listenerMap = goog.events.getListenerMap_(
        633 /** @type {EventTarget} */ (obj));
        634 return !!listenerMap && listenerMap.hasListener(opt_type, opt_capture);
        635};
        636
        637
        638/**
        639 * Provides a nice string showing the normalized event objects public members
        640 * @param {Object} e Event Object.
        641 * @return {string} String of the public members of the normalized event object.
        642 */
        643goog.events.expose = function(e) {
        644 var str = [];
        645 for (var key in e) {
        646 if (e[key] && e[key].id) {
        647 str.push(key + ' = ' + e[key] + ' (' + e[key].id + ')');
        648 } else {
        649 str.push(key + ' = ' + e[key]);
        650 }
        651 }
        652 return str.join('\n');
        653};
        654
        655
        656/**
        657 * Returns a string with on prepended to the specified type. This is used for IE
        658 * which expects "on" to be prepended. This function caches the string in order
        659 * to avoid extra allocations in steady state.
        660 * @param {string} type Event type.
        661 * @return {string} The type string with 'on' prepended.
        662 * @private
        663 */
        664goog.events.getOnString_ = function(type) {
        665 if (type in goog.events.onStringMap_) {
        666 return goog.events.onStringMap_[type];
        667 }
        668 return goog.events.onStringMap_[type] = goog.events.onString_ + type;
        669};
        670
        671
        672/**
        673 * Fires an object's listeners of a particular type and phase
        674 *
        675 * @param {Object} obj Object whose listeners to call.
        676 * @param {string|!goog.events.EventId} type Event type.
        677 * @param {boolean} capture Which event phase.
        678 * @param {Object} eventObject Event object to be passed to listener.
        679 * @return {boolean} True if all listeners returned true else false.
        680 */
        681goog.events.fireListeners = function(obj, type, capture, eventObject) {
        682 if (goog.events.Listenable.isImplementedBy(obj)) {
        683 return obj.fireListeners(type, capture, eventObject);
        684 }
        685
        686 return goog.events.fireListeners_(obj, type, capture, eventObject);
        687};
        688
        689
        690/**
        691 * Fires an object's listeners of a particular type and phase.
        692 * @param {Object} obj Object whose listeners to call.
        693 * @param {string|!goog.events.EventId} type Event type.
        694 * @param {boolean} capture Which event phase.
        695 * @param {Object} eventObject Event object to be passed to listener.
        696 * @return {boolean} True if all listeners returned true else false.
        697 * @private
        698 */
        699goog.events.fireListeners_ = function(obj, type, capture, eventObject) {
        700 var retval = 1;
        701
        702 var listenerMap = goog.events.getListenerMap_(
        703 /** @type {EventTarget} */ (obj));
        704 if (listenerMap) {
        705 // TODO(user): Original code avoids array creation when there
        706 // is no listener, so we do the same. If this optimization turns
        707 // out to be not required, we can replace this with
        708 // listenerMap.getListeners(type, capture) instead, which is simpler.
        709 var listenerArray = listenerMap.listeners[type.toString()];
        710 if (listenerArray) {
        711 listenerArray = listenerArray.concat();
        712 for (var i = 0; i < listenerArray.length; i++) {
        713 var listener = listenerArray[i];
        714 // We might not have a listener if the listener was removed.
        715 if (listener && listener.capture == capture && !listener.removed) {
        716 retval &=
        717 goog.events.fireListener(listener, eventObject) !== false;
        718 }
        719 }
        720 }
        721 }
        722 return Boolean(retval);
        723};
        724
        725
        726/**
        727 * Fires a listener with a set of arguments
        728 *
        729 * @param {goog.events.Listener} listener The listener object to call.
        730 * @param {Object} eventObject The event object to pass to the listener.
        731 * @return {boolean} Result of listener.
        732 */
        733goog.events.fireListener = function(listener, eventObject) {
        734 var listenerFn = listener.listener;
        735 var listenerHandler = listener.handler || listener.src;
        736
        737 if (listener.callOnce) {
        738 goog.events.unlistenByKey(listener);
        739 }
        740 return listenerFn.call(listenerHandler, eventObject);
        741};
        742
        743
        744/**
        745 * Gets the total number of listeners currently in the system.
        746 * @return {number} Number of listeners.
        747 * @deprecated This returns estimated count, now that Closure no longer
        748 * stores a central listener registry. We still return an estimation
        749 * to keep existing listener-related tests passing. In the near future,
        750 * this function will be removed.
        751 */
        752goog.events.getTotalListenerCount = function() {
        753 return goog.events.listenerCountEstimate_;
        754};
        755
        756
        757/**
        758 * Dispatches an event (or event like object) and calls all listeners
        759 * listening for events of this type. The type of the event is decided by the
        760 * type property on the event object.
        761 *
        762 * If any of the listeners returns false OR calls preventDefault then this
        763 * function will return false. If one of the capture listeners calls
        764 * stopPropagation, then the bubble listeners won't fire.
        765 *
        766 * @param {goog.events.Listenable} src The event target.
        767 * @param {goog.events.EventLike} e Event object.
        768 * @return {boolean} If anyone called preventDefault on the event object (or
        769 * if any of the handlers returns false) this will also return false.
        770 * If there are no handlers, or if all handlers return true, this returns
        771 * true.
        772 */
        773goog.events.dispatchEvent = function(src, e) {
        774 goog.asserts.assert(
        775 goog.events.Listenable.isImplementedBy(src),
        776 'Can not use goog.events.dispatchEvent with ' +
        777 'non-goog.events.Listenable instance.');
        778 return src.dispatchEvent(e);
        779};
        780
        781
        782/**
        783 * Installs exception protection for the browser event entry point using the
        784 * given error handler.
        785 *
        786 * @param {goog.debug.ErrorHandler} errorHandler Error handler with which to
        787 * protect the entry point.
        788 */
        789goog.events.protectBrowserEventEntryPoint = function(errorHandler) {
        790 goog.events.handleBrowserEvent_ = errorHandler.protectEntryPoint(
        791 goog.events.handleBrowserEvent_);
        792};
        793
        794
        795/**
        796 * Handles an event and dispatches it to the correct listeners. This
        797 * function is a proxy for the real listener the user specified.
        798 *
        799 * @param {goog.events.Listener} listener The listener object.
        800 * @param {Event=} opt_evt Optional event object that gets passed in via the
        801 * native event handlers.
        802 * @return {boolean} Result of the event handler.
        803 * @this {EventTarget} The object or Element that fired the event.
        804 * @private
        805 */
        806goog.events.handleBrowserEvent_ = function(listener, opt_evt) {
        807 if (listener.removed) {
        808 return true;
        809 }
        810
        811 // Synthesize event propagation if the browser does not support W3C
        812 // event model.
        813 if (!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) {
        814 var ieEvent = opt_evt ||
        815 /** @type {Event} */ (goog.getObjectByName('window.event'));
        816 var evt = new goog.events.BrowserEvent(ieEvent, this);
        817 var retval = true;
        818
        819 if (goog.events.CAPTURE_SIMULATION_MODE ==
        820 goog.events.CaptureSimulationMode.ON) {
        821 // If we have not marked this event yet, we should perform capture
        822 // simulation.
        823 if (!goog.events.isMarkedIeEvent_(ieEvent)) {
        824 goog.events.markIeEvent_(ieEvent);
        825
        826 var ancestors = [];
        827 for (var parent = evt.currentTarget; parent;
        828 parent = parent.parentNode) {
        829 ancestors.push(parent);
        830 }
        831
        832 // Fire capture listeners.
        833 var type = listener.type;
        834 for (var i = ancestors.length - 1; !evt.propagationStopped_ && i >= 0;
        835 i--) {
        836 evt.currentTarget = ancestors[i];
        837 retval &= goog.events.fireListeners_(ancestors[i], type, true, evt);
        838 }
        839
        840 // Fire bubble listeners.
        841 //
        842 // We can technically rely on IE to perform bubble event
        843 // propagation. However, it turns out that IE fires events in
        844 // opposite order of attachEvent registration, which broke
        845 // some code and tests that rely on the order. (While W3C DOM
        846 // Level 2 Events TR leaves the event ordering unspecified,
        847 // modern browsers and W3C DOM Level 3 Events Working Draft
        848 // actually specify the order as the registration order.)
        849 for (var i = 0; !evt.propagationStopped_ && i < ancestors.length; i++) {
        850 evt.currentTarget = ancestors[i];
        851 retval &= goog.events.fireListeners_(ancestors[i], type, false, evt);
        852 }
        853 }
        854 } else {
        855 retval = goog.events.fireListener(listener, evt);
        856 }
        857 return retval;
        858 }
        859
        860 // Otherwise, simply fire the listener.
        861 return goog.events.fireListener(
        862 listener, new goog.events.BrowserEvent(opt_evt, this));
        863};
        864
        865
        866/**
        867 * This is used to mark the IE event object so we do not do the Closure pass
        868 * twice for a bubbling event.
        869 * @param {Event} e The IE browser event.
        870 * @private
        871 */
        872goog.events.markIeEvent_ = function(e) {
        873 // Only the keyCode and the returnValue can be changed. We use keyCode for
        874 // non keyboard events.
        875 // event.returnValue is a bit more tricky. It is undefined by default. A
        876 // boolean false prevents the default action. In a window.onbeforeunload and
        877 // the returnValue is non undefined it will be alerted. However, we will only
        878 // modify the returnValue for keyboard events. We can get a problem if non
        879 // closure events sets the keyCode or the returnValue
        880
        881 var useReturnValue = false;
        882
        883 if (e.keyCode == 0) {
        884 // We cannot change the keyCode in case that srcElement is input[type=file].
        885 // We could test that that is the case but that would allocate 3 objects.
        886 // If we use try/catch we will only allocate extra objects in the case of a
        887 // failure.
        888 /** @preserveTry */
        889 try {
        890 e.keyCode = -1;
        891 return;
        892 } catch (ex) {
        893 useReturnValue = true;
        894 }
        895 }
        896
        897 if (useReturnValue ||
        898 /** @type {boolean|undefined} */ (e.returnValue) == undefined) {
        899 e.returnValue = true;
        900 }
        901};
        902
        903
        904/**
        905 * This is used to check if an IE event has already been handled by the Closure
        906 * system so we do not do the Closure pass twice for a bubbling event.
        907 * @param {Event} e The IE browser event.
        908 * @return {boolean} True if the event object has been marked.
        909 * @private
        910 */
        911goog.events.isMarkedIeEvent_ = function(e) {
        912 return e.keyCode < 0 || e.returnValue != undefined;
        913};
        914
        915
        916/**
        917 * Counter to create unique event ids.
        918 * @private {number}
        919 */
        920goog.events.uniqueIdCounter_ = 0;
        921
        922
        923/**
        924 * Creates a unique event id.
        925 *
        926 * @param {string} identifier The identifier.
        927 * @return {string} A unique identifier.
        928 * @idGenerator
        929 */
        930goog.events.getUniqueId = function(identifier) {
        931 return identifier + '_' + goog.events.uniqueIdCounter_++;
        932};
        933
        934
        935/**
        936 * @param {EventTarget} src The source object.
        937 * @return {goog.events.ListenerMap} A listener map for the given
        938 * source object, or null if none exists.
        939 * @private
        940 */
        941goog.events.getListenerMap_ = function(src) {
        942 var listenerMap = src[goog.events.LISTENER_MAP_PROP_];
        943 // IE serializes the property as well (e.g. when serializing outer
        944 // HTML). So we must check that the value is of the correct type.
        945 return listenerMap instanceof goog.events.ListenerMap ? listenerMap : null;
        946};
        947
        948
        949/**
        950 * Expando property for listener function wrapper for Object with
        951 * handleEvent.
        952 * @private @const {string}
        953 */
        954goog.events.LISTENER_WRAPPER_PROP_ = '__closure_events_fn_' +
        955 ((Math.random() * 1e9) >>> 0);
        956
        957
        958/**
        959 * @param {Object|Function} listener The listener function or an
        960 * object that contains handleEvent method.
        961 * @return {!Function} Either the original function or a function that
        962 * calls obj.handleEvent. If the same listener is passed to this
        963 * function more than once, the same function is guaranteed to be
        964 * returned.
        965 */
        966goog.events.wrapListener = function(listener) {
        967 goog.asserts.assert(listener, 'Listener can not be null.');
        968
        969 if (goog.isFunction(listener)) {
        970 return listener;
        971 }
        972
        973 goog.asserts.assert(
        974 listener.handleEvent, 'An object listener must have handleEvent method.');
        975 if (!listener[goog.events.LISTENER_WRAPPER_PROP_]) {
        976 listener[goog.events.LISTENER_WRAPPER_PROP_] =
        977 function(e) { return listener.handleEvent(e); };
        978 }
        979 return listener[goog.events.LISTENER_WRAPPER_PROP_];
        980};
        981
        982
        983// Register the browser event handler as an entry point, so that
        984// it can be monitored for exception handling, etc.
        985goog.debug.entryPointRegistry.register(
        986 /**
        987 * @param {function(!Function): !Function} transformer The transforming
        988 * function.
        989 */
        990 function(transformer) {
        991 goog.events.handleBrowserEvent_ = transformer(
        992 goog.events.handleBrowserEvent_);
        993 });
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/events/eventtarget.js.src.html b/docs/api/javascript/source/lib/goog/events/eventtarget.js.src.html new file mode 100644 index 0000000000000..88ce69d931ac3 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/events/eventtarget.js.src.html @@ -0,0 +1 @@ +eventtarget.js

        lib/goog/events/eventtarget.js

        1// Copyright 2005 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 A disposable implementation of a custom
        17 * listenable/event target. See also: documentation for
        18 * {@code goog.events.Listenable}.
        19 *
        20 * @author arv@google.com (Erik Arvidsson) [Original implementation]
        21 * @author pupius@google.com (Daniel Pupius) [Port to use goog.events]
        22 * @see ../demos/eventtarget.html
        23 * @see goog.events.Listenable
        24 */
        25
        26goog.provide('goog.events.EventTarget');
        27
        28goog.require('goog.Disposable');
        29goog.require('goog.asserts');
        30goog.require('goog.events');
        31goog.require('goog.events.Event');
        32goog.require('goog.events.Listenable');
        33goog.require('goog.events.ListenerMap');
        34goog.require('goog.object');
        35
        36
        37
        38/**
        39 * An implementation of {@code goog.events.Listenable} with full W3C
        40 * EventTarget-like support (capture/bubble mechanism, stopping event
        41 * propagation, preventing default actions).
        42 *
        43 * You may subclass this class to turn your class into a Listenable.
        44 *
        45 * Unless propagation is stopped, an event dispatched by an
        46 * EventTarget will bubble to the parent returned by
        47 * {@code getParentEventTarget}. To set the parent, call
        48 * {@code setParentEventTarget}. Subclasses that don't support
        49 * changing the parent can override the setter to throw an error.
        50 *
        51 * Example usage:
        52 * <pre>
        53 * var source = new goog.events.EventTarget();
        54 * function handleEvent(e) {
        55 * alert('Type: ' + e.type + '; Target: ' + e.target);
        56 * }
        57 * source.listen('foo', handleEvent);
        58 * // Or: goog.events.listen(source, 'foo', handleEvent);
        59 * ...
        60 * source.dispatchEvent('foo'); // will call handleEvent
        61 * ...
        62 * source.unlisten('foo', handleEvent);
        63 * // Or: goog.events.unlisten(source, 'foo', handleEvent);
        64 * </pre>
        65 *
        66 * @constructor
        67 * @extends {goog.Disposable}
        68 * @implements {goog.events.Listenable}
        69 */
        70goog.events.EventTarget = function() {
        71 goog.Disposable.call(this);
        72
        73 /**
        74 * Maps of event type to an array of listeners.
        75 * @private {!goog.events.ListenerMap}
        76 */
        77 this.eventTargetListeners_ = new goog.events.ListenerMap(this);
        78
        79 /**
        80 * The object to use for event.target. Useful when mixing in an
        81 * EventTarget to another object.
        82 * @private {!Object}
        83 */
        84 this.actualEventTarget_ = this;
        85
        86 /**
        87 * Parent event target, used during event bubbling.
        88 *
        89 * TODO(user): Change this to goog.events.Listenable. This
        90 * currently breaks people who expect getParentEventTarget to return
        91 * goog.events.EventTarget.
        92 *
        93 * @private {goog.events.EventTarget}
        94 */
        95 this.parentEventTarget_ = null;
        96};
        97goog.inherits(goog.events.EventTarget, goog.Disposable);
        98goog.events.Listenable.addImplementation(goog.events.EventTarget);
        99
        100
        101/**
        102 * An artificial cap on the number of ancestors you can have. This is mainly
        103 * for loop detection.
        104 * @const {number}
        105 * @private
        106 */
        107goog.events.EventTarget.MAX_ANCESTORS_ = 1000;
        108
        109
        110/**
        111 * Returns the parent of this event target to use for bubbling.
        112 *
        113 * @return {goog.events.EventTarget} The parent EventTarget or null if
        114 * there is no parent.
        115 * @override
        116 */
        117goog.events.EventTarget.prototype.getParentEventTarget = function() {
        118 return this.parentEventTarget_;
        119};
        120
        121
        122/**
        123 * Sets the parent of this event target to use for capture/bubble
        124 * mechanism.
        125 * @param {goog.events.EventTarget} parent Parent listenable (null if none).
        126 */
        127goog.events.EventTarget.prototype.setParentEventTarget = function(parent) {
        128 this.parentEventTarget_ = parent;
        129};
        130
        131
        132/**
        133 * Adds an event listener to the event target. The same handler can only be
        134 * added once per the type. Even if you add the same handler multiple times
        135 * using the same type then it will only be called once when the event is
        136 * dispatched.
        137 *
        138 * @param {string} type The type of the event to listen for.
        139 * @param {function(?):?|{handleEvent:function(?):?}|null} handler The function
        140 * to handle the event. The handler can also be an object that implements
        141 * the handleEvent method which takes the event object as argument.
        142 * @param {boolean=} opt_capture In DOM-compliant browsers, this determines
        143 * whether the listener is fired during the capture or bubble phase
        144 * of the event.
        145 * @param {Object=} opt_handlerScope Object in whose scope to call
        146 * the listener.
        147 * @deprecated Use {@code #listen} instead, when possible. Otherwise, use
        148 * {@code goog.events.listen} if you are passing Object
        149 * (instead of Function) as handler.
        150 */
        151goog.events.EventTarget.prototype.addEventListener = function(
        152 type, handler, opt_capture, opt_handlerScope) {
        153 goog.events.listen(this, type, handler, opt_capture, opt_handlerScope);
        154};
        155
        156
        157/**
        158 * Removes an event listener from the event target. The handler must be the
        159 * same object as the one added. If the handler has not been added then
        160 * nothing is done.
        161 *
        162 * @param {string} type The type of the event to listen for.
        163 * @param {function(?):?|{handleEvent:function(?):?}|null} handler The function
        164 * to handle the event. The handler can also be an object that implements
        165 * the handleEvent method which takes the event object as argument.
        166 * @param {boolean=} opt_capture In DOM-compliant browsers, this determines
        167 * whether the listener is fired during the capture or bubble phase
        168 * of the event.
        169 * @param {Object=} opt_handlerScope Object in whose scope to call
        170 * the listener.
        171 * @deprecated Use {@code #unlisten} instead, when possible. Otherwise, use
        172 * {@code goog.events.unlisten} if you are passing Object
        173 * (instead of Function) as handler.
        174 */
        175goog.events.EventTarget.prototype.removeEventListener = function(
        176 type, handler, opt_capture, opt_handlerScope) {
        177 goog.events.unlisten(this, type, handler, opt_capture, opt_handlerScope);
        178};
        179
        180
        181/** @override */
        182goog.events.EventTarget.prototype.dispatchEvent = function(e) {
        183 this.assertInitialized_();
        184
        185 var ancestorsTree, ancestor = this.getParentEventTarget();
        186 if (ancestor) {
        187 ancestorsTree = [];
        188 var ancestorCount = 1;
        189 for (; ancestor; ancestor = ancestor.getParentEventTarget()) {
        190 ancestorsTree.push(ancestor);
        191 goog.asserts.assert(
        192 (++ancestorCount < goog.events.EventTarget.MAX_ANCESTORS_),
        193 'infinite loop');
        194 }
        195 }
        196
        197 return goog.events.EventTarget.dispatchEventInternal_(
        198 this.actualEventTarget_, e, ancestorsTree);
        199};
        200
        201
        202/**
        203 * Removes listeners from this object. Classes that extend EventTarget may
        204 * need to override this method in order to remove references to DOM Elements
        205 * and additional listeners.
        206 * @override
        207 */
        208goog.events.EventTarget.prototype.disposeInternal = function() {
        209 goog.events.EventTarget.superClass_.disposeInternal.call(this);
        210
        211 this.removeAllListeners();
        212 this.parentEventTarget_ = null;
        213};
        214
        215
        216/** @override */
        217goog.events.EventTarget.prototype.listen = function(
        218 type, listener, opt_useCapture, opt_listenerScope) {
        219 this.assertInitialized_();
        220 return this.eventTargetListeners_.add(
        221 String(type), listener, false /* callOnce */, opt_useCapture,
        222 opt_listenerScope);
        223};
        224
        225
        226/** @override */
        227goog.events.EventTarget.prototype.listenOnce = function(
        228 type, listener, opt_useCapture, opt_listenerScope) {
        229 return this.eventTargetListeners_.add(
        230 String(type), listener, true /* callOnce */, opt_useCapture,
        231 opt_listenerScope);
        232};
        233
        234
        235/** @override */
        236goog.events.EventTarget.prototype.unlisten = function(
        237 type, listener, opt_useCapture, opt_listenerScope) {
        238 return this.eventTargetListeners_.remove(
        239 String(type), listener, opt_useCapture, opt_listenerScope);
        240};
        241
        242
        243/** @override */
        244goog.events.EventTarget.prototype.unlistenByKey = function(key) {
        245 return this.eventTargetListeners_.removeByKey(key);
        246};
        247
        248
        249/** @override */
        250goog.events.EventTarget.prototype.removeAllListeners = function(opt_type) {
        251 // TODO(user): Previously, removeAllListeners can be called on
        252 // uninitialized EventTarget, so we preserve that behavior. We
        253 // should remove this when usages that rely on that fact are purged.
        254 if (!this.eventTargetListeners_) {
        255 return 0;
        256 }
        257 return this.eventTargetListeners_.removeAll(opt_type);
        258};
        259
        260
        261/** @override */
        262goog.events.EventTarget.prototype.fireListeners = function(
        263 type, capture, eventObject) {
        264 // TODO(user): Original code avoids array creation when there
        265 // is no listener, so we do the same. If this optimization turns
        266 // out to be not required, we can replace this with
        267 // getListeners(type, capture) instead, which is simpler.
        268 var listenerArray = this.eventTargetListeners_.listeners[String(type)];
        269 if (!listenerArray) {
        270 return true;
        271 }
        272 listenerArray = listenerArray.concat();
        273
        274 var rv = true;
        275 for (var i = 0; i < listenerArray.length; ++i) {
        276 var listener = listenerArray[i];
        277 // We might not have a listener if the listener was removed.
        278 if (listener && !listener.removed && listener.capture == capture) {
        279 var listenerFn = listener.listener;
        280 var listenerHandler = listener.handler || listener.src;
        281
        282 if (listener.callOnce) {
        283 this.unlistenByKey(listener);
        284 }
        285 rv = listenerFn.call(listenerHandler, eventObject) !== false && rv;
        286 }
        287 }
        288
        289 return rv && eventObject.returnValue_ != false;
        290};
        291
        292
        293/** @override */
        294goog.events.EventTarget.prototype.getListeners = function(type, capture) {
        295 return this.eventTargetListeners_.getListeners(String(type), capture);
        296};
        297
        298
        299/** @override */
        300goog.events.EventTarget.prototype.getListener = function(
        301 type, listener, capture, opt_listenerScope) {
        302 return this.eventTargetListeners_.getListener(
        303 String(type), listener, capture, opt_listenerScope);
        304};
        305
        306
        307/** @override */
        308goog.events.EventTarget.prototype.hasListener = function(
        309 opt_type, opt_capture) {
        310 var id = goog.isDef(opt_type) ? String(opt_type) : undefined;
        311 return this.eventTargetListeners_.hasListener(id, opt_capture);
        312};
        313
        314
        315/**
        316 * Sets the target to be used for {@code event.target} when firing
        317 * event. Mainly used for testing. For example, see
        318 * {@code goog.testing.events.mixinListenable}.
        319 * @param {!Object} target The target.
        320 */
        321goog.events.EventTarget.prototype.setTargetForTesting = function(target) {
        322 this.actualEventTarget_ = target;
        323};
        324
        325
        326/**
        327 * Asserts that the event target instance is initialized properly.
        328 * @private
        329 */
        330goog.events.EventTarget.prototype.assertInitialized_ = function() {
        331 goog.asserts.assert(
        332 this.eventTargetListeners_,
        333 'Event target is not initialized. Did you call the superclass ' +
        334 '(goog.events.EventTarget) constructor?');
        335};
        336
        337
        338/**
        339 * Dispatches the given event on the ancestorsTree.
        340 *
        341 * @param {!Object} target The target to dispatch on.
        342 * @param {goog.events.Event|Object|string} e The event object.
        343 * @param {Array.<goog.events.Listenable>=} opt_ancestorsTree The ancestors
        344 * tree of the target, in reverse order from the closest ancestor
        345 * to the root event target. May be null if the target has no ancestor.
        346 * @return {boolean} If anyone called preventDefault on the event object (or
        347 * if any of the listeners returns false) this will also return false.
        348 * @private
        349 */
        350goog.events.EventTarget.dispatchEventInternal_ = function(
        351 target, e, opt_ancestorsTree) {
        352 var type = e.type || /** @type {string} */ (e);
        353
        354 // If accepting a string or object, create a custom event object so that
        355 // preventDefault and stopPropagation work with the event.
        356 if (goog.isString(e)) {
        357 e = new goog.events.Event(e, target);
        358 } else if (!(e instanceof goog.events.Event)) {
        359 var oldEvent = e;
        360 e = new goog.events.Event(type, target);
        361 goog.object.extend(e, oldEvent);
        362 } else {
        363 e.target = e.target || target;
        364 }
        365
        366 var rv = true, currentTarget;
        367
        368 // Executes all capture listeners on the ancestors, if any.
        369 if (opt_ancestorsTree) {
        370 for (var i = opt_ancestorsTree.length - 1; !e.propagationStopped_ && i >= 0;
        371 i--) {
        372 currentTarget = e.currentTarget = opt_ancestorsTree[i];
        373 rv = currentTarget.fireListeners(type, true, e) && rv;
        374 }
        375 }
        376
        377 // Executes capture and bubble listeners on the target.
        378 if (!e.propagationStopped_) {
        379 currentTarget = e.currentTarget = target;
        380 rv = currentTarget.fireListeners(type, true, e) && rv;
        381 if (!e.propagationStopped_) {
        382 rv = currentTarget.fireListeners(type, false, e) && rv;
        383 }
        384 }
        385
        386 // Executes all bubble listeners on the ancestors, if any.
        387 if (opt_ancestorsTree) {
        388 for (i = 0; !e.propagationStopped_ && i < opt_ancestorsTree.length; i++) {
        389 currentTarget = e.currentTarget = opt_ancestorsTree[i];
        390 rv = currentTarget.fireListeners(type, false, e) && rv;
        391 }
        392 }
        393
        394 return rv;
        395};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/events/eventtype.js.src.html b/docs/api/javascript/source/lib/goog/events/eventtype.js.src.html new file mode 100644 index 0000000000000..6c9af2aa310f2 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/events/eventtype.js.src.html @@ -0,0 +1 @@ +eventtype.js

        lib/goog/events/eventtype.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 Event Types.
        17 *
        18 * @author arv@google.com (Erik Arvidsson)
        19 * @author mirkov@google.com (Mirko Visontai)
        20 */
        21
        22
        23goog.provide('goog.events.EventType');
        24
        25goog.require('goog.userAgent');
        26
        27
        28/**
        29 * Returns a prefixed event name for the current browser.
        30 * @param {string} eventName The name of the event.
        31 * @return {string} The prefixed event name.
        32 * @suppress {missingRequire|missingProvide}
        33 * @private
        34 */
        35goog.events.getVendorPrefixedName_ = function(eventName) {
        36 return goog.userAgent.WEBKIT ? 'webkit' + eventName :
        37 (goog.userAgent.OPERA ? 'o' + eventName.toLowerCase() :
        38 eventName.toLowerCase());
        39};
        40
        41
        42/**
        43 * Constants for event names.
        44 * @enum {string}
        45 */
        46goog.events.EventType = {
        47 // Mouse events
        48 CLICK: 'click',
        49 RIGHTCLICK: 'rightclick',
        50 DBLCLICK: 'dblclick',
        51 MOUSEDOWN: 'mousedown',
        52 MOUSEUP: 'mouseup',
        53 MOUSEOVER: 'mouseover',
        54 MOUSEOUT: 'mouseout',
        55 MOUSEMOVE: 'mousemove',
        56 MOUSEENTER: 'mouseenter',
        57 MOUSELEAVE: 'mouseleave',
        58 // Select start is non-standard.
        59 // See http://msdn.microsoft.com/en-us/library/ie/ms536969(v=vs.85).aspx.
        60 SELECTSTART: 'selectstart', // IE, Safari, Chrome
        61
        62 // Key events
        63 KEYPRESS: 'keypress',
        64 KEYDOWN: 'keydown',
        65 KEYUP: 'keyup',
        66
        67 // Focus
        68 BLUR: 'blur',
        69 FOCUS: 'focus',
        70 DEACTIVATE: 'deactivate', // IE only
        71 // NOTE: The following two events are not stable in cross-browser usage.
        72 // WebKit and Opera implement DOMFocusIn/Out.
        73 // IE implements focusin/out.
        74 // Gecko implements neither see bug at
        75 // https://bugzilla.mozilla.org/show_bug.cgi?id=396927.
        76 // The DOM Events Level 3 Draft deprecates DOMFocusIn in favor of focusin:
        77 // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html
        78 // You can use FOCUS in Capture phase until implementations converge.
        79 FOCUSIN: goog.userAgent.IE ? 'focusin' : 'DOMFocusIn',
        80 FOCUSOUT: goog.userAgent.IE ? 'focusout' : 'DOMFocusOut',
        81
        82 // Forms
        83 CHANGE: 'change',
        84 SELECT: 'select',
        85 SUBMIT: 'submit',
        86 INPUT: 'input',
        87 PROPERTYCHANGE: 'propertychange', // IE only
        88
        89 // Drag and drop
        90 DRAGSTART: 'dragstart',
        91 DRAG: 'drag',
        92 DRAGENTER: 'dragenter',
        93 DRAGOVER: 'dragover',
        94 DRAGLEAVE: 'dragleave',
        95 DROP: 'drop',
        96 DRAGEND: 'dragend',
        97
        98 // WebKit touch events.
        99 TOUCHSTART: 'touchstart',
        100 TOUCHMOVE: 'touchmove',
        101 TOUCHEND: 'touchend',
        102 TOUCHCANCEL: 'touchcancel',
        103
        104 // Misc
        105 BEFOREUNLOAD: 'beforeunload',
        106 CONSOLEMESSAGE: 'consolemessage',
        107 CONTEXTMENU: 'contextmenu',
        108 DOMCONTENTLOADED: 'DOMContentLoaded',
        109 ERROR: 'error',
        110 HELP: 'help',
        111 LOAD: 'load',
        112 LOSECAPTURE: 'losecapture',
        113 ORIENTATIONCHANGE: 'orientationchange',
        114 READYSTATECHANGE: 'readystatechange',
        115 RESIZE: 'resize',
        116 SCROLL: 'scroll',
        117 UNLOAD: 'unload',
        118
        119 // HTML 5 History events
        120 // See http://www.w3.org/TR/html5/history.html#event-definitions
        121 HASHCHANGE: 'hashchange',
        122 PAGEHIDE: 'pagehide',
        123 PAGESHOW: 'pageshow',
        124 POPSTATE: 'popstate',
        125
        126 // Copy and Paste
        127 // Support is limited. Make sure it works on your favorite browser
        128 // before using.
        129 // http://www.quirksmode.org/dom/events/cutcopypaste.html
        130 COPY: 'copy',
        131 PASTE: 'paste',
        132 CUT: 'cut',
        133 BEFORECOPY: 'beforecopy',
        134 BEFORECUT: 'beforecut',
        135 BEFOREPASTE: 'beforepaste',
        136
        137 // HTML5 online/offline events.
        138 // http://www.w3.org/TR/offline-webapps/#related
        139 ONLINE: 'online',
        140 OFFLINE: 'offline',
        141
        142 // HTML 5 worker events
        143 MESSAGE: 'message',
        144 CONNECT: 'connect',
        145
        146 // CSS animation events.
        147 /** @suppress {missingRequire} */
        148 ANIMATIONSTART: goog.events.getVendorPrefixedName_('AnimationStart'),
        149 /** @suppress {missingRequire} */
        150 ANIMATIONEND: goog.events.getVendorPrefixedName_('AnimationEnd'),
        151 /** @suppress {missingRequire} */
        152 ANIMATIONITERATION: goog.events.getVendorPrefixedName_('AnimationIteration'),
        153
        154 // CSS transition events. Based on the browser support described at:
        155 // https://developer.mozilla.org/en/css/css_transitions#Browser_compatibility
        156 /** @suppress {missingRequire} */
        157 TRANSITIONEND: goog.events.getVendorPrefixedName_('TransitionEnd'),
        158
        159 // W3C Pointer Events
        160 // http://www.w3.org/TR/pointerevents/
        161 POINTERDOWN: 'pointerdown',
        162 POINTERUP: 'pointerup',
        163 POINTERCANCEL: 'pointercancel',
        164 POINTERMOVE: 'pointermove',
        165 POINTEROVER: 'pointerover',
        166 POINTEROUT: 'pointerout',
        167 POINTERENTER: 'pointerenter',
        168 POINTERLEAVE: 'pointerleave',
        169 GOTPOINTERCAPTURE: 'gotpointercapture',
        170 LOSTPOINTERCAPTURE: 'lostpointercapture',
        171
        172 // IE specific events.
        173 // See http://msdn.microsoft.com/en-us/library/ie/hh772103(v=vs.85).aspx
        174 // Note: these events will be supplanted in IE11.
        175 MSGESTURECHANGE: 'MSGestureChange',
        176 MSGESTUREEND: 'MSGestureEnd',
        177 MSGESTUREHOLD: 'MSGestureHold',
        178 MSGESTURESTART: 'MSGestureStart',
        179 MSGESTURETAP: 'MSGestureTap',
        180 MSGOTPOINTERCAPTURE: 'MSGotPointerCapture',
        181 MSINERTIASTART: 'MSInertiaStart',
        182 MSLOSTPOINTERCAPTURE: 'MSLostPointerCapture',
        183 MSPOINTERCANCEL: 'MSPointerCancel',
        184 MSPOINTERDOWN: 'MSPointerDown',
        185 MSPOINTERENTER: 'MSPointerEnter',
        186 MSPOINTERHOVER: 'MSPointerHover',
        187 MSPOINTERLEAVE: 'MSPointerLeave',
        188 MSPOINTERMOVE: 'MSPointerMove',
        189 MSPOINTEROUT: 'MSPointerOut',
        190 MSPOINTEROVER: 'MSPointerOver',
        191 MSPOINTERUP: 'MSPointerUp',
        192
        193 // Native IMEs/input tools events.
        194 TEXTINPUT: 'textinput',
        195 COMPOSITIONSTART: 'compositionstart',
        196 COMPOSITIONUPDATE: 'compositionupdate',
        197 COMPOSITIONEND: 'compositionend',
        198
        199 // Webview tag events
        200 // See http://developer.chrome.com/dev/apps/webview_tag.html
        201 EXIT: 'exit',
        202 LOADABORT: 'loadabort',
        203 LOADCOMMIT: 'loadcommit',
        204 LOADREDIRECT: 'loadredirect',
        205 LOADSTART: 'loadstart',
        206 LOADSTOP: 'loadstop',
        207 RESPONSIVE: 'responsive',
        208 SIZECHANGED: 'sizechanged',
        209 UNRESPONSIVE: 'unresponsive',
        210
        211 // HTML5 Page Visibility API. See details at
        212 // {@code goog.labs.dom.PageVisibilityMonitor}.
        213 VISIBILITYCHANGE: 'visibilitychange',
        214
        215 // LocalStorage event.
        216 STORAGE: 'storage',
        217
        218 // DOM Level 2 mutation events (deprecated).
        219 DOMSUBTREEMODIFIED: 'DOMSubtreeModified',
        220 DOMNODEINSERTED: 'DOMNodeInserted',
        221 DOMNODEREMOVED: 'DOMNodeRemoved',
        222 DOMNODEREMOVEDFROMDOCUMENT: 'DOMNodeRemovedFromDocument',
        223 DOMNODEINSERTEDINTODOCUMENT: 'DOMNodeInsertedIntoDocument',
        224 DOMATTRMODIFIED: 'DOMAttrModified',
        225 DOMCHARACTERDATAMODIFIED: 'DOMCharacterDataModified'
        226};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/events/keycodes.js.src.html b/docs/api/javascript/source/lib/goog/events/keycodes.js.src.html new file mode 100644 index 0000000000000..71f59def1fa13 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/events/keycodes.js.src.html @@ -0,0 +1 @@ +keycodes.js

        lib/goog/events/keycodes.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 Constant declarations for common key codes.
        17 *
        18 * @author eae@google.com (Emil A Eklund)
        19 * @see ../demos/keyhandler.html
        20 */
        21
        22goog.provide('goog.events.KeyCodes');
        23
        24goog.require('goog.userAgent');
        25
        26
        27/**
        28 * Key codes for common characters.
        29 *
        30 * This list is not localized and therefore some of the key codes are not
        31 * correct for non US keyboard layouts. See comments below.
        32 *
        33 * @enum {number}
        34 */
        35goog.events.KeyCodes = {
        36 WIN_KEY_FF_LINUX: 0,
        37 MAC_ENTER: 3,
        38 BACKSPACE: 8,
        39 TAB: 9,
        40 NUM_CENTER: 12, // NUMLOCK on FF/Safari Mac
        41 ENTER: 13,
        42 SHIFT: 16,
        43 CTRL: 17,
        44 ALT: 18,
        45 PAUSE: 19,
        46 CAPS_LOCK: 20,
        47 ESC: 27,
        48 SPACE: 32,
        49 PAGE_UP: 33, // also NUM_NORTH_EAST
        50 PAGE_DOWN: 34, // also NUM_SOUTH_EAST
        51 END: 35, // also NUM_SOUTH_WEST
        52 HOME: 36, // also NUM_NORTH_WEST
        53 LEFT: 37, // also NUM_WEST
        54 UP: 38, // also NUM_NORTH
        55 RIGHT: 39, // also NUM_EAST
        56 DOWN: 40, // also NUM_SOUTH
        57 PRINT_SCREEN: 44,
        58 INSERT: 45, // also NUM_INSERT
        59 DELETE: 46, // also NUM_DELETE
        60 ZERO: 48,
        61 ONE: 49,
        62 TWO: 50,
        63 THREE: 51,
        64 FOUR: 52,
        65 FIVE: 53,
        66 SIX: 54,
        67 SEVEN: 55,
        68 EIGHT: 56,
        69 NINE: 57,
        70 FF_SEMICOLON: 59, // Firefox (Gecko) fires this for semicolon instead of 186
        71 FF_EQUALS: 61, // Firefox (Gecko) fires this for equals instead of 187
        72 FF_DASH: 173, // Firefox (Gecko) fires this for dash instead of 189
        73 QUESTION_MARK: 63, // needs localization
        74 A: 65,
        75 B: 66,
        76 C: 67,
        77 D: 68,
        78 E: 69,
        79 F: 70,
        80 G: 71,
        81 H: 72,
        82 I: 73,
        83 J: 74,
        84 K: 75,
        85 L: 76,
        86 M: 77,
        87 N: 78,
        88 O: 79,
        89 P: 80,
        90 Q: 81,
        91 R: 82,
        92 S: 83,
        93 T: 84,
        94 U: 85,
        95 V: 86,
        96 W: 87,
        97 X: 88,
        98 Y: 89,
        99 Z: 90,
        100 META: 91, // WIN_KEY_LEFT
        101 WIN_KEY_RIGHT: 92,
        102 CONTEXT_MENU: 93,
        103 NUM_ZERO: 96,
        104 NUM_ONE: 97,
        105 NUM_TWO: 98,
        106 NUM_THREE: 99,
        107 NUM_FOUR: 100,
        108 NUM_FIVE: 101,
        109 NUM_SIX: 102,
        110 NUM_SEVEN: 103,
        111 NUM_EIGHT: 104,
        112 NUM_NINE: 105,
        113 NUM_MULTIPLY: 106,
        114 NUM_PLUS: 107,
        115 NUM_MINUS: 109,
        116 NUM_PERIOD: 110,
        117 NUM_DIVISION: 111,
        118 F1: 112,
        119 F2: 113,
        120 F3: 114,
        121 F4: 115,
        122 F5: 116,
        123 F6: 117,
        124 F7: 118,
        125 F8: 119,
        126 F9: 120,
        127 F10: 121,
        128 F11: 122,
        129 F12: 123,
        130 NUMLOCK: 144,
        131 SCROLL_LOCK: 145,
        132
        133 // OS-specific media keys like volume controls and browser controls.
        134 FIRST_MEDIA_KEY: 166,
        135 LAST_MEDIA_KEY: 183,
        136
        137 SEMICOLON: 186, // needs localization
        138 DASH: 189, // needs localization
        139 EQUALS: 187, // needs localization
        140 COMMA: 188, // needs localization
        141 PERIOD: 190, // needs localization
        142 SLASH: 191, // needs localization
        143 APOSTROPHE: 192, // needs localization
        144 TILDE: 192, // needs localization
        145 SINGLE_QUOTE: 222, // needs localization
        146 OPEN_SQUARE_BRACKET: 219, // needs localization
        147 BACKSLASH: 220, // needs localization
        148 CLOSE_SQUARE_BRACKET: 221, // needs localization
        149 WIN_KEY: 224,
        150 MAC_FF_META: 224, // Firefox (Gecko) fires this for the meta key instead of 91
        151 MAC_WK_CMD_LEFT: 91, // WebKit Left Command key fired, same as META
        152 MAC_WK_CMD_RIGHT: 93, // WebKit Right Command key fired, different from META
        153 WIN_IME: 229,
        154
        155 // We've seen users whose machines fire this keycode at regular one
        156 // second intervals. The common thread among these users is that
        157 // they're all using Dell Inspiron laptops, so we suspect that this
        158 // indicates a hardware/bios problem.
        159 // http://en.community.dell.com/support-forums/laptop/f/3518/p/19285957/19523128.aspx
        160 PHANTOM: 255
        161};
        162
        163
        164/**
        165 * Returns true if the event contains a text modifying key.
        166 * @param {goog.events.BrowserEvent} e A key event.
        167 * @return {boolean} Whether it's a text modifying key.
        168 */
        169goog.events.KeyCodes.isTextModifyingKeyEvent = function(e) {
        170 if (e.altKey && !e.ctrlKey ||
        171 e.metaKey ||
        172 // Function keys don't generate text
        173 e.keyCode >= goog.events.KeyCodes.F1 &&
        174 e.keyCode <= goog.events.KeyCodes.F12) {
        175 return false;
        176 }
        177
        178 // The following keys are quite harmless, even in combination with
        179 // CTRL, ALT or SHIFT.
        180 switch (e.keyCode) {
        181 case goog.events.KeyCodes.ALT:
        182 case goog.events.KeyCodes.CAPS_LOCK:
        183 case goog.events.KeyCodes.CONTEXT_MENU:
        184 case goog.events.KeyCodes.CTRL:
        185 case goog.events.KeyCodes.DOWN:
        186 case goog.events.KeyCodes.END:
        187 case goog.events.KeyCodes.ESC:
        188 case goog.events.KeyCodes.HOME:
        189 case goog.events.KeyCodes.INSERT:
        190 case goog.events.KeyCodes.LEFT:
        191 case goog.events.KeyCodes.MAC_FF_META:
        192 case goog.events.KeyCodes.META:
        193 case goog.events.KeyCodes.NUMLOCK:
        194 case goog.events.KeyCodes.NUM_CENTER:
        195 case goog.events.KeyCodes.PAGE_DOWN:
        196 case goog.events.KeyCodes.PAGE_UP:
        197 case goog.events.KeyCodes.PAUSE:
        198 case goog.events.KeyCodes.PHANTOM:
        199 case goog.events.KeyCodes.PRINT_SCREEN:
        200 case goog.events.KeyCodes.RIGHT:
        201 case goog.events.KeyCodes.SCROLL_LOCK:
        202 case goog.events.KeyCodes.SHIFT:
        203 case goog.events.KeyCodes.UP:
        204 case goog.events.KeyCodes.WIN_KEY:
        205 case goog.events.KeyCodes.WIN_KEY_RIGHT:
        206 return false;
        207 case goog.events.KeyCodes.WIN_KEY_FF_LINUX:
        208 return !goog.userAgent.GECKO;
        209 default:
        210 return e.keyCode < goog.events.KeyCodes.FIRST_MEDIA_KEY ||
        211 e.keyCode > goog.events.KeyCodes.LAST_MEDIA_KEY;
        212 }
        213};
        214
        215
        216/**
        217 * Returns true if the key fires a keypress event in the current browser.
        218 *
        219 * Accoridng to MSDN [1] IE only fires keypress events for the following keys:
        220 * - Letters: A - Z (uppercase and lowercase)
        221 * - Numerals: 0 - 9
        222 * - Symbols: ! @ # $ % ^ & * ( ) _ - + = < [ ] { } , . / ? \ | ' ` " ~
        223 * - System: ESC, SPACEBAR, ENTER
        224 *
        225 * That's not entirely correct though, for instance there's no distinction
        226 * between upper and lower case letters.
        227 *
        228 * [1] http://msdn2.microsoft.com/en-us/library/ms536939(VS.85).aspx)
        229 *
        230 * Safari is similar to IE, but does not fire keypress for ESC.
        231 *
        232 * Additionally, IE6 does not fire keydown or keypress events for letters when
        233 * the control or alt keys are held down and the shift key is not. IE7 does
        234 * fire keydown in these cases, though, but not keypress.
        235 *
        236 * @param {number} keyCode A key code.
        237 * @param {number=} opt_heldKeyCode Key code of a currently-held key.
        238 * @param {boolean=} opt_shiftKey Whether the shift key is held down.
        239 * @param {boolean=} opt_ctrlKey Whether the control key is held down.
        240 * @param {boolean=} opt_altKey Whether the alt key is held down.
        241 * @return {boolean} Whether it's a key that fires a keypress event.
        242 */
        243goog.events.KeyCodes.firesKeyPressEvent = function(keyCode, opt_heldKeyCode,
        244 opt_shiftKey, opt_ctrlKey, opt_altKey) {
        245 if (!goog.userAgent.IE &&
        246 !(goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('525'))) {
        247 return true;
        248 }
        249
        250 if (goog.userAgent.MAC && opt_altKey) {
        251 return goog.events.KeyCodes.isCharacterKey(keyCode);
        252 }
        253
        254 // Alt but not AltGr which is represented as Alt+Ctrl.
        255 if (opt_altKey && !opt_ctrlKey) {
        256 return false;
        257 }
        258
        259 // Saves Ctrl or Alt + key for IE and WebKit 525+, which won't fire keypress.
        260 // Non-IE browsers and WebKit prior to 525 won't get this far so no need to
        261 // check the user agent.
        262 if (goog.isNumber(opt_heldKeyCode)) {
        263 opt_heldKeyCode = goog.events.KeyCodes.normalizeKeyCode(opt_heldKeyCode);
        264 }
        265 if (!opt_shiftKey &&
        266 (opt_heldKeyCode == goog.events.KeyCodes.CTRL ||
        267 opt_heldKeyCode == goog.events.KeyCodes.ALT ||
        268 goog.userAgent.MAC &&
        269 opt_heldKeyCode == goog.events.KeyCodes.META)) {
        270 return false;
        271 }
        272
        273 // Some keys with Ctrl/Shift do not issue keypress in WEBKIT.
        274 if (goog.userAgent.WEBKIT && opt_ctrlKey && opt_shiftKey) {
        275 switch (keyCode) {
        276 case goog.events.KeyCodes.BACKSLASH:
        277 case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:
        278 case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:
        279 case goog.events.KeyCodes.TILDE:
        280 case goog.events.KeyCodes.SEMICOLON:
        281 case goog.events.KeyCodes.DASH:
        282 case goog.events.KeyCodes.EQUALS:
        283 case goog.events.KeyCodes.COMMA:
        284 case goog.events.KeyCodes.PERIOD:
        285 case goog.events.KeyCodes.SLASH:
        286 case goog.events.KeyCodes.APOSTROPHE:
        287 case goog.events.KeyCodes.SINGLE_QUOTE:
        288 return false;
        289 }
        290 }
        291
        292 // When Ctrl+<somekey> is held in IE, it only fires a keypress once, but it
        293 // continues to fire keydown events as the event repeats.
        294 if (goog.userAgent.IE && opt_ctrlKey && opt_heldKeyCode == keyCode) {
        295 return false;
        296 }
        297
        298 switch (keyCode) {
        299 case goog.events.KeyCodes.ENTER:
        300 return true;
        301 case goog.events.KeyCodes.ESC:
        302 return !goog.userAgent.WEBKIT;
        303 }
        304
        305 return goog.events.KeyCodes.isCharacterKey(keyCode);
        306};
        307
        308
        309/**
        310 * Returns true if the key produces a character.
        311 * This does not cover characters on non-US keyboards (Russian, Hebrew, etc.).
        312 *
        313 * @param {number} keyCode A key code.
        314 * @return {boolean} Whether it's a character key.
        315 */
        316goog.events.KeyCodes.isCharacterKey = function(keyCode) {
        317 if (keyCode >= goog.events.KeyCodes.ZERO &&
        318 keyCode <= goog.events.KeyCodes.NINE) {
        319 return true;
        320 }
        321
        322 if (keyCode >= goog.events.KeyCodes.NUM_ZERO &&
        323 keyCode <= goog.events.KeyCodes.NUM_MULTIPLY) {
        324 return true;
        325 }
        326
        327 if (keyCode >= goog.events.KeyCodes.A &&
        328 keyCode <= goog.events.KeyCodes.Z) {
        329 return true;
        330 }
        331
        332 // Safari sends zero key code for non-latin characters.
        333 if (goog.userAgent.WEBKIT && keyCode == 0) {
        334 return true;
        335 }
        336
        337 switch (keyCode) {
        338 case goog.events.KeyCodes.SPACE:
        339 case goog.events.KeyCodes.QUESTION_MARK:
        340 case goog.events.KeyCodes.NUM_PLUS:
        341 case goog.events.KeyCodes.NUM_MINUS:
        342 case goog.events.KeyCodes.NUM_PERIOD:
        343 case goog.events.KeyCodes.NUM_DIVISION:
        344 case goog.events.KeyCodes.SEMICOLON:
        345 case goog.events.KeyCodes.FF_SEMICOLON:
        346 case goog.events.KeyCodes.DASH:
        347 case goog.events.KeyCodes.EQUALS:
        348 case goog.events.KeyCodes.FF_EQUALS:
        349 case goog.events.KeyCodes.COMMA:
        350 case goog.events.KeyCodes.PERIOD:
        351 case goog.events.KeyCodes.SLASH:
        352 case goog.events.KeyCodes.APOSTROPHE:
        353 case goog.events.KeyCodes.SINGLE_QUOTE:
        354 case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:
        355 case goog.events.KeyCodes.BACKSLASH:
        356 case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:
        357 return true;
        358 default:
        359 return false;
        360 }
        361};
        362
        363
        364/**
        365 * Normalizes key codes from OS/Browser-specific value to the general one.
        366 * @param {number} keyCode The native key code.
        367 * @return {number} The normalized key code.
        368 */
        369goog.events.KeyCodes.normalizeKeyCode = function(keyCode) {
        370 if (goog.userAgent.GECKO) {
        371 return goog.events.KeyCodes.normalizeGeckoKeyCode(keyCode);
        372 } else if (goog.userAgent.MAC && goog.userAgent.WEBKIT) {
        373 return goog.events.KeyCodes.normalizeMacWebKitKeyCode(keyCode);
        374 } else {
        375 return keyCode;
        376 }
        377};
        378
        379
        380/**
        381 * Normalizes key codes from their Gecko-specific value to the general one.
        382 * @param {number} keyCode The native key code.
        383 * @return {number} The normalized key code.
        384 */
        385goog.events.KeyCodes.normalizeGeckoKeyCode = function(keyCode) {
        386 switch (keyCode) {
        387 case goog.events.KeyCodes.FF_EQUALS:
        388 return goog.events.KeyCodes.EQUALS;
        389 case goog.events.KeyCodes.FF_SEMICOLON:
        390 return goog.events.KeyCodes.SEMICOLON;
        391 case goog.events.KeyCodes.FF_DASH:
        392 return goog.events.KeyCodes.DASH;
        393 case goog.events.KeyCodes.MAC_FF_META:
        394 return goog.events.KeyCodes.META;
        395 case goog.events.KeyCodes.WIN_KEY_FF_LINUX:
        396 return goog.events.KeyCodes.WIN_KEY;
        397 default:
        398 return keyCode;
        399 }
        400};
        401
        402
        403/**
        404 * Normalizes key codes from their Mac WebKit-specific value to the general one.
        405 * @param {number} keyCode The native key code.
        406 * @return {number} The normalized key code.
        407 */
        408goog.events.KeyCodes.normalizeMacWebKitKeyCode = function(keyCode) {
        409 switch (keyCode) {
        410 case goog.events.KeyCodes.MAC_WK_CMD_RIGHT: // 93
        411 return goog.events.KeyCodes.META; // 91
        412 default:
        413 return keyCode;
        414 }
        415};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/events/listenable.js.src.html b/docs/api/javascript/source/lib/goog/events/listenable.js.src.html new file mode 100644 index 0000000000000..b4c178df3f75b --- /dev/null +++ b/docs/api/javascript/source/lib/goog/events/listenable.js.src.html @@ -0,0 +1 @@ +listenable.js

        lib/goog/events/listenable.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 An interface for a listenable JavaScript object.
        17 */
        18
        19goog.provide('goog.events.Listenable');
        20goog.provide('goog.events.ListenableKey');
        21
        22/** @suppress {extraRequire} */
        23goog.require('goog.events.EventId');
        24
        25
        26
        27/**
        28 * A listenable interface. A listenable is an object with the ability
        29 * to dispatch/broadcast events to "event listeners" registered via
        30 * listen/listenOnce.
        31 *
        32 * The interface allows for an event propagation mechanism similar
        33 * to one offered by native browser event targets, such as
        34 * capture/bubble mechanism, stopping propagation, and preventing
        35 * default actions. Capture/bubble mechanism depends on the ancestor
        36 * tree constructed via {@code #getParentEventTarget}; this tree
        37 * must be directed acyclic graph. The meaning of default action(s)
        38 * in preventDefault is specific to a particular use case.
        39 *
        40 * Implementations that do not support capture/bubble or can not have
        41 * a parent listenable can simply not implement any ability to set the
        42 * parent listenable (and have {@code #getParentEventTarget} return
        43 * null).
        44 *
        45 * Implementation of this class can be used with or independently from
        46 * goog.events.
        47 *
        48 * Implementation must call {@code #addImplementation(implClass)}.
        49 *
        50 * @interface
        51 * @see goog.events
        52 * @see http://www.w3.org/TR/DOM-Level-2-Events/events.html
        53 */
        54goog.events.Listenable = function() {};
        55
        56
        57/**
        58 * An expando property to indicate that an object implements
        59 * goog.events.Listenable.
        60 *
        61 * See addImplementation/isImplementedBy.
        62 *
        63 * @type {string}
        64 * @const
        65 */
        66goog.events.Listenable.IMPLEMENTED_BY_PROP =
        67 'closure_listenable_' + ((Math.random() * 1e6) | 0);
        68
        69
        70/**
        71 * Marks a given class (constructor) as an implementation of
        72 * Listenable, do that we can query that fact at runtime. The class
        73 * must have already implemented the interface.
        74 * @param {!Function} cls The class constructor. The corresponding
        75 * class must have already implemented the interface.
        76 */
        77goog.events.Listenable.addImplementation = function(cls) {
        78 cls.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP] = true;
        79};
        80
        81
        82/**
        83 * @param {Object} obj The object to check.
        84 * @return {boolean} Whether a given instance implements Listenable. The
        85 * class/superclass of the instance must call addImplementation.
        86 */
        87goog.events.Listenable.isImplementedBy = function(obj) {
        88 return !!(obj && obj[goog.events.Listenable.IMPLEMENTED_BY_PROP]);
        89};
        90
        91
        92/**
        93 * Adds an event listener. A listener can only be added once to an
        94 * object and if it is added again the key for the listener is
        95 * returned. Note that if the existing listener is a one-off listener
        96 * (registered via listenOnce), it will no longer be a one-off
        97 * listener after a call to listen().
        98 *
        99 * @param {string|!goog.events.EventId.<EVENTOBJ>} type The event type id.
        100 * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback
        101 * method.
        102 * @param {boolean=} opt_useCapture Whether to fire in capture phase
        103 * (defaults to false).
        104 * @param {SCOPE=} opt_listenerScope Object in whose scope to call the
        105 * listener.
        106 * @return {goog.events.ListenableKey} Unique key for the listener.
        107 * @template SCOPE,EVENTOBJ
        108 */
        109goog.events.Listenable.prototype.listen;
        110
        111
        112/**
        113 * Adds an event listener that is removed automatically after the
        114 * listener fired once.
        115 *
        116 * If an existing listener already exists, listenOnce will do
        117 * nothing. In particular, if the listener was previously registered
        118 * via listen(), listenOnce() will not turn the listener into a
        119 * one-off listener. Similarly, if there is already an existing
        120 * one-off listener, listenOnce does not modify the listeners (it is
        121 * still a once listener).
        122 *
        123 * @param {string|!goog.events.EventId.<EVENTOBJ>} type The event type id.
        124 * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback
        125 * method.
        126 * @param {boolean=} opt_useCapture Whether to fire in capture phase
        127 * (defaults to false).
        128 * @param {SCOPE=} opt_listenerScope Object in whose scope to call the
        129 * listener.
        130 * @return {goog.events.ListenableKey} Unique key for the listener.
        131 * @template SCOPE,EVENTOBJ
        132 */
        133goog.events.Listenable.prototype.listenOnce;
        134
        135
        136/**
        137 * Removes an event listener which was added with listen() or listenOnce().
        138 *
        139 * @param {string|!goog.events.EventId.<EVENTOBJ>} type The event type id.
        140 * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback
        141 * method.
        142 * @param {boolean=} opt_useCapture Whether to fire in capture phase
        143 * (defaults to false).
        144 * @param {SCOPE=} opt_listenerScope Object in whose scope to call
        145 * the listener.
        146 * @return {boolean} Whether any listener was removed.
        147 * @template SCOPE,EVENTOBJ
        148 */
        149goog.events.Listenable.prototype.unlisten;
        150
        151
        152/**
        153 * Removes an event listener which was added with listen() by the key
        154 * returned by listen().
        155 *
        156 * @param {goog.events.ListenableKey} key The key returned by
        157 * listen() or listenOnce().
        158 * @return {boolean} Whether any listener was removed.
        159 */
        160goog.events.Listenable.prototype.unlistenByKey;
        161
        162
        163/**
        164 * Dispatches an event (or event like object) and calls all listeners
        165 * listening for events of this type. The type of the event is decided by the
        166 * type property on the event object.
        167 *
        168 * If any of the listeners returns false OR calls preventDefault then this
        169 * function will return false. If one of the capture listeners calls
        170 * stopPropagation, then the bubble listeners won't fire.
        171 *
        172 * @param {goog.events.EventLike} e Event object.
        173 * @return {boolean} If anyone called preventDefault on the event object (or
        174 * if any of the listeners returns false) this will also return false.
        175 */
        176goog.events.Listenable.prototype.dispatchEvent;
        177
        178
        179/**
        180 * Removes all listeners from this listenable. If type is specified,
        181 * it will only remove listeners of the particular type. otherwise all
        182 * registered listeners will be removed.
        183 *
        184 * @param {string=} opt_type Type of event to remove, default is to
        185 * remove all types.
        186 * @return {number} Number of listeners removed.
        187 */
        188goog.events.Listenable.prototype.removeAllListeners;
        189
        190
        191/**
        192 * Returns the parent of this event target to use for capture/bubble
        193 * mechanism.
        194 *
        195 * NOTE(user): The name reflects the original implementation of
        196 * custom event target ({@code goog.events.EventTarget}). We decided
        197 * that changing the name is not worth it.
        198 *
        199 * @return {goog.events.Listenable} The parent EventTarget or null if
        200 * there is no parent.
        201 */
        202goog.events.Listenable.prototype.getParentEventTarget;
        203
        204
        205/**
        206 * Fires all registered listeners in this listenable for the given
        207 * type and capture mode, passing them the given eventObject. This
        208 * does not perform actual capture/bubble. Only implementors of the
        209 * interface should be using this.
        210 *
        211 * @param {string|!goog.events.EventId.<EVENTOBJ>} type The type of the
        212 * listeners to fire.
        213 * @param {boolean} capture The capture mode of the listeners to fire.
        214 * @param {EVENTOBJ} eventObject The event object to fire.
        215 * @return {boolean} Whether all listeners succeeded without
        216 * attempting to prevent default behavior. If any listener returns
        217 * false or called goog.events.Event#preventDefault, this returns
        218 * false.
        219 * @template EVENTOBJ
        220 */
        221goog.events.Listenable.prototype.fireListeners;
        222
        223
        224/**
        225 * Gets all listeners in this listenable for the given type and
        226 * capture mode.
        227 *
        228 * @param {string|!goog.events.EventId} type The type of the listeners to fire.
        229 * @param {boolean} capture The capture mode of the listeners to fire.
        230 * @return {!Array.<goog.events.ListenableKey>} An array of registered
        231 * listeners.
        232 * @template EVENTOBJ
        233 */
        234goog.events.Listenable.prototype.getListeners;
        235
        236
        237/**
        238 * Gets the goog.events.ListenableKey for the event or null if no such
        239 * listener is in use.
        240 *
        241 * @param {string|!goog.events.EventId.<EVENTOBJ>} type The name of the event
        242 * without the 'on' prefix.
        243 * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener The
        244 * listener function to get.
        245 * @param {boolean} capture Whether the listener is a capturing listener.
        246 * @param {SCOPE=} opt_listenerScope Object in whose scope to call the
        247 * listener.
        248 * @return {goog.events.ListenableKey} the found listener or null if not found.
        249 * @template SCOPE,EVENTOBJ
        250 */
        251goog.events.Listenable.prototype.getListener;
        252
        253
        254/**
        255 * Whether there is any active listeners matching the specified
        256 * signature. If either the type or capture parameters are
        257 * unspecified, the function will match on the remaining criteria.
        258 *
        259 * @param {string|!goog.events.EventId.<EVENTOBJ>=} opt_type Event type.
        260 * @param {boolean=} opt_capture Whether to check for capture or bubble
        261 * listeners.
        262 * @return {boolean} Whether there is any active listeners matching
        263 * the requested type and/or capture phase.
        264 * @template EVENTOBJ
        265 */
        266goog.events.Listenable.prototype.hasListener;
        267
        268
        269
        270/**
        271 * An interface that describes a single registered listener.
        272 * @interface
        273 */
        274goog.events.ListenableKey = function() {};
        275
        276
        277/**
        278 * Counter used to create a unique key
        279 * @type {number}
        280 * @private
        281 */
        282goog.events.ListenableKey.counter_ = 0;
        283
        284
        285/**
        286 * Reserves a key to be used for ListenableKey#key field.
        287 * @return {number} A number to be used to fill ListenableKey#key
        288 * field.
        289 */
        290goog.events.ListenableKey.reserveKey = function() {
        291 return ++goog.events.ListenableKey.counter_;
        292};
        293
        294
        295/**
        296 * The source event target.
        297 * @type {!(Object|goog.events.Listenable|goog.events.EventTarget)}
        298 */
        299goog.events.ListenableKey.prototype.src;
        300
        301
        302/**
        303 * The event type the listener is listening to.
        304 * @type {string}
        305 */
        306goog.events.ListenableKey.prototype.type;
        307
        308
        309/**
        310 * The listener function.
        311 * @type {function(?):?|{handleEvent:function(?):?}|null}
        312 */
        313goog.events.ListenableKey.prototype.listener;
        314
        315
        316/**
        317 * Whether the listener works on capture phase.
        318 * @type {boolean}
        319 */
        320goog.events.ListenableKey.prototype.capture;
        321
        322
        323/**
        324 * The 'this' object for the listener function's scope.
        325 * @type {Object}
        326 */
        327goog.events.ListenableKey.prototype.handler;
        328
        329
        330/**
        331 * A globally unique number to identify the key.
        332 * @type {number}
        333 */
        334goog.events.ListenableKey.prototype.key;
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/events/listener.js.src.html b/docs/api/javascript/source/lib/goog/events/listener.js.src.html new file mode 100644 index 0000000000000..7ed2f62fe75cb --- /dev/null +++ b/docs/api/javascript/source/lib/goog/events/listener.js.src.html @@ -0,0 +1 @@ +listener.js

        lib/goog/events/listener.js

        1// Copyright 2005 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 Listener object.
        17 * @see ../demos/events.html
        18 */
        19
        20goog.provide('goog.events.Listener');
        21
        22goog.require('goog.events.ListenableKey');
        23
        24
        25
        26/**
        27 * Simple class that stores information about a listener
        28 * @param {!Function} listener Callback function.
        29 * @param {Function} proxy Wrapper for the listener that patches the event.
        30 * @param {EventTarget|goog.events.Listenable} src Source object for
        31 * the event.
        32 * @param {string} type Event type.
        33 * @param {boolean} capture Whether in capture or bubble phase.
        34 * @param {Object=} opt_handler Object in whose context to execute the callback.
        35 * @implements {goog.events.ListenableKey}
        36 * @constructor
        37 */
        38goog.events.Listener = function(
        39 listener, proxy, src, type, capture, opt_handler) {
        40 if (goog.events.Listener.ENABLE_MONITORING) {
        41 this.creationStack = new Error().stack;
        42 }
        43
        44 /**
        45 * Callback function.
        46 * @type {Function}
        47 */
        48 this.listener = listener;
        49
        50 /**
        51 * A wrapper over the original listener. This is used solely to
        52 * handle native browser events (it is used to simulate the capture
        53 * phase and to patch the event object).
        54 * @type {Function}
        55 */
        56 this.proxy = proxy;
        57
        58 /**
        59 * Object or node that callback is listening to
        60 * @type {EventTarget|goog.events.Listenable}
        61 */
        62 this.src = src;
        63
        64 /**
        65 * The event type.
        66 * @const {string}
        67 */
        68 this.type = type;
        69
        70 /**
        71 * Whether the listener is being called in the capture or bubble phase
        72 * @const {boolean}
        73 */
        74 this.capture = !!capture;
        75
        76 /**
        77 * Optional object whose context to execute the listener in
        78 * @type {Object|undefined}
        79 */
        80 this.handler = opt_handler;
        81
        82 /**
        83 * The key of the listener.
        84 * @const {number}
        85 * @override
        86 */
        87 this.key = goog.events.ListenableKey.reserveKey();
        88
        89 /**
        90 * Whether to remove the listener after it has been called.
        91 * @type {boolean}
        92 */
        93 this.callOnce = false;
        94
        95 /**
        96 * Whether the listener has been removed.
        97 * @type {boolean}
        98 */
        99 this.removed = false;
        100};
        101
        102
        103/**
        104 * @define {boolean} Whether to enable the monitoring of the
        105 * goog.events.Listener instances. Switching on the monitoring is only
        106 * recommended for debugging because it has a significant impact on
        107 * performance and memory usage. If switched off, the monitoring code
        108 * compiles down to 0 bytes.
        109 */
        110goog.define('goog.events.Listener.ENABLE_MONITORING', false);
        111
        112
        113/**
        114 * If monitoring the goog.events.Listener instances is enabled, stores the
        115 * creation stack trace of the Disposable instance.
        116 * @type {string}
        117 */
        118goog.events.Listener.prototype.creationStack;
        119
        120
        121/**
        122 * Marks this listener as removed. This also remove references held by
        123 * this listener object (such as listener and event source).
        124 */
        125goog.events.Listener.prototype.markAsRemoved = function() {
        126 this.removed = true;
        127 this.listener = null;
        128 this.proxy = null;
        129 this.src = null;
        130 this.handler = null;
        131};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/events/listenermap.js.src.html b/docs/api/javascript/source/lib/goog/events/listenermap.js.src.html new file mode 100644 index 0000000000000..a0d26e7d6e3d4 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/events/listenermap.js.src.html @@ -0,0 +1 @@ +listenermap.js

        lib/goog/events/listenermap.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 A map of listeners that provides utility functions to
        17 * deal with listeners on an event target. Used by
        18 * {@code goog.events.EventTarget}.
        19 *
        20 * WARNING: Do not use this class from outside goog.events package.
        21 *
        22 * @visibility {//closure/goog/bin/sizetests:__pkg__}
        23 * @visibility {//closure/goog/events:__pkg__}
        24 * @visibility {//closure/goog/labs/events:__pkg__}
        25 */
        26
        27goog.provide('goog.events.ListenerMap');
        28
        29goog.require('goog.array');
        30goog.require('goog.events.Listener');
        31goog.require('goog.object');
        32
        33
        34
        35/**
        36 * Creates a new listener map.
        37 * @param {EventTarget|goog.events.Listenable} src The src object.
        38 * @constructor
        39 * @final
        40 */
        41goog.events.ListenerMap = function(src) {
        42 /** @type {EventTarget|goog.events.Listenable} */
        43 this.src = src;
        44
        45 /**
        46 * Maps of event type to an array of listeners.
        47 * @type {Object.<string, !Array.<!goog.events.Listener>>}
        48 */
        49 this.listeners = {};
        50
        51 /**
        52 * The count of types in this map that have registered listeners.
        53 * @private {number}
        54 */
        55 this.typeCount_ = 0;
        56};
        57
        58
        59/**
        60 * @return {number} The count of event types in this map that actually
        61 * have registered listeners.
        62 */
        63goog.events.ListenerMap.prototype.getTypeCount = function() {
        64 return this.typeCount_;
        65};
        66
        67
        68/**
        69 * @return {number} Total number of registered listeners.
        70 */
        71goog.events.ListenerMap.prototype.getListenerCount = function() {
        72 var count = 0;
        73 for (var type in this.listeners) {
        74 count += this.listeners[type].length;
        75 }
        76 return count;
        77};
        78
        79
        80/**
        81 * Adds an event listener. A listener can only be added once to an
        82 * object and if it is added again the key for the listener is
        83 * returned.
        84 *
        85 * Note that a one-off listener will not change an existing listener,
        86 * if any. On the other hand a normal listener will change existing
        87 * one-off listener to become a normal listener.
        88 *
        89 * @param {string|!goog.events.EventId} type The listener event type.
        90 * @param {!Function} listener This listener callback method.
        91 * @param {boolean} callOnce Whether the listener is a one-off
        92 * listener.
        93 * @param {boolean=} opt_useCapture The capture mode of the listener.
        94 * @param {Object=} opt_listenerScope Object in whose scope to call the
        95 * listener.
        96 * @return {goog.events.ListenableKey} Unique key for the listener.
        97 */
        98goog.events.ListenerMap.prototype.add = function(
        99 type, listener, callOnce, opt_useCapture, opt_listenerScope) {
        100 var typeStr = type.toString();
        101 var listenerArray = this.listeners[typeStr];
        102 if (!listenerArray) {
        103 listenerArray = this.listeners[typeStr] = [];
        104 this.typeCount_++;
        105 }
        106
        107 var listenerObj;
        108 var index = goog.events.ListenerMap.findListenerIndex_(
        109 listenerArray, listener, opt_useCapture, opt_listenerScope);
        110 if (index > -1) {
        111 listenerObj = listenerArray[index];
        112 if (!callOnce) {
        113 // Ensure that, if there is an existing callOnce listener, it is no
        114 // longer a callOnce listener.
        115 listenerObj.callOnce = false;
        116 }
        117 } else {
        118 listenerObj = new goog.events.Listener(
        119 listener, null, this.src, typeStr, !!opt_useCapture, opt_listenerScope);
        120 listenerObj.callOnce = callOnce;
        121 listenerArray.push(listenerObj);
        122 }
        123 return listenerObj;
        124};
        125
        126
        127/**
        128 * Removes a matching listener.
        129 * @param {string|!goog.events.EventId} type The listener event type.
        130 * @param {!Function} listener This listener callback method.
        131 * @param {boolean=} opt_useCapture The capture mode of the listener.
        132 * @param {Object=} opt_listenerScope Object in whose scope to call the
        133 * listener.
        134 * @return {boolean} Whether any listener was removed.
        135 */
        136goog.events.ListenerMap.prototype.remove = function(
        137 type, listener, opt_useCapture, opt_listenerScope) {
        138 var typeStr = type.toString();
        139 if (!(typeStr in this.listeners)) {
        140 return false;
        141 }
        142
        143 var listenerArray = this.listeners[typeStr];
        144 var index = goog.events.ListenerMap.findListenerIndex_(
        145 listenerArray, listener, opt_useCapture, opt_listenerScope);
        146 if (index > -1) {
        147 var listenerObj = listenerArray[index];
        148 listenerObj.markAsRemoved();
        149 goog.array.removeAt(listenerArray, index);
        150 if (listenerArray.length == 0) {
        151 delete this.listeners[typeStr];
        152 this.typeCount_--;
        153 }
        154 return true;
        155 }
        156 return false;
        157};
        158
        159
        160/**
        161 * Removes the given listener object.
        162 * @param {goog.events.ListenableKey} listener The listener to remove.
        163 * @return {boolean} Whether the listener is removed.
        164 */
        165goog.events.ListenerMap.prototype.removeByKey = function(listener) {
        166 var type = listener.type;
        167 if (!(type in this.listeners)) {
        168 return false;
        169 }
        170
        171 var removed = goog.array.remove(this.listeners[type], listener);
        172 if (removed) {
        173 listener.markAsRemoved();
        174 if (this.listeners[type].length == 0) {
        175 delete this.listeners[type];
        176 this.typeCount_--;
        177 }
        178 }
        179 return removed;
        180};
        181
        182
        183/**
        184 * Removes all listeners from this map. If opt_type is provided, only
        185 * listeners that match the given type are removed.
        186 * @param {string|!goog.events.EventId=} opt_type Type of event to remove.
        187 * @return {number} Number of listeners removed.
        188 */
        189goog.events.ListenerMap.prototype.removeAll = function(opt_type) {
        190 var typeStr = opt_type && opt_type.toString();
        191 var count = 0;
        192 for (var type in this.listeners) {
        193 if (!typeStr || type == typeStr) {
        194 var listenerArray = this.listeners[type];
        195 for (var i = 0; i < listenerArray.length; i++) {
        196 ++count;
        197 listenerArray[i].markAsRemoved();
        198 }
        199 delete this.listeners[type];
        200 this.typeCount_--;
        201 }
        202 }
        203 return count;
        204};
        205
        206
        207/**
        208 * Gets all listeners that match the given type and capture mode. The
        209 * returned array is a copy (but the listener objects are not).
        210 * @param {string|!goog.events.EventId} type The type of the listeners
        211 * to retrieve.
        212 * @param {boolean} capture The capture mode of the listeners to retrieve.
        213 * @return {!Array.<goog.events.ListenableKey>} An array of matching
        214 * listeners.
        215 */
        216goog.events.ListenerMap.prototype.getListeners = function(type, capture) {
        217 var listenerArray = this.listeners[type.toString()];
        218 var rv = [];
        219 if (listenerArray) {
        220 for (var i = 0; i < listenerArray.length; ++i) {
        221 var listenerObj = listenerArray[i];
        222 if (listenerObj.capture == capture) {
        223 rv.push(listenerObj);
        224 }
        225 }
        226 }
        227 return rv;
        228};
        229
        230
        231/**
        232 * Gets the goog.events.ListenableKey for the event or null if no such
        233 * listener is in use.
        234 *
        235 * @param {string|!goog.events.EventId} type The type of the listener
        236 * to retrieve.
        237 * @param {!Function} listener The listener function to get.
        238 * @param {boolean} capture Whether the listener is a capturing listener.
        239 * @param {Object=} opt_listenerScope Object in whose scope to call the
        240 * listener.
        241 * @return {goog.events.ListenableKey} the found listener or null if not found.
        242 */
        243goog.events.ListenerMap.prototype.getListener = function(
        244 type, listener, capture, opt_listenerScope) {
        245 var listenerArray = this.listeners[type.toString()];
        246 var i = -1;
        247 if (listenerArray) {
        248 i = goog.events.ListenerMap.findListenerIndex_(
        249 listenerArray, listener, capture, opt_listenerScope);
        250 }
        251 return i > -1 ? listenerArray[i] : null;
        252};
        253
        254
        255/**
        256 * Whether there is a matching listener. If either the type or capture
        257 * parameters are unspecified, the function will match on the
        258 * remaining criteria.
        259 *
        260 * @param {string|!goog.events.EventId=} opt_type The type of the listener.
        261 * @param {boolean=} opt_capture The capture mode of the listener.
        262 * @return {boolean} Whether there is an active listener matching
        263 * the requested type and/or capture phase.
        264 */
        265goog.events.ListenerMap.prototype.hasListener = function(
        266 opt_type, opt_capture) {
        267 var hasType = goog.isDef(opt_type);
        268 var typeStr = hasType ? opt_type.toString() : '';
        269 var hasCapture = goog.isDef(opt_capture);
        270
        271 return goog.object.some(
        272 this.listeners, function(listenerArray, type) {
        273 for (var i = 0; i < listenerArray.length; ++i) {
        274 if ((!hasType || listenerArray[i].type == typeStr) &&
        275 (!hasCapture || listenerArray[i].capture == opt_capture)) {
        276 return true;
        277 }
        278 }
        279
        280 return false;
        281 });
        282};
        283
        284
        285/**
        286 * Finds the index of a matching goog.events.Listener in the given
        287 * listenerArray.
        288 * @param {!Array.<!goog.events.Listener>} listenerArray Array of listener.
        289 * @param {!Function} listener The listener function.
        290 * @param {boolean=} opt_useCapture The capture flag for the listener.
        291 * @param {Object=} opt_listenerScope The listener scope.
        292 * @return {number} The index of the matching listener within the
        293 * listenerArray.
        294 * @private
        295 */
        296goog.events.ListenerMap.findListenerIndex_ = function(
        297 listenerArray, listener, opt_useCapture, opt_listenerScope) {
        298 for (var i = 0; i < listenerArray.length; ++i) {
        299 var listenerObj = listenerArray[i];
        300 if (!listenerObj.removed &&
        301 listenerObj.listener == listener &&
        302 listenerObj.capture == !!opt_useCapture &&
        303 listenerObj.handler == opt_listenerScope) {
        304 return i;
        305 }
        306 }
        307 return -1;
        308};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/functions/functions.js.src.html b/docs/api/javascript/source/lib/goog/functions/functions.js.src.html index eafedd69c133e..ecd96dec57fd6 100644 --- a/docs/api/javascript/source/lib/goog/functions/functions.js.src.html +++ b/docs/api/javascript/source/lib/goog/functions/functions.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/iter/iter.js.src.html b/docs/api/javascript/source/lib/goog/iter/iter.js.src.html index 73d326a0bec48..32211136606be 100644 --- a/docs/api/javascript/source/lib/goog/iter/iter.js.src.html +++ b/docs/api/javascript/source/lib/goog/iter/iter.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/json/json.js.src.html b/docs/api/javascript/source/lib/goog/json/json.js.src.html index 8691161439dd3..2de98abd7af18 100644 --- a/docs/api/javascript/source/lib/goog/json/json.js.src.html +++ b/docs/api/javascript/source/lib/goog/json/json.js.src.html @@ -1 +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 +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 */
        42goog.json.isValid = function(s) {
        43 // All empty whitespace is not valid.
        44 if (/^\s*$/.test(s)) {
        45 return false;
        46 }
        47
        48 // This is taken from http://www.json.org/json2.js which is released to the
        49 // public domain.
        50 // Changes: We dissallow \u2028 Line separator and \u2029 Paragraph separator
        51 // inside strings. We also treat \u2028 and \u2029 as whitespace which they
        52 // are in the RFC but IE and Safari does not match \s to these so we need to
        53 // include them in the reg exps in all places where whitespace is allowed.
        54 // We allowed \x7f inside strings because some tools don't escape it,
        55 // e.g. http://www.json.org/java/org/json/JSONObject.java
        56
        57 // Parsing happens in three stages. In the first stage, we run the text
        58 // against regular expressions that look for non-JSON patterns. We are
        59 // especially concerned with '()' and 'new' because they can cause invocation,
        60 // and '=' because it can cause mutation. But just to be safe, we want to
        61 // reject all unexpected forms.
        62
        63 // We split the first stage into 4 regexp operations in order to work around
        64 // crippling inefficiencies in IE's and Safari's regexp engines. First we
        65 // replace all backslash pairs with '@' (a non-JSON character). Second, we
        66 // replace all simple value tokens with ']' characters. Third, we delete all
        67 // open brackets that follow a colon or comma or that begin the text. Finally,
        68 // we look to see that the remaining characters are only whitespace or ']' or
        69 // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
        70
        71 // Don't make these static since they have the global flag.
        72 var backslashesRe = /\\["\\\/bfnrtu]/g;
        73 var simpleValuesRe =
        74 /"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
        75 var openBracketsRe = /(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g;
        76 var remainderRe = /^[\],:{}\s\u2028\u2029]*$/;
        77
        78 return remainderRe.test(s.replace(backslashesRe, '@').
        79 replace(simpleValuesRe, ']').
        80 replace(openBracketsRe, ''));
        81};
        82
        83
        84/**
        85 * Parses a JSON string and returns the result. This throws an exception if
        86 * the string is an invalid JSON string.
        87 *
        88 * Note that this is very slow on large strings. If you trust the source of
        89 * the string then you should use unsafeParse instead.
        90 *
        91 * @param {*} s The JSON string to parse.
        92 * @throws Error if s is invalid JSON.
        93 * @return {Object} The object generated from the JSON string, or null.
        94 */
        95goog.json.parse = goog.json.USE_NATIVE_JSON ?
        96 /** @type {function(*):Object} */ (goog.global['JSON']['parse']) :
        97 function(s) {
        98 var o = String(s);
        99 if (goog.json.isValid(o)) {
        100 /** @preserveTry */
        101 try {
        102 return /** @type {Object} */ (eval('(' + o + ')'));
        103 } catch (ex) {
        104 }
        105 }
        106 throw Error('Invalid JSON string: ' + o);
        107 };
        108
        109
        110/**
        111 * Parses a JSON string and returns the result. This uses eval so it is open
        112 * to security issues and it should only be used if you trust the source.
        113 *
        114 * @param {string} s The JSON string to parse.
        115 * @return {Object} The object generated from the JSON string.
        116 */
        117goog.json.unsafeParse = goog.json.USE_NATIVE_JSON ?
        118 /** @type {function(string):Object} */ (goog.global['JSON']['parse']) :
        119 function(s) {
        120 return /** @type {Object} */ (eval('(' + s + ')'));
        121 };
        122
        123
        124/**
        125 * JSON replacer, as defined in Section 15.12.3 of the ES5 spec.
        126 * @see http://ecma-international.org/ecma-262/5.1/#sec-15.12.3
        127 *
        128 * TODO(nicksantos): Array should also be a valid replacer.
        129 *
        130 * @typedef {function(this:Object, string, *): *}
        131 */
        132goog.json.Replacer;
        133
        134
        135/**
        136 * JSON reviver, as defined in Section 15.12.2 of the ES5 spec.
        137 * @see http://ecma-international.org/ecma-262/5.1/#sec-15.12.3
        138 *
        139 * @typedef {function(this:Object, string, *): *}
        140 */
        141goog.json.Reviver;
        142
        143
        144/**
        145 * Serializes an object or a value to a JSON string.
        146 *
        147 * @param {*} object The object to serialize.
        148 * @param {?goog.json.Replacer=} opt_replacer A replacer function
        149 * called for each (key, value) pair that determines how the value
        150 * should be serialized. By defult, this just returns the value
        151 * and allows default serialization to kick in.
        152 * @throws Error if there are loops in the object graph.
        153 * @return {string} A JSON string representation of the input.
        154 */
        155goog.json.serialize = goog.json.USE_NATIVE_JSON ?
        156 /** @type {function(*, ?goog.json.Replacer=):string} */
        157 (goog.global['JSON']['stringify']) :
        158 function(object, opt_replacer) {
        159 // NOTE(nicksantos): Currently, we never use JSON.stringify.
        160 //
        161 // The last time I evaluated this, JSON.stringify had subtle bugs and
        162 // behavior differences on all browsers, and the performance win was not
        163 // large enough to justify all the issues. This may change in the future
        164 // as browser implementations get better.
        165 //
        166 // assertSerialize in json_test contains if branches for the cases
        167 // that fail.
        168 return new goog.json.Serializer(opt_replacer).serialize(object);
        169 };
        170
        171
        172
        173/**
        174 * Class that is used to serialize JSON objects to a string.
        175 * @param {?goog.json.Replacer=} opt_replacer Replacer.
        176 * @constructor
        177 */
        178goog.json.Serializer = function(opt_replacer) {
        179 /**
        180 * @type {goog.json.Replacer|null|undefined}
        181 * @private
        182 */
        183 this.replacer_ = opt_replacer;
        184};
        185
        186
        187/**
        188 * Serializes an object or a value to a JSON string.
        189 *
        190 * @param {*} object The object to serialize.
        191 * @throws Error if there are loops in the object graph.
        192 * @return {string} A JSON string representation of the input.
        193 */
        194goog.json.Serializer.prototype.serialize = function(object) {
        195 var sb = [];
        196 this.serializeInternal(object, sb);
        197 return sb.join('');
        198};
        199
        200
        201/**
        202 * Serializes a generic value to a JSON string
        203 * @protected
        204 * @param {*} object The object to serialize.
        205 * @param {Array} sb Array used as a string builder.
        206 * @throws Error if there are loops in the object graph.
        207 */
        208goog.json.Serializer.prototype.serializeInternal = function(object, sb) {
        209 switch (typeof object) {
        210 case 'string':
        211 this.serializeString_(/** @type {string} */ (object), sb);
        212 break;
        213 case 'number':
        214 this.serializeNumber_(/** @type {number} */ (object), sb);
        215 break;
        216 case 'boolean':
        217 sb.push(object);
        218 break;
        219 case 'undefined':
        220 sb.push('null');
        221 break;
        222 case 'object':
        223 if (object == null) {
        224 sb.push('null');
        225 break;
        226 }
        227 if (goog.isArray(object)) {
        228 this.serializeArray(/** @type {!Array} */ (object), sb);
        229 break;
        230 }
        231 // should we allow new String, new Number and new Boolean to be treated
        232 // as string, number and boolean? Most implementations do not and the
        233 // need is not very big
        234 this.serializeObject_(/** @type {Object} */ (object), sb);
        235 break;
        236 case 'function':
        237 // Skip functions.
        238 // TODO(user) Should we return something here?
        239 break;
        240 default:
        241 throw Error('Unknown type: ' + typeof object);
        242 }
        243};
        244
        245
        246/**
        247 * Character mappings used internally for goog.string.quote
        248 * @private
        249 * @type {!Object}
        250 */
        251goog.json.Serializer.charToJsonCharCache_ = {
        252 '\"': '\\"',
        253 '\\': '\\\\',
        254 '/': '\\/',
        255 '\b': '\\b',
        256 '\f': '\\f',
        257 '\n': '\\n',
        258 '\r': '\\r',
        259 '\t': '\\t',
        260
        261 '\x0B': '\\u000b' // '\v' is not supported in JScript
        262};
        263
        264
        265/**
        266 * Regular expression used to match characters that need to be replaced.
        267 * The S60 browser has a bug where unicode characters are not matched by
        268 * regular expressions. The condition below detects such behaviour and
        269 * adjusts the regular expression accordingly.
        270 * @private
        271 * @type {!RegExp}
        272 */
        273goog.json.Serializer.charsToReplace_ = /\uffff/.test('\uffff') ?
        274 /[\\\"\x00-\x1f\x7f-\uffff]/g : /[\\\"\x00-\x1f\x7f-\xff]/g;
        275
        276
        277/**
        278 * Serializes a string to a JSON string
        279 * @private
        280 * @param {string} s The string to serialize.
        281 * @param {Array} sb Array used as a string builder.
        282 */
        283goog.json.Serializer.prototype.serializeString_ = function(s, sb) {
        284 // The official JSON implementation does not work with international
        285 // characters.
        286 sb.push('"', s.replace(goog.json.Serializer.charsToReplace_, function(c) {
        287 // caching the result improves performance by a factor 2-3
        288 if (c in goog.json.Serializer.charToJsonCharCache_) {
        289 return goog.json.Serializer.charToJsonCharCache_[c];
        290 }
        291
        292 var cc = c.charCodeAt(0);
        293 var rv = '\\u';
        294 if (cc < 16) {
        295 rv += '000';
        296 } else if (cc < 256) {
        297 rv += '00';
        298 } else if (cc < 4096) { // \u1000
        299 rv += '0';
        300 }
        301 return goog.json.Serializer.charToJsonCharCache_[c] = rv + cc.toString(16);
        302 }), '"');
        303};
        304
        305
        306/**
        307 * Serializes a number to a JSON string
        308 * @private
        309 * @param {number} n The number to serialize.
        310 * @param {Array} sb Array used as a string builder.
        311 */
        312goog.json.Serializer.prototype.serializeNumber_ = function(n, sb) {
        313 sb.push(isFinite(n) && !isNaN(n) ? n : 'null');
        314};
        315
        316
        317/**
        318 * Serializes an array to a JSON string
        319 * @param {Array} arr The array to serialize.
        320 * @param {Array} sb Array used as a string builder.
        321 * @protected
        322 */
        323goog.json.Serializer.prototype.serializeArray = function(arr, sb) {
        324 var l = arr.length;
        325 sb.push('[');
        326 var sep = '';
        327 for (var i = 0; i < l; i++) {
        328 sb.push(sep);
        329
        330 var value = arr[i];
        331 this.serializeInternal(
        332 this.replacer_ ? this.replacer_.call(arr, String(i), value) : value,
        333 sb);
        334
        335 sep = ',';
        336 }
        337 sb.push(']');
        338};
        339
        340
        341/**
        342 * Serializes an object to a JSON string
        343 * @private
        344 * @param {Object} obj The object to serialize.
        345 * @param {Array} sb Array used as a string builder.
        346 */
        347goog.json.Serializer.prototype.serializeObject_ = function(obj, sb) {
        348 sb.push('{');
        349 var sep = '';
        350 for (var key in obj) {
        351 if (Object.prototype.hasOwnProperty.call(obj, key)) {
        352 var value = obj[key];
        353 // Skip functions.
        354 // TODO(ptucker) Should we return something for function properties?
        355 if (typeof value != 'function') {
        356 sb.push(sep);
        357 this.serializeString_(key, sb);
        358 sb.push(':');
        359
        360 this.serializeInternal(
        361 this.replacer_ ? this.replacer_.call(obj, key, value) : value,
        362 sb);
        363
        364 sep = ',';
        365 }
        366 }
        367 }
        368 sb.push('}');
        369};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/labs/testing/assertthat.js.src.html b/docs/api/javascript/source/lib/goog/labs/testing/assertthat.js.src.html index fcb21e3e8cd1e..b0c94bdfece79 100644 --- a/docs/api/javascript/source/lib/goog/labs/testing/assertthat.js.src.html +++ b/docs/api/javascript/source/lib/goog/labs/testing/assertthat.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/labs/testing/logicmatcher.js.src.html b/docs/api/javascript/source/lib/goog/labs/testing/logicmatcher.js.src.html index 4266eff438476..732ea8693d72a 100644 --- a/docs/api/javascript/source/lib/goog/labs/testing/logicmatcher.js.src.html +++ b/docs/api/javascript/source/lib/goog/labs/testing/logicmatcher.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/labs/testing/matcher.js.src.html b/docs/api/javascript/source/lib/goog/labs/testing/matcher.js.src.html index 2de83874a6b08..5a4455b809e57 100644 --- a/docs/api/javascript/source/lib/goog/labs/testing/matcher.js.src.html +++ b/docs/api/javascript/source/lib/goog/labs/testing/matcher.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/labs/testing/numbermatcher.js.src.html b/docs/api/javascript/source/lib/goog/labs/testing/numbermatcher.js.src.html index 49f919002d0f6..a369788a91733 100644 --- a/docs/api/javascript/source/lib/goog/labs/testing/numbermatcher.js.src.html +++ b/docs/api/javascript/source/lib/goog/labs/testing/numbermatcher.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/labs/testing/objectmatcher.js.src.html b/docs/api/javascript/source/lib/goog/labs/testing/objectmatcher.js.src.html index f7b3ee9dafcd5..4424c7160f254 100644 --- a/docs/api/javascript/source/lib/goog/labs/testing/objectmatcher.js.src.html +++ b/docs/api/javascript/source/lib/goog/labs/testing/objectmatcher.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/labs/testing/stringmatcher.js.src.html b/docs/api/javascript/source/lib/goog/labs/testing/stringmatcher.js.src.html index da868e8bb5e29..34f820233c3d3 100644 --- a/docs/api/javascript/source/lib/goog/labs/testing/stringmatcher.js.src.html +++ b/docs/api/javascript/source/lib/goog/labs/testing/stringmatcher.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/labs/useragent/browser.js.src.html b/docs/api/javascript/source/lib/goog/labs/useragent/browser.js.src.html index db262b0ced2ca..3ec8b125185f0 100644 --- a/docs/api/javascript/source/lib/goog/labs/useragent/browser.js.src.html +++ b/docs/api/javascript/source/lib/goog/labs/useragent/browser.js.src.html @@ -1 +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 +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.labs.userAgent.util');
        28goog.require('goog.object');
        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 // Android can appear in the user agent string for Chrome on Android.
        89 // This is not the Android standalone browser if it does.
        90 return !goog.labs.userAgent.browser.isChrome() &&
        91 goog.labs.userAgent.util.matchUserAgent('Android');
        92
        93};
        94
        95
        96/**
        97 * @return {boolean} Whether the user's browser is Opera.
        98 */
        99goog.labs.userAgent.browser.isOpera = goog.labs.userAgent.browser.matchOpera_;
        100
        101
        102/**
        103 * @return {boolean} Whether the user's browser is IE.
        104 */
        105goog.labs.userAgent.browser.isIE = goog.labs.userAgent.browser.matchIE_;
        106
        107
        108/**
        109 * @return {boolean} Whether the user's browser is Firefox.
        110 */
        111goog.labs.userAgent.browser.isFirefox =
        112 goog.labs.userAgent.browser.matchFirefox_;
        113
        114
        115/**
        116 * @return {boolean} Whether the user's browser is Safari.
        117 */
        118goog.labs.userAgent.browser.isSafari =
        119 goog.labs.userAgent.browser.matchSafari_;
        120
        121
        122/**
        123 * @return {boolean} Whether the user's browser is Chrome.
        124 */
        125goog.labs.userAgent.browser.isChrome =
        126 goog.labs.userAgent.browser.matchChrome_;
        127
        128
        129/**
        130 * @return {boolean} Whether the user's browser is the Android browser.
        131 */
        132goog.labs.userAgent.browser.isAndroidBrowser =
        133 goog.labs.userAgent.browser.matchAndroidBrowser_;
        134
        135
        136/**
        137 * For more information, see:
        138 * http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html
        139 * @return {boolean} Whether the user's browser is Silk.
        140 */
        141goog.labs.userAgent.browser.isSilk = function() {
        142 return goog.labs.userAgent.util.matchUserAgent('Silk');
        143};
        144
        145
        146/**
        147 * @return {string} The browser version or empty string if version cannot be
        148 * determined. Note that for Internet Explorer, this returns the version of
        149 * the browser, not the version of the rendering engine. (IE 8 in
        150 * compatibility mode will return 8.0 rather than 7.0. To determine the
        151 * rendering engine version, look at document.documentMode instead. See
        152 * http://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx for more
        153 * details.)
        154 */
        155goog.labs.userAgent.browser.getVersion = function() {
        156 var userAgentString = goog.labs.userAgent.util.getUserAgent();
        157 // Special case IE since IE's version is inside the parenthesis and
        158 // without the '/'.
        159 if (goog.labs.userAgent.browser.isIE()) {
        160 return goog.labs.userAgent.browser.getIEVersion_(userAgentString);
        161 }
        162
        163 var versionTuples = goog.labs.userAgent.util.extractVersionTuples(
        164 userAgentString);
        165
        166 // Construct a map for easy lookup.
        167 var versionMap = {};
        168 goog.array.forEach(versionTuples, function(tuple) {
        169 // Note that the tuple is of length three, but we only care about the
        170 // first two.
        171 var key = tuple[0];
        172 var value = tuple[1];
        173 versionMap[key] = value;
        174 });
        175
        176 var versionMapHasKey = goog.partial(goog.object.containsKey, versionMap);
        177
        178 // Gives the value with the first key it finds, otherwise empty string.
        179 function lookUpValueWithKeys(keys) {
        180 var key = goog.array.find(keys, versionMapHasKey);
        181 return versionMap[key] || '';
        182 }
        183
        184 // Check Opera before Chrome since Opera 15+ has "Chrome" in the string.
        185 // See
        186 // http://my.opera.com/ODIN/blog/2013/07/15/opera-user-agent-strings-opera-15-and-beyond
        187 if (goog.labs.userAgent.browser.isOpera()) {
        188 // Opera 10 has Version/10.0 but Opera/9.8, so look for "Version" first.
        189 // Opera uses 'OPR' for more recent UAs.
        190 return lookUpValueWithKeys(['Version', 'Opera', 'OPR']);
        191 }
        192
        193 if (goog.labs.userAgent.browser.isChrome()) {
        194 return lookUpValueWithKeys(['Chrome', 'CriOS']);
        195 }
        196
        197 // Usually products browser versions are in the third tuple after "Mozilla"
        198 // and the engine.
        199 var tuple = versionTuples[2];
        200 return tuple && tuple[1] || '';
        201};
        202
        203
        204/**
        205 * @param {string|number} version The version to check.
        206 * @return {boolean} Whether the browser version is higher or the same as the
        207 * given version.
        208 */
        209goog.labs.userAgent.browser.isVersionOrHigher = function(version) {
        210 return goog.string.compareVersions(goog.labs.userAgent.browser.getVersion(),
        211 version) >= 0;
        212};
        213
        214
        215/**
        216 * Determines IE version. More information:
        217 * http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx#uaString
        218 * http://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx
        219 * http://blogs.msdn.com/b/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx
        220 * http://blogs.msdn.com/b/ie/archive/2009/01/09/the-internet-explorer-8-user-agent-string-updated-edition.aspx
        221 *
        222 * @param {string} userAgent the User-Agent.
        223 * @return {string}
        224 * @private
        225 */
        226goog.labs.userAgent.browser.getIEVersion_ = function(userAgent) {
        227 // IE11 may identify itself as MSIE 9.0 or MSIE 10.0 due to an IE 11 upgrade
        228 // bug. Example UA:
        229 // Mozilla/5.0 (MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; rv:11.0)
        230 // like Gecko.
        231 // See http://www.whatismybrowser.com/developers/unknown-user-agent-fragments.
        232 var rv = /rv: *([\d\.]*)/.exec(userAgent);
        233 if (rv && rv[1]) {
        234 return rv[1];
        235 }
        236
        237 var version = '';
        238 var msie = /MSIE +([\d\.]+)/.exec(userAgent);
        239 if (msie && msie[1]) {
        240 // IE in compatibility mode usually identifies itself as MSIE 7.0; in this
        241 // case, use the Trident version to determine the version of IE. For more
        242 // details, see the links above.
        243 var tridentVersion = /Trident\/(\d.\d)/.exec(userAgent);
        244 if (msie[1] == '7.0') {
        245 if (tridentVersion && tridentVersion[1]) {
        246 switch (tridentVersion[1]) {
        247 case '4.0':
        248 version = '8.0';
        249 break;
        250 case '5.0':
        251 version = '9.0';
        252 break;
        253 case '6.0':
        254 version = '10.0';
        255 break;
        256 case '7.0':
        257 version = '11.0';
        258 break;
        259 }
        260 } else {
        261 version = '7.0';
        262 }
        263 } else {
        264 version = msie[1];
        265 }
        266 }
        267 return version;
        268};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/labs/useragent/engine.js.src.html b/docs/api/javascript/source/lib/goog/labs/useragent/engine.js.src.html index c03eabb9b70ab..60b50480cc663 100644 --- a/docs/api/javascript/source/lib/goog/labs/useragent/engine.js.src.html +++ b/docs/api/javascript/source/lib/goog/labs/useragent/engine.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/labs/useragent/util.js.src.html b/docs/api/javascript/source/lib/goog/labs/useragent/util.js.src.html index 40bff3680dd23..45f284ecb69ca 100644 --- a/docs/api/javascript/source/lib/goog/labs/useragent/util.js.src.html +++ b/docs/api/javascript/source/lib/goog/labs/useragent/util.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/math/box.js.src.html b/docs/api/javascript/source/lib/goog/math/box.js.src.html new file mode 100644 index 0000000000000..77c185a877921 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/math/box.js.src.html @@ -0,0 +1 @@ +box.js

        lib/goog/math/box.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 A utility class for representing a numeric box.
        17 */
        18
        19
        20goog.provide('goog.math.Box');
        21
        22goog.require('goog.math.Coordinate');
        23
        24
        25
        26/**
        27 * Class for representing a box. A box is specified as a top, right, bottom,
        28 * and left. A box is useful for representing margins and padding.
        29 *
        30 * This class assumes 'screen coordinates': larger Y coordinates are further
        31 * from the top of the screen.
        32 *
        33 * @param {number} top Top.
        34 * @param {number} right Right.
        35 * @param {number} bottom Bottom.
        36 * @param {number} left Left.
        37 * @constructor
        38 */
        39goog.math.Box = function(top, right, bottom, left) {
        40 /**
        41 * Top
        42 * @type {number}
        43 */
        44 this.top = top;
        45
        46 /**
        47 * Right
        48 * @type {number}
        49 */
        50 this.right = right;
        51
        52 /**
        53 * Bottom
        54 * @type {number}
        55 */
        56 this.bottom = bottom;
        57
        58 /**
        59 * Left
        60 * @type {number}
        61 */
        62 this.left = left;
        63};
        64
        65
        66/**
        67 * Creates a Box by bounding a collection of goog.math.Coordinate objects
        68 * @param {...goog.math.Coordinate} var_args Coordinates to be included inside
        69 * the box.
        70 * @return {!goog.math.Box} A Box containing all the specified Coordinates.
        71 */
        72goog.math.Box.boundingBox = function(var_args) {
        73 var box = new goog.math.Box(arguments[0].y, arguments[0].x,
        74 arguments[0].y, arguments[0].x);
        75 for (var i = 1; i < arguments.length; i++) {
        76 var coord = arguments[i];
        77 box.top = Math.min(box.top, coord.y);
        78 box.right = Math.max(box.right, coord.x);
        79 box.bottom = Math.max(box.bottom, coord.y);
        80 box.left = Math.min(box.left, coord.x);
        81 }
        82 return box;
        83};
        84
        85
        86/**
        87 * @return {number} width The width of this Box.
        88 */
        89goog.math.Box.prototype.getWidth = function() {
        90 return this.right - this.left;
        91};
        92
        93
        94/**
        95 * @return {number} height The height of this Box.
        96 */
        97goog.math.Box.prototype.getHeight = function() {
        98 return this.bottom - this.top;
        99};
        100
        101
        102/**
        103 * Creates a copy of the box with the same dimensions.
        104 * @return {!goog.math.Box} A clone of this Box.
        105 */
        106goog.math.Box.prototype.clone = function() {
        107 return new goog.math.Box(this.top, this.right, this.bottom, this.left);
        108};
        109
        110
        111if (goog.DEBUG) {
        112 /**
        113 * Returns a nice string representing the box.
        114 * @return {string} In the form (50t, 73r, 24b, 13l).
        115 * @override
        116 */
        117 goog.math.Box.prototype.toString = function() {
        118 return '(' + this.top + 't, ' + this.right + 'r, ' + this.bottom + 'b, ' +
        119 this.left + 'l)';
        120 };
        121}
        122
        123
        124/**
        125 * Returns whether the box contains a coordinate or another box.
        126 *
        127 * @param {goog.math.Coordinate|goog.math.Box} other A Coordinate or a Box.
        128 * @return {boolean} Whether the box contains the coordinate or other box.
        129 */
        130goog.math.Box.prototype.contains = function(other) {
        131 return goog.math.Box.contains(this, other);
        132};
        133
        134
        135/**
        136 * Expands box with the given margins.
        137 *
        138 * @param {number|goog.math.Box} top Top margin or box with all margins.
        139 * @param {number=} opt_right Right margin.
        140 * @param {number=} opt_bottom Bottom margin.
        141 * @param {number=} opt_left Left margin.
        142 * @return {!goog.math.Box} A reference to this Box.
        143 */
        144goog.math.Box.prototype.expand = function(top, opt_right, opt_bottom,
        145 opt_left) {
        146 if (goog.isObject(top)) {
        147 this.top -= top.top;
        148 this.right += top.right;
        149 this.bottom += top.bottom;
        150 this.left -= top.left;
        151 } else {
        152 this.top -= top;
        153 this.right += opt_right;
        154 this.bottom += opt_bottom;
        155 this.left -= opt_left;
        156 }
        157
        158 return this;
        159};
        160
        161
        162/**
        163 * Expand this box to include another box.
        164 * NOTE(user): This is used in code that needs to be very fast, please don't
        165 * add functionality to this function at the expense of speed (variable
        166 * arguments, accepting multiple argument types, etc).
        167 * @param {goog.math.Box} box The box to include in this one.
        168 */
        169goog.math.Box.prototype.expandToInclude = function(box) {
        170 this.left = Math.min(this.left, box.left);
        171 this.top = Math.min(this.top, box.top);
        172 this.right = Math.max(this.right, box.right);
        173 this.bottom = Math.max(this.bottom, box.bottom);
        174};
        175
        176
        177/**
        178 * Compares boxes for equality.
        179 * @param {goog.math.Box} a A Box.
        180 * @param {goog.math.Box} b A Box.
        181 * @return {boolean} True iff the boxes are equal, or if both are null.
        182 */
        183goog.math.Box.equals = function(a, b) {
        184 if (a == b) {
        185 return true;
        186 }
        187 if (!a || !b) {
        188 return false;
        189 }
        190 return a.top == b.top && a.right == b.right &&
        191 a.bottom == b.bottom && a.left == b.left;
        192};
        193
        194
        195/**
        196 * Returns whether a box contains a coordinate or another box.
        197 *
        198 * @param {goog.math.Box} box A Box.
        199 * @param {goog.math.Coordinate|goog.math.Box} other A Coordinate or a Box.
        200 * @return {boolean} Whether the box contains the coordinate or other box.
        201 */
        202goog.math.Box.contains = function(box, other) {
        203 if (!box || !other) {
        204 return false;
        205 }
        206
        207 if (other instanceof goog.math.Box) {
        208 return other.left >= box.left && other.right <= box.right &&
        209 other.top >= box.top && other.bottom <= box.bottom;
        210 }
        211
        212 // other is a Coordinate.
        213 return other.x >= box.left && other.x <= box.right &&
        214 other.y >= box.top && other.y <= box.bottom;
        215};
        216
        217
        218/**
        219 * Returns the relative x position of a coordinate compared to a box. Returns
        220 * zero if the coordinate is inside the box.
        221 *
        222 * @param {goog.math.Box} box A Box.
        223 * @param {goog.math.Coordinate} coord A Coordinate.
        224 * @return {number} The x position of {@code coord} relative to the nearest
        225 * side of {@code box}, or zero if {@code coord} is inside {@code box}.
        226 */
        227goog.math.Box.relativePositionX = function(box, coord) {
        228 if (coord.x < box.left) {
        229 return coord.x - box.left;
        230 } else if (coord.x > box.right) {
        231 return coord.x - box.right;
        232 }
        233 return 0;
        234};
        235
        236
        237/**
        238 * Returns the relative y position of a coordinate compared to a box. Returns
        239 * zero if the coordinate is inside the box.
        240 *
        241 * @param {goog.math.Box} box A Box.
        242 * @param {goog.math.Coordinate} coord A Coordinate.
        243 * @return {number} The y position of {@code coord} relative to the nearest
        244 * side of {@code box}, or zero if {@code coord} is inside {@code box}.
        245 */
        246goog.math.Box.relativePositionY = function(box, coord) {
        247 if (coord.y < box.top) {
        248 return coord.y - box.top;
        249 } else if (coord.y > box.bottom) {
        250 return coord.y - box.bottom;
        251 }
        252 return 0;
        253};
        254
        255
        256/**
        257 * Returns the distance between a coordinate and the nearest corner/side of a
        258 * box. Returns zero if the coordinate is inside the box.
        259 *
        260 * @param {goog.math.Box} box A Box.
        261 * @param {goog.math.Coordinate} coord A Coordinate.
        262 * @return {number} The distance between {@code coord} and the nearest
        263 * corner/side of {@code box}, or zero if {@code coord} is inside
        264 * {@code box}.
        265 */
        266goog.math.Box.distance = function(box, coord) {
        267 var x = goog.math.Box.relativePositionX(box, coord);
        268 var y = goog.math.Box.relativePositionY(box, coord);
        269 return Math.sqrt(x * x + y * y);
        270};
        271
        272
        273/**
        274 * Returns whether two boxes intersect.
        275 *
        276 * @param {goog.math.Box} a A Box.
        277 * @param {goog.math.Box} b A second Box.
        278 * @return {boolean} Whether the boxes intersect.
        279 */
        280goog.math.Box.intersects = function(a, b) {
        281 return (a.left <= b.right && b.left <= a.right &&
        282 a.top <= b.bottom && b.top <= a.bottom);
        283};
        284
        285
        286/**
        287 * Returns whether two boxes would intersect with additional padding.
        288 *
        289 * @param {goog.math.Box} a A Box.
        290 * @param {goog.math.Box} b A second Box.
        291 * @param {number} padding The additional padding.
        292 * @return {boolean} Whether the boxes intersect.
        293 */
        294goog.math.Box.intersectsWithPadding = function(a, b, padding) {
        295 return (a.left <= b.right + padding && b.left <= a.right + padding &&
        296 a.top <= b.bottom + padding && b.top <= a.bottom + padding);
        297};
        298
        299
        300/**
        301 * Rounds the fields to the next larger integer values.
        302 *
        303 * @return {!goog.math.Box} This box with ceil'd fields.
        304 */
        305goog.math.Box.prototype.ceil = function() {
        306 this.top = Math.ceil(this.top);
        307 this.right = Math.ceil(this.right);
        308 this.bottom = Math.ceil(this.bottom);
        309 this.left = Math.ceil(this.left);
        310 return this;
        311};
        312
        313
        314/**
        315 * Rounds the fields to the next smaller integer values.
        316 *
        317 * @return {!goog.math.Box} This box with floored fields.
        318 */
        319goog.math.Box.prototype.floor = function() {
        320 this.top = Math.floor(this.top);
        321 this.right = Math.floor(this.right);
        322 this.bottom = Math.floor(this.bottom);
        323 this.left = Math.floor(this.left);
        324 return this;
        325};
        326
        327
        328/**
        329 * Rounds the fields to nearest integer values.
        330 *
        331 * @return {!goog.math.Box} This box with rounded fields.
        332 */
        333goog.math.Box.prototype.round = function() {
        334 this.top = Math.round(this.top);
        335 this.right = Math.round(this.right);
        336 this.bottom = Math.round(this.bottom);
        337 this.left = Math.round(this.left);
        338 return this;
        339};
        340
        341
        342/**
        343 * Translates this box by the given offsets. If a {@code goog.math.Coordinate}
        344 * is given, then the left and right values are translated by the coordinate's
        345 * x value and the top and bottom values are translated by the coordinate's y
        346 * value. Otherwise, {@code tx} and {@code opt_ty} are used to translate the x
        347 * and y dimension values.
        348 *
        349 * @param {number|goog.math.Coordinate} tx The value to translate the x
        350 * dimension values by or the the coordinate to translate this box by.
        351 * @param {number=} opt_ty The value to translate y dimension values by.
        352 * @return {!goog.math.Box} This box after translating.
        353 */
        354goog.math.Box.prototype.translate = function(tx, opt_ty) {
        355 if (tx instanceof goog.math.Coordinate) {
        356 this.left += tx.x;
        357 this.right += tx.x;
        358 this.top += tx.y;
        359 this.bottom += tx.y;
        360 } else {
        361 this.left += tx;
        362 this.right += tx;
        363 if (goog.isNumber(opt_ty)) {
        364 this.top += opt_ty;
        365 this.bottom += opt_ty;
        366 }
        367 }
        368 return this;
        369};
        370
        371
        372/**
        373 * Scales this coordinate by the given scale factors. The x and y dimension
        374 * values are scaled by {@code sx} and {@code opt_sy} respectively.
        375 * If {@code opt_sy} is not given, then {@code sx} is used for both x and y.
        376 *
        377 * @param {number} sx The scale factor to use for the x dimension.
        378 * @param {number=} opt_sy The scale factor to use for the y dimension.
        379 * @return {!goog.math.Box} This box after scaling.
        380 */
        381goog.math.Box.prototype.scale = function(sx, opt_sy) {
        382 var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
        383 this.left *= sx;
        384 this.right *= sx;
        385 this.top *= sy;
        386 this.bottom *= sy;
        387 return this;
        388};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/math/coordinate.js.src.html b/docs/api/javascript/source/lib/goog/math/coordinate.js.src.html new file mode 100644 index 0000000000000..70ab6df64682a --- /dev/null +++ b/docs/api/javascript/source/lib/goog/math/coordinate.js.src.html @@ -0,0 +1 @@ +coordinate.js

        lib/goog/math/coordinate.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 A utility class for representing two-dimensional positions.
        17 */
        18
        19
        20goog.provide('goog.math.Coordinate');
        21
        22goog.require('goog.math');
        23
        24
        25
        26/**
        27 * Class for representing coordinates and positions.
        28 * @param {number=} opt_x Left, defaults to 0.
        29 * @param {number=} opt_y Top, defaults to 0.
        30 * @constructor
        31 */
        32goog.math.Coordinate = function(opt_x, opt_y) {
        33 /**
        34 * X-value
        35 * @type {number}
        36 */
        37 this.x = goog.isDef(opt_x) ? opt_x : 0;
        38
        39 /**
        40 * Y-value
        41 * @type {number}
        42 */
        43 this.y = goog.isDef(opt_y) ? opt_y : 0;
        44};
        45
        46
        47/**
        48 * Returns a new copy of the coordinate.
        49 * @return {!goog.math.Coordinate} A clone of this coordinate.
        50 */
        51goog.math.Coordinate.prototype.clone = function() {
        52 return new goog.math.Coordinate(this.x, this.y);
        53};
        54
        55
        56if (goog.DEBUG) {
        57 /**
        58 * Returns a nice string representing the coordinate.
        59 * @return {string} In the form (50, 73).
        60 * @override
        61 */
        62 goog.math.Coordinate.prototype.toString = function() {
        63 return '(' + this.x + ', ' + this.y + ')';
        64 };
        65}
        66
        67
        68/**
        69 * Compares coordinates for equality.
        70 * @param {goog.math.Coordinate} a A Coordinate.
        71 * @param {goog.math.Coordinate} b A Coordinate.
        72 * @return {boolean} True iff the coordinates are equal, or if both are null.
        73 */
        74goog.math.Coordinate.equals = function(a, b) {
        75 if (a == b) {
        76 return true;
        77 }
        78 if (!a || !b) {
        79 return false;
        80 }
        81 return a.x == b.x && a.y == b.y;
        82};
        83
        84
        85/**
        86 * Returns the distance between two coordinates.
        87 * @param {!goog.math.Coordinate} a A Coordinate.
        88 * @param {!goog.math.Coordinate} b A Coordinate.
        89 * @return {number} The distance between {@code a} and {@code b}.
        90 */
        91goog.math.Coordinate.distance = function(a, b) {
        92 var dx = a.x - b.x;
        93 var dy = a.y - b.y;
        94 return Math.sqrt(dx * dx + dy * dy);
        95};
        96
        97
        98/**
        99 * Returns the magnitude of a coordinate.
        100 * @param {!goog.math.Coordinate} a A Coordinate.
        101 * @return {number} The distance between the origin and {@code a}.
        102 */
        103goog.math.Coordinate.magnitude = function(a) {
        104 return Math.sqrt(a.x * a.x + a.y * a.y);
        105};
        106
        107
        108/**
        109 * Returns the angle from the origin to a coordinate.
        110 * @param {!goog.math.Coordinate} a A Coordinate.
        111 * @return {number} The angle, in degrees, clockwise from the positive X
        112 * axis to {@code a}.
        113 */
        114goog.math.Coordinate.azimuth = function(a) {
        115 return goog.math.angle(0, 0, a.x, a.y);
        116};
        117
        118
        119/**
        120 * Returns the squared distance between two coordinates. Squared distances can
        121 * be used for comparisons when the actual value is not required.
        122 *
        123 * Performance note: eliminating the square root is an optimization often used
        124 * in lower-level languages, but the speed difference is not nearly as
        125 * pronounced in JavaScript (only a few percent.)
        126 *
        127 * @param {!goog.math.Coordinate} a A Coordinate.
        128 * @param {!goog.math.Coordinate} b A Coordinate.
        129 * @return {number} The squared distance between {@code a} and {@code b}.
        130 */
        131goog.math.Coordinate.squaredDistance = function(a, b) {
        132 var dx = a.x - b.x;
        133 var dy = a.y - b.y;
        134 return dx * dx + dy * dy;
        135};
        136
        137
        138/**
        139 * Returns the difference between two coordinates as a new
        140 * goog.math.Coordinate.
        141 * @param {!goog.math.Coordinate} a A Coordinate.
        142 * @param {!goog.math.Coordinate} b A Coordinate.
        143 * @return {!goog.math.Coordinate} A Coordinate representing the difference
        144 * between {@code a} and {@code b}.
        145 */
        146goog.math.Coordinate.difference = function(a, b) {
        147 return new goog.math.Coordinate(a.x - b.x, a.y - b.y);
        148};
        149
        150
        151/**
        152 * Returns the sum of two coordinates as a new goog.math.Coordinate.
        153 * @param {!goog.math.Coordinate} a A Coordinate.
        154 * @param {!goog.math.Coordinate} b A Coordinate.
        155 * @return {!goog.math.Coordinate} A Coordinate representing the sum of the two
        156 * coordinates.
        157 */
        158goog.math.Coordinate.sum = function(a, b) {
        159 return new goog.math.Coordinate(a.x + b.x, a.y + b.y);
        160};
        161
        162
        163/**
        164 * Rounds the x and y fields to the next larger integer values.
        165 * @return {!goog.math.Coordinate} This coordinate with ceil'd fields.
        166 */
        167goog.math.Coordinate.prototype.ceil = function() {
        168 this.x = Math.ceil(this.x);
        169 this.y = Math.ceil(this.y);
        170 return this;
        171};
        172
        173
        174/**
        175 * Rounds the x and y fields to the next smaller integer values.
        176 * @return {!goog.math.Coordinate} This coordinate with floored fields.
        177 */
        178goog.math.Coordinate.prototype.floor = function() {
        179 this.x = Math.floor(this.x);
        180 this.y = Math.floor(this.y);
        181 return this;
        182};
        183
        184
        185/**
        186 * Rounds the x and y fields to the nearest integer values.
        187 * @return {!goog.math.Coordinate} This coordinate with rounded fields.
        188 */
        189goog.math.Coordinate.prototype.round = function() {
        190 this.x = Math.round(this.x);
        191 this.y = Math.round(this.y);
        192 return this;
        193};
        194
        195
        196/**
        197 * Translates this box by the given offsets. If a {@code goog.math.Coordinate}
        198 * is given, then the x and y values are translated by the coordinate's x and y.
        199 * Otherwise, x and y are translated by {@code tx} and {@code opt_ty}
        200 * respectively.
        201 * @param {number|goog.math.Coordinate} tx The value to translate x by or the
        202 * the coordinate to translate this coordinate by.
        203 * @param {number=} opt_ty The value to translate y by.
        204 * @return {!goog.math.Coordinate} This coordinate after translating.
        205 */
        206goog.math.Coordinate.prototype.translate = function(tx, opt_ty) {
        207 if (tx instanceof goog.math.Coordinate) {
        208 this.x += tx.x;
        209 this.y += tx.y;
        210 } else {
        211 this.x += tx;
        212 if (goog.isNumber(opt_ty)) {
        213 this.y += opt_ty;
        214 }
        215 }
        216 return this;
        217};
        218
        219
        220/**
        221 * Scales this coordinate by the given scale factors. The x and y values are
        222 * scaled by {@code sx} and {@code opt_sy} respectively. If {@code opt_sy}
        223 * is not given, then {@code sx} is used for both x and y.
        224 * @param {number} sx The scale factor to use for the x dimension.
        225 * @param {number=} opt_sy The scale factor to use for the y dimension.
        226 * @return {!goog.math.Coordinate} This coordinate after scaling.
        227 */
        228goog.math.Coordinate.prototype.scale = function(sx, opt_sy) {
        229 var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
        230 this.x *= sx;
        231 this.y *= sy;
        232 return this;
        233};
        234
        235
        236/**
        237 * Rotates this coordinate clockwise about the origin (or, optionally, the given
        238 * center) by the given angle, in radians.
        239 * @param {number} radians The angle by which to rotate this coordinate
        240 * clockwise about the given center, in radians.
        241 * @param {!goog.math.Coordinate=} opt_center The center of rotation. Defaults
        242 * to (0, 0) if not given.
        243 */
        244goog.math.Coordinate.prototype.rotateRadians = function(radians, opt_center) {
        245 var center = opt_center || new goog.math.Coordinate(0, 0);
        246
        247 var x = this.x;
        248 var y = this.y;
        249 var cos = Math.cos(radians);
        250 var sin = Math.sin(radians);
        251
        252 this.x = (x - center.x) * cos - (y - center.y) * sin + center.x;
        253 this.y = (x - center.x) * sin + (y - center.y) * cos + center.y;
        254};
        255
        256
        257/**
        258 * Rotates this coordinate clockwise about the origin (or, optionally, the given
        259 * center) by the given angle, in degrees.
        260 * @param {number} degrees The angle by which to rotate this coordinate
        261 * clockwise about the given center, in degrees.
        262 * @param {!goog.math.Coordinate=} opt_center The center of rotation. Defaults
        263 * to (0, 0) if not given.
        264 */
        265goog.math.Coordinate.prototype.rotateDegrees = function(degrees, opt_center) {
        266 this.rotateRadians(goog.math.toRadians(degrees), opt_center);
        267};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/math/math.js.src.html b/docs/api/javascript/source/lib/goog/math/math.js.src.html index 605957d8577e9..9a911cd23657d 100644 --- a/docs/api/javascript/source/lib/goog/math/math.js.src.html +++ b/docs/api/javascript/source/lib/goog/math/math.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/math/rect.js.src.html b/docs/api/javascript/source/lib/goog/math/rect.js.src.html new file mode 100644 index 0000000000000..4427f71cabab5 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/math/rect.js.src.html @@ -0,0 +1 @@ +rect.js

        lib/goog/math/rect.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 A utility class for representing rectangles.
        17 */
        18
        19goog.provide('goog.math.Rect');
        20
        21goog.require('goog.math.Box');
        22goog.require('goog.math.Coordinate');
        23goog.require('goog.math.Size');
        24
        25
        26
        27/**
        28 * Class for representing rectangular regions.
        29 * @param {number} x Left.
        30 * @param {number} y Top.
        31 * @param {number} w Width.
        32 * @param {number} h Height.
        33 * @constructor
        34 */
        35goog.math.Rect = function(x, y, w, h) {
        36 /** @type {number} */
        37 this.left = x;
        38
        39 /** @type {number} */
        40 this.top = y;
        41
        42 /** @type {number} */
        43 this.width = w;
        44
        45 /** @type {number} */
        46 this.height = h;
        47};
        48
        49
        50/**
        51 * @return {!goog.math.Rect} A new copy of this Rectangle.
        52 */
        53goog.math.Rect.prototype.clone = function() {
        54 return new goog.math.Rect(this.left, this.top, this.width, this.height);
        55};
        56
        57
        58/**
        59 * Returns a new Box object with the same position and dimensions as this
        60 * rectangle.
        61 * @return {!goog.math.Box} A new Box representation of this Rectangle.
        62 */
        63goog.math.Rect.prototype.toBox = function() {
        64 var right = this.left + this.width;
        65 var bottom = this.top + this.height;
        66 return new goog.math.Box(this.top,
        67 right,
        68 bottom,
        69 this.left);
        70};
        71
        72
        73/**
        74 * Creates a new Rect object with the same position and dimensions as a given
        75 * Box. Note that this is only the inverse of toBox if left/top are defined.
        76 * @param {goog.math.Box} box A box.
        77 * @return {!goog.math.Rect} A new Rect initialized with the box's position
        78 * and size.
        79 */
        80goog.math.Rect.createFromBox = function(box) {
        81 return new goog.math.Rect(box.left, box.top,
        82 box.right - box.left, box.bottom - box.top);
        83};
        84
        85
        86if (goog.DEBUG) {
        87 /**
        88 * Returns a nice string representing size and dimensions of rectangle.
        89 * @return {string} In the form (50, 73 - 75w x 25h).
        90 * @override
        91 */
        92 goog.math.Rect.prototype.toString = function() {
        93 return '(' + this.left + ', ' + this.top + ' - ' + this.width + 'w x ' +
        94 this.height + 'h)';
        95 };
        96}
        97
        98
        99/**
        100 * Compares rectangles for equality.
        101 * @param {goog.math.Rect} a A Rectangle.
        102 * @param {goog.math.Rect} b A Rectangle.
        103 * @return {boolean} True iff the rectangles have the same left, top, width,
        104 * and height, or if both are null.
        105 */
        106goog.math.Rect.equals = function(a, b) {
        107 if (a == b) {
        108 return true;
        109 }
        110 if (!a || !b) {
        111 return false;
        112 }
        113 return a.left == b.left && a.width == b.width &&
        114 a.top == b.top && a.height == b.height;
        115};
        116
        117
        118/**
        119 * Computes the intersection of this rectangle and the rectangle parameter. If
        120 * there is no intersection, returns false and leaves this rectangle as is.
        121 * @param {goog.math.Rect} rect A Rectangle.
        122 * @return {boolean} True iff this rectangle intersects with the parameter.
        123 */
        124goog.math.Rect.prototype.intersection = function(rect) {
        125 var x0 = Math.max(this.left, rect.left);
        126 var x1 = Math.min(this.left + this.width, rect.left + rect.width);
        127
        128 if (x0 <= x1) {
        129 var y0 = Math.max(this.top, rect.top);
        130 var y1 = Math.min(this.top + this.height, rect.top + rect.height);
        131
        132 if (y0 <= y1) {
        133 this.left = x0;
        134 this.top = y0;
        135 this.width = x1 - x0;
        136 this.height = y1 - y0;
        137
        138 return true;
        139 }
        140 }
        141 return false;
        142};
        143
        144
        145/**
        146 * Returns the intersection of two rectangles. Two rectangles intersect if they
        147 * touch at all, for example, two zero width and height rectangles would
        148 * intersect if they had the same top and left.
        149 * @param {goog.math.Rect} a A Rectangle.
        150 * @param {goog.math.Rect} b A Rectangle.
        151 * @return {goog.math.Rect} A new intersection rect (even if width and height
        152 * are 0), or null if there is no intersection.
        153 */
        154goog.math.Rect.intersection = function(a, b) {
        155 // There is no nice way to do intersection via a clone, because any such
        156 // clone might be unnecessary if this function returns null. So, we duplicate
        157 // code from above.
        158
        159 var x0 = Math.max(a.left, b.left);
        160 var x1 = Math.min(a.left + a.width, b.left + b.width);
        161
        162 if (x0 <= x1) {
        163 var y0 = Math.max(a.top, b.top);
        164 var y1 = Math.min(a.top + a.height, b.top + b.height);
        165
        166 if (y0 <= y1) {
        167 return new goog.math.Rect(x0, y0, x1 - x0, y1 - y0);
        168 }
        169 }
        170 return null;
        171};
        172
        173
        174/**
        175 * Returns whether two rectangles intersect. Two rectangles intersect if they
        176 * touch at all, for example, two zero width and height rectangles would
        177 * intersect if they had the same top and left.
        178 * @param {goog.math.Rect} a A Rectangle.
        179 * @param {goog.math.Rect} b A Rectangle.
        180 * @return {boolean} Whether a and b intersect.
        181 */
        182goog.math.Rect.intersects = function(a, b) {
        183 return (a.left <= b.left + b.width && b.left <= a.left + a.width &&
        184 a.top <= b.top + b.height && b.top <= a.top + a.height);
        185};
        186
        187
        188/**
        189 * Returns whether a rectangle intersects this rectangle.
        190 * @param {goog.math.Rect} rect A rectangle.
        191 * @return {boolean} Whether rect intersects this rectangle.
        192 */
        193goog.math.Rect.prototype.intersects = function(rect) {
        194 return goog.math.Rect.intersects(this, rect);
        195};
        196
        197
        198/**
        199 * Computes the difference regions between two rectangles. The return value is
        200 * an array of 0 to 4 rectangles defining the remaining regions of the first
        201 * rectangle after the second has been subtracted.
        202 * @param {goog.math.Rect} a A Rectangle.
        203 * @param {goog.math.Rect} b A Rectangle.
        204 * @return {!Array.<!goog.math.Rect>} An array with 0 to 4 rectangles which
        205 * together define the difference area of rectangle a minus rectangle b.
        206 */
        207goog.math.Rect.difference = function(a, b) {
        208 var intersection = goog.math.Rect.intersection(a, b);
        209 if (!intersection || !intersection.height || !intersection.width) {
        210 return [a.clone()];
        211 }
        212
        213 var result = [];
        214
        215 var top = a.top;
        216 var height = a.height;
        217
        218 var ar = a.left + a.width;
        219 var ab = a.top + a.height;
        220
        221 var br = b.left + b.width;
        222 var bb = b.top + b.height;
        223
        224 // Subtract off any area on top where A extends past B
        225 if (b.top > a.top) {
        226 result.push(new goog.math.Rect(a.left, a.top, a.width, b.top - a.top));
        227 top = b.top;
        228 // If we're moving the top down, we also need to subtract the height diff.
        229 height -= b.top - a.top;
        230 }
        231 // Subtract off any area on bottom where A extends past B
        232 if (bb < ab) {
        233 result.push(new goog.math.Rect(a.left, bb, a.width, ab - bb));
        234 height = bb - top;
        235 }
        236 // Subtract any area on left where A extends past B
        237 if (b.left > a.left) {
        238 result.push(new goog.math.Rect(a.left, top, b.left - a.left, height));
        239 }
        240 // Subtract any area on right where A extends past B
        241 if (br < ar) {
        242 result.push(new goog.math.Rect(br, top, ar - br, height));
        243 }
        244
        245 return result;
        246};
        247
        248
        249/**
        250 * Computes the difference regions between this rectangle and {@code rect}. The
        251 * return value is an array of 0 to 4 rectangles defining the remaining regions
        252 * of this rectangle after the other has been subtracted.
        253 * @param {goog.math.Rect} rect A Rectangle.
        254 * @return {!Array.<!goog.math.Rect>} An array with 0 to 4 rectangles which
        255 * together define the difference area of rectangle a minus rectangle b.
        256 */
        257goog.math.Rect.prototype.difference = function(rect) {
        258 return goog.math.Rect.difference(this, rect);
        259};
        260
        261
        262/**
        263 * Expand this rectangle to also include the area of the given rectangle.
        264 * @param {goog.math.Rect} rect The other rectangle.
        265 */
        266goog.math.Rect.prototype.boundingRect = function(rect) {
        267 // We compute right and bottom before we change left and top below.
        268 var right = Math.max(this.left + this.width, rect.left + rect.width);
        269 var bottom = Math.max(this.top + this.height, rect.top + rect.height);
        270
        271 this.left = Math.min(this.left, rect.left);
        272 this.top = Math.min(this.top, rect.top);
        273
        274 this.width = right - this.left;
        275 this.height = bottom - this.top;
        276};
        277
        278
        279/**
        280 * Returns a new rectangle which completely contains both input rectangles.
        281 * @param {goog.math.Rect} a A rectangle.
        282 * @param {goog.math.Rect} b A rectangle.
        283 * @return {goog.math.Rect} A new bounding rect, or null if either rect is
        284 * null.
        285 */
        286goog.math.Rect.boundingRect = function(a, b) {
        287 if (!a || !b) {
        288 return null;
        289 }
        290
        291 var clone = a.clone();
        292 clone.boundingRect(b);
        293
        294 return clone;
        295};
        296
        297
        298/**
        299 * Tests whether this rectangle entirely contains another rectangle or
        300 * coordinate.
        301 *
        302 * @param {goog.math.Rect|goog.math.Coordinate} another The rectangle or
        303 * coordinate to test for containment.
        304 * @return {boolean} Whether this rectangle contains given rectangle or
        305 * coordinate.
        306 */
        307goog.math.Rect.prototype.contains = function(another) {
        308 if (another instanceof goog.math.Rect) {
        309 return this.left <= another.left &&
        310 this.left + this.width >= another.left + another.width &&
        311 this.top <= another.top &&
        312 this.top + this.height >= another.top + another.height;
        313 } else { // (another instanceof goog.math.Coordinate)
        314 return another.x >= this.left &&
        315 another.x <= this.left + this.width &&
        316 another.y >= this.top &&
        317 another.y <= this.top + this.height;
        318 }
        319};
        320
        321
        322/**
        323 * @param {!goog.math.Coordinate} point A coordinate.
        324 * @return {number} The squared distance between the point and the closest
        325 * point inside the rectangle. Returns 0 if the point is inside the
        326 * rectangle.
        327 */
        328goog.math.Rect.prototype.squaredDistance = function(point) {
        329 var dx = point.x < this.left ?
        330 this.left - point.x : Math.max(point.x - (this.left + this.width), 0);
        331 var dy = point.y < this.top ?
        332 this.top - point.y : Math.max(point.y - (this.top + this.height), 0);
        333 return dx * dx + dy * dy;
        334};
        335
        336
        337/**
        338 * @param {!goog.math.Coordinate} point A coordinate.
        339 * @return {number} The distance between the point and the closest point
        340 * inside the rectangle. Returns 0 if the point is inside the rectangle.
        341 */
        342goog.math.Rect.prototype.distance = function(point) {
        343 return Math.sqrt(this.squaredDistance(point));
        344};
        345
        346
        347/**
        348 * @return {!goog.math.Size} The size of this rectangle.
        349 */
        350goog.math.Rect.prototype.getSize = function() {
        351 return new goog.math.Size(this.width, this.height);
        352};
        353
        354
        355/**
        356 * @return {!goog.math.Coordinate} A new coordinate for the top-left corner of
        357 * the rectangle.
        358 */
        359goog.math.Rect.prototype.getTopLeft = function() {
        360 return new goog.math.Coordinate(this.left, this.top);
        361};
        362
        363
        364/**
        365 * @return {!goog.math.Coordinate} A new coordinate for the center of the
        366 * rectangle.
        367 */
        368goog.math.Rect.prototype.getCenter = function() {
        369 return new goog.math.Coordinate(
        370 this.left + this.width / 2, this.top + this.height / 2);
        371};
        372
        373
        374/**
        375 * @return {!goog.math.Coordinate} A new coordinate for the bottom-right corner
        376 * of the rectangle.
        377 */
        378goog.math.Rect.prototype.getBottomRight = function() {
        379 return new goog.math.Coordinate(
        380 this.left + this.width, this.top + this.height);
        381};
        382
        383
        384/**
        385 * Rounds the fields to the next larger integer values.
        386 * @return {!goog.math.Rect} This rectangle with ceil'd fields.
        387 */
        388goog.math.Rect.prototype.ceil = function() {
        389 this.left = Math.ceil(this.left);
        390 this.top = Math.ceil(this.top);
        391 this.width = Math.ceil(this.width);
        392 this.height = Math.ceil(this.height);
        393 return this;
        394};
        395
        396
        397/**
        398 * Rounds the fields to the next smaller integer values.
        399 * @return {!goog.math.Rect} This rectangle with floored fields.
        400 */
        401goog.math.Rect.prototype.floor = function() {
        402 this.left = Math.floor(this.left);
        403 this.top = Math.floor(this.top);
        404 this.width = Math.floor(this.width);
        405 this.height = Math.floor(this.height);
        406 return this;
        407};
        408
        409
        410/**
        411 * Rounds the fields to nearest integer values.
        412 * @return {!goog.math.Rect} This rectangle with rounded fields.
        413 */
        414goog.math.Rect.prototype.round = function() {
        415 this.left = Math.round(this.left);
        416 this.top = Math.round(this.top);
        417 this.width = Math.round(this.width);
        418 this.height = Math.round(this.height);
        419 return this;
        420};
        421
        422
        423/**
        424 * Translates this rectangle by the given offsets. If a
        425 * {@code goog.math.Coordinate} is given, then the left and top values are
        426 * translated by the coordinate's x and y values. Otherwise, top and left are
        427 * translated by {@code tx} and {@code opt_ty} respectively.
        428 * @param {number|goog.math.Coordinate} tx The value to translate left by or the
        429 * the coordinate to translate this rect by.
        430 * @param {number=} opt_ty The value to translate top by.
        431 * @return {!goog.math.Rect} This rectangle after translating.
        432 */
        433goog.math.Rect.prototype.translate = function(tx, opt_ty) {
        434 if (tx instanceof goog.math.Coordinate) {
        435 this.left += tx.x;
        436 this.top += tx.y;
        437 } else {
        438 this.left += tx;
        439 if (goog.isNumber(opt_ty)) {
        440 this.top += opt_ty;
        441 }
        442 }
        443 return this;
        444};
        445
        446
        447/**
        448 * Scales this rectangle by the given scale factors. The left and width values
        449 * are scaled by {@code sx} and the top and height values are scaled by
        450 * {@code opt_sy}. If {@code opt_sy} is not given, then all fields are scaled
        451 * by {@code sx}.
        452 * @param {number} sx The scale factor to use for the x dimension.
        453 * @param {number=} opt_sy The scale factor to use for the y dimension.
        454 * @return {!goog.math.Rect} This rectangle after scaling.
        455 */
        456goog.math.Rect.prototype.scale = function(sx, opt_sy) {
        457 var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
        458 this.left *= sx;
        459 this.width *= sx;
        460 this.top *= sy;
        461 this.height *= sy;
        462 return this;
        463};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/math/size.js.src.html b/docs/api/javascript/source/lib/goog/math/size.js.src.html new file mode 100644 index 0000000000000..d26bc9837c34c --- /dev/null +++ b/docs/api/javascript/source/lib/goog/math/size.js.src.html @@ -0,0 +1 @@ +size.js

        lib/goog/math/size.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 A utility class for representing two-dimensional sizes.
        17 */
        18
        19
        20goog.provide('goog.math.Size');
        21
        22
        23
        24/**
        25 * Class for representing sizes consisting of a width and height. Undefined
        26 * width and height support is deprecated and results in compiler warning.
        27 * @param {number} width Width.
        28 * @param {number} height Height.
        29 * @constructor
        30 */
        31goog.math.Size = function(width, height) {
        32 /**
        33 * Width
        34 * @type {number}
        35 */
        36 this.width = width;
        37
        38 /**
        39 * Height
        40 * @type {number}
        41 */
        42 this.height = height;
        43};
        44
        45
        46/**
        47 * Compares sizes for equality.
        48 * @param {goog.math.Size} a A Size.
        49 * @param {goog.math.Size} b A Size.
        50 * @return {boolean} True iff the sizes have equal widths and equal
        51 * heights, or if both are null.
        52 */
        53goog.math.Size.equals = function(a, b) {
        54 if (a == b) {
        55 return true;
        56 }
        57 if (!a || !b) {
        58 return false;
        59 }
        60 return a.width == b.width && a.height == b.height;
        61};
        62
        63
        64/**
        65 * @return {!goog.math.Size} A new copy of the Size.
        66 */
        67goog.math.Size.prototype.clone = function() {
        68 return new goog.math.Size(this.width, this.height);
        69};
        70
        71
        72if (goog.DEBUG) {
        73 /**
        74 * Returns a nice string representing size.
        75 * @return {string} In the form (50 x 73).
        76 * @override
        77 */
        78 goog.math.Size.prototype.toString = function() {
        79 return '(' + this.width + ' x ' + this.height + ')';
        80 };
        81}
        82
        83
        84/**
        85 * @return {number} The longer of the two dimensions in the size.
        86 */
        87goog.math.Size.prototype.getLongest = function() {
        88 return Math.max(this.width, this.height);
        89};
        90
        91
        92/**
        93 * @return {number} The shorter of the two dimensions in the size.
        94 */
        95goog.math.Size.prototype.getShortest = function() {
        96 return Math.min(this.width, this.height);
        97};
        98
        99
        100/**
        101 * @return {number} The area of the size (width * height).
        102 */
        103goog.math.Size.prototype.area = function() {
        104 return this.width * this.height;
        105};
        106
        107
        108/**
        109 * @return {number} The perimeter of the size (width + height) * 2.
        110 */
        111goog.math.Size.prototype.perimeter = function() {
        112 return (this.width + this.height) * 2;
        113};
        114
        115
        116/**
        117 * @return {number} The ratio of the size's width to its height.
        118 */
        119goog.math.Size.prototype.aspectRatio = function() {
        120 return this.width / this.height;
        121};
        122
        123
        124/**
        125 * @return {boolean} True if the size has zero area, false if both dimensions
        126 * are non-zero numbers.
        127 */
        128goog.math.Size.prototype.isEmpty = function() {
        129 return !this.area();
        130};
        131
        132
        133/**
        134 * Clamps the width and height parameters upward to integer values.
        135 * @return {!goog.math.Size} This size with ceil'd components.
        136 */
        137goog.math.Size.prototype.ceil = function() {
        138 this.width = Math.ceil(this.width);
        139 this.height = Math.ceil(this.height);
        140 return this;
        141};
        142
        143
        144/**
        145 * @param {!goog.math.Size} target The target size.
        146 * @return {boolean} True if this Size is the same size or smaller than the
        147 * target size in both dimensions.
        148 */
        149goog.math.Size.prototype.fitsInside = function(target) {
        150 return this.width <= target.width && this.height <= target.height;
        151};
        152
        153
        154/**
        155 * Clamps the width and height parameters downward to integer values.
        156 * @return {!goog.math.Size} This size with floored components.
        157 */
        158goog.math.Size.prototype.floor = function() {
        159 this.width = Math.floor(this.width);
        160 this.height = Math.floor(this.height);
        161 return this;
        162};
        163
        164
        165/**
        166 * Rounds the width and height parameters to integer values.
        167 * @return {!goog.math.Size} This size with rounded components.
        168 */
        169goog.math.Size.prototype.round = function() {
        170 this.width = Math.round(this.width);
        171 this.height = Math.round(this.height);
        172 return this;
        173};
        174
        175
        176/**
        177 * Scales this size by the given scale factors. The width and height are scaled
        178 * by {@code sx} and {@code opt_sy} respectively. If {@code opt_sy} is not
        179 * given, then {@code sx} is used for both the width and height.
        180 * @param {number} sx The scale factor to use for the width.
        181 * @param {number=} opt_sy The scale factor to use for the height.
        182 * @return {!goog.math.Size} This Size object after scaling.
        183 */
        184goog.math.Size.prototype.scale = function(sx, opt_sy) {
        185 var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
        186 this.width *= sx;
        187 this.height *= sy;
        188 return this;
        189};
        190
        191
        192/**
        193 * Uniformly scales the size to fit inside the dimensions of a given size. The
        194 * original aspect ratio will be preserved.
        195 *
        196 * This function assumes that both Sizes contain strictly positive dimensions.
        197 * @param {!goog.math.Size} target The target size.
        198 * @return {!goog.math.Size} This Size object, after optional scaling.
        199 */
        200goog.math.Size.prototype.scaleToFit = function(target) {
        201 var s = this.aspectRatio() > target.aspectRatio() ?
        202 target.width / this.width :
        203 target.height / this.height;
        204
        205 return this.scale(s);
        206};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html b/docs/api/javascript/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html index e59447a334bb0..71eee01e73e08 100644 --- a/docs/api/javascript/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html +++ b/docs/api/javascript/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/net/xhrlike.js.src.html b/docs/api/javascript/source/lib/goog/net/xhrlike.js.src.html index 09b2494d0d41c..d04d1464761c6 100644 --- a/docs/api/javascript/source/lib/goog/net/xhrlike.js.src.html +++ b/docs/api/javascript/source/lib/goog/net/xhrlike.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/net/xmlhttp.js.src.html b/docs/api/javascript/source/lib/goog/net/xmlhttp.js.src.html index 2388c37b06e2c..8e8647455403d 100644 --- a/docs/api/javascript/source/lib/goog/net/xmlhttp.js.src.html +++ b/docs/api/javascript/source/lib/goog/net/xmlhttp.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/net/xmlhttpfactory.js.src.html b/docs/api/javascript/source/lib/goog/net/xmlhttpfactory.js.src.html index 7a261c206c190..f022159348635 100644 --- a/docs/api/javascript/source/lib/goog/net/xmlhttpfactory.js.src.html +++ b/docs/api/javascript/source/lib/goog/net/xmlhttpfactory.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/object/object.js.src.html b/docs/api/javascript/source/lib/goog/object/object.js.src.html index 668f1a5f36f7f..7d341cf988964 100644 --- a/docs/api/javascript/source/lib/goog/object/object.js.src.html +++ b/docs/api/javascript/source/lib/goog/object/object.js.src.html @@ -1 +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 +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
        21goog.require('goog.array');
        22
        23
        24/**
        25 * Calls a function for each element in an object/map/hash.
        26 *
        27 * @param {Object.<K,V>} obj The object over which to iterate.
        28 * @param {function(this:T,V,?,Object.<K,V>):?} f The function to call
        29 * for every element. This function takes 3 arguments (the element, the
        30 * index and the object) and the return value is ignored.
        31 * @param {T=} opt_obj This is used as the 'this' object within f.
        32 * @template T,K,V
        33 */
        34goog.object.forEach = function(obj, f, opt_obj) {
        35 for (var key in obj) {
        36 f.call(opt_obj, obj[key], key, obj);
        37 }
        38};
        39
        40
        41/**
        42 * Calls a function for each element in an object/map/hash. If that call returns
        43 * true, adds the element to a new object.
        44 *
        45 * @param {Object.<K,V>} obj The object over which to iterate.
        46 * @param {function(this:T,V,?,Object.<K,V>):boolean} f The function to call
        47 * for every element. This
        48 * function takes 3 arguments (the element, the index and the object)
        49 * and should return a boolean. If the return value is true the
        50 * element is added to the result object. If it is false the
        51 * element is not included.
        52 * @param {T=} opt_obj This is used as the 'this' object within f.
        53 * @return {!Object.<K,V>} a new object in which only elements that passed the
        54 * test are present.
        55 * @template T,K,V
        56 */
        57goog.object.filter = function(obj, f, opt_obj) {
        58 var res = {};
        59 for (var key in obj) {
        60 if (f.call(opt_obj, obj[key], key, obj)) {
        61 res[key] = obj[key];
        62 }
        63 }
        64 return res;
        65};
        66
        67
        68/**
        69 * For every element in an object/map/hash calls a function and inserts the
        70 * result into a new object.
        71 *
        72 * @param {Object.<K,V>} obj The object over which to iterate.
        73 * @param {function(this:T,V,?,Object.<K,V>):R} f The function to call
        74 * for every element. This function
        75 * takes 3 arguments (the element, the index and the object)
        76 * and should return something. The result will be inserted
        77 * into a new object.
        78 * @param {T=} opt_obj This is used as the 'this' object within f.
        79 * @return {!Object.<K,R>} a new object with the results from f.
        80 * @template T,K,V,R
        81 */
        82goog.object.map = function(obj, f, opt_obj) {
        83 var res = {};
        84 for (var key in obj) {
        85 res[key] = f.call(opt_obj, obj[key], key, obj);
        86 }
        87 return res;
        88};
        89
        90
        91/**
        92 * Calls a function for each element in an object/map/hash. If any
        93 * call returns true, returns true (without checking the rest). If
        94 * all calls return false, returns false.
        95 *
        96 * @param {Object.<K,V>} obj The object to check.
        97 * @param {function(this:T,V,?,Object.<K,V>):boolean} f The function to
        98 * call for every element. This function
        99 * takes 3 arguments (the element, the index and the object) and should
        100 * return a boolean.
        101 * @param {T=} opt_obj This is used as the 'this' object within f.
        102 * @return {boolean} true if any element passes the test.
        103 * @template T,K,V
        104 */
        105goog.object.some = function(obj, f, opt_obj) {
        106 for (var key in obj) {
        107 if (f.call(opt_obj, obj[key], key, obj)) {
        108 return true;
        109 }
        110 }
        111 return false;
        112};
        113
        114
        115/**
        116 * Calls a function for each element in an object/map/hash. If
        117 * all calls return true, returns true. If any call returns false, returns
        118 * false at this point and does not continue to check the remaining elements.
        119 *
        120 * @param {Object.<K,V>} obj The object to check.
        121 * @param {?function(this:T,V,?,Object.<K,V>):boolean} f The function to
        122 * call for every element. This function
        123 * takes 3 arguments (the element, the index and the object) and should
        124 * return a boolean.
        125 * @param {T=} opt_obj This is used as the 'this' object within f.
        126 * @return {boolean} false if any element fails the test.
        127 * @template T,K,V
        128 */
        129goog.object.every = function(obj, f, opt_obj) {
        130 for (var key in obj) {
        131 if (!f.call(opt_obj, obj[key], key, obj)) {
        132 return false;
        133 }
        134 }
        135 return true;
        136};
        137
        138
        139/**
        140 * Returns the number of key-value pairs in the object map.
        141 *
        142 * @param {Object} obj The object for which to get the number of key-value
        143 * pairs.
        144 * @return {number} The number of key-value pairs in the object map.
        145 */
        146goog.object.getCount = function(obj) {
        147 // JS1.5 has __count__ but it has been deprecated so it raises a warning...
        148 // in other words do not use. Also __count__ only includes the fields on the
        149 // actual object and not in the prototype chain.
        150 var rv = 0;
        151 for (var key in obj) {
        152 rv++;
        153 }
        154 return rv;
        155};
        156
        157
        158/**
        159 * Returns one key from the object map, if any exists.
        160 * For map literals the returned key will be the first one in most of the
        161 * browsers (a know exception is Konqueror).
        162 *
        163 * @param {Object} obj The object to pick a key from.
        164 * @return {string|undefined} The key or undefined if the object is empty.
        165 */
        166goog.object.getAnyKey = function(obj) {
        167 for (var key in obj) {
        168 return key;
        169 }
        170};
        171
        172
        173/**
        174 * Returns one value from the object map, if any exists.
        175 * For map literals the returned value will be the first one in most of the
        176 * browsers (a know exception is Konqueror).
        177 *
        178 * @param {Object.<K,V>} obj The object to pick a value from.
        179 * @return {V|undefined} The value or undefined if the object is empty.
        180 * @template K,V
        181 */
        182goog.object.getAnyValue = function(obj) {
        183 for (var key in obj) {
        184 return obj[key];
        185 }
        186};
        187
        188
        189/**
        190 * Whether the object/hash/map contains the given object as a value.
        191 * An alias for goog.object.containsValue(obj, val).
        192 *
        193 * @param {Object.<K,V>} obj The object in which to look for val.
        194 * @param {V} val The object for which to check.
        195 * @return {boolean} true if val is present.
        196 * @template K,V
        197 */
        198goog.object.contains = function(obj, val) {
        199 return goog.object.containsValue(obj, val);
        200};
        201
        202
        203/**
        204 * Returns the values of the object/map/hash.
        205 *
        206 * @param {Object.<K,V>} obj The object from which to get the values.
        207 * @return {!Array.<V>} The values in the object/map/hash.
        208 * @template K,V
        209 */
        210goog.object.getValues = function(obj) {
        211 var res = [];
        212 var i = 0;
        213 for (var key in obj) {
        214 res[i++] = obj[key];
        215 }
        216 return res;
        217};
        218
        219
        220/**
        221 * Returns the keys of the object/map/hash.
        222 *
        223 * @param {Object} obj The object from which to get the keys.
        224 * @return {!Array.<string>} Array of property keys.
        225 */
        226goog.object.getKeys = function(obj) {
        227 var res = [];
        228 var i = 0;
        229 for (var key in obj) {
        230 res[i++] = key;
        231 }
        232 return res;
        233};
        234
        235
        236/**
        237 * Get a value from an object multiple levels deep. This is useful for
        238 * pulling values from deeply nested objects, such as JSON responses.
        239 * Example usage: getValueByKeys(jsonObj, 'foo', 'entries', 3)
        240 *
        241 * @param {!Object} obj An object to get the value from. Can be array-like.
        242 * @param {...(string|number|!Array.<number|string>)} var_args A number of keys
        243 * (as strings, or numbers, for array-like objects). Can also be
        244 * specified as a single array of keys.
        245 * @return {*} The resulting value. If, at any point, the value for a key
        246 * is undefined, returns undefined.
        247 */
        248goog.object.getValueByKeys = function(obj, var_args) {
        249 var isArrayLike = goog.isArrayLike(var_args);
        250 var keys = isArrayLike ? var_args : arguments;
        251
        252 // Start with the 2nd parameter for the variable parameters syntax.
        253 for (var i = isArrayLike ? 0 : 1; i < keys.length; i++) {
        254 obj = obj[keys[i]];
        255 if (!goog.isDef(obj)) {
        256 break;
        257 }
        258 }
        259
        260 return obj;
        261};
        262
        263
        264/**
        265 * Whether the object/map/hash contains the given key.
        266 *
        267 * @param {Object} obj The object in which to look for key.
        268 * @param {*} key The key for which to check.
        269 * @return {boolean} true If the map contains the key.
        270 */
        271goog.object.containsKey = function(obj, key) {
        272 return key in obj;
        273};
        274
        275
        276/**
        277 * Whether the object/map/hash contains the given value. This is O(n).
        278 *
        279 * @param {Object.<K,V>} obj The object in which to look for val.
        280 * @param {V} val The value for which to check.
        281 * @return {boolean} true If the map contains the value.
        282 * @template K,V
        283 */
        284goog.object.containsValue = function(obj, val) {
        285 for (var key in obj) {
        286 if (obj[key] == val) {
        287 return true;
        288 }
        289 }
        290 return false;
        291};
        292
        293
        294/**
        295 * Searches an object for an element that satisfies the given condition and
        296 * returns its key.
        297 * @param {Object.<K,V>} obj The object to search in.
        298 * @param {function(this:T,V,string,Object.<K,V>):boolean} f The
        299 * function to call for every element. Takes 3 arguments (the value,
        300 * the key and the object) and should return a boolean.
        301 * @param {T=} opt_this An optional "this" context for the function.
        302 * @return {string|undefined} The key of an element for which the function
        303 * returns true or undefined if no such element is found.
        304 * @template T,K,V
        305 */
        306goog.object.findKey = function(obj, f, opt_this) {
        307 for (var key in obj) {
        308 if (f.call(opt_this, obj[key], key, obj)) {
        309 return key;
        310 }
        311 }
        312 return undefined;
        313};
        314
        315
        316/**
        317 * Searches an object for an element that satisfies the given condition and
        318 * returns its value.
        319 * @param {Object.<K,V>} obj The object to search in.
        320 * @param {function(this:T,V,string,Object.<K,V>):boolean} f The function
        321 * to call for every element. Takes 3 arguments (the value, the key
        322 * and the object) and should return a boolean.
        323 * @param {T=} opt_this An optional "this" context for the function.
        324 * @return {V} The value of an element for which the function returns true or
        325 * undefined if no such element is found.
        326 * @template T,K,V
        327 */
        328goog.object.findValue = function(obj, f, opt_this) {
        329 var key = goog.object.findKey(obj, f, opt_this);
        330 return key && obj[key];
        331};
        332
        333
        334/**
        335 * Whether the object/map/hash is empty.
        336 *
        337 * @param {Object} obj The object to test.
        338 * @return {boolean} true if obj is empty.
        339 */
        340goog.object.isEmpty = function(obj) {
        341 for (var key in obj) {
        342 return false;
        343 }
        344 return true;
        345};
        346
        347
        348/**
        349 * Removes all key value pairs from the object/map/hash.
        350 *
        351 * @param {Object} obj The object to clear.
        352 */
        353goog.object.clear = function(obj) {
        354 for (var i in obj) {
        355 delete obj[i];
        356 }
        357};
        358
        359
        360/**
        361 * Removes a key-value pair based on the key.
        362 *
        363 * @param {Object} obj The object from which to remove the key.
        364 * @param {*} key The key to remove.
        365 * @return {boolean} Whether an element was removed.
        366 */
        367goog.object.remove = function(obj, key) {
        368 var rv;
        369 if ((rv = key in obj)) {
        370 delete obj[key];
        371 }
        372 return rv;
        373};
        374
        375
        376/**
        377 * Adds a key-value pair to the object. Throws an exception if the key is
        378 * already in use. Use set if you want to change an existing pair.
        379 *
        380 * @param {Object.<K,V>} obj The object to which to add the key-value pair.
        381 * @param {string} key The key to add.
        382 * @param {V} val The value to add.
        383 * @template K,V
        384 */
        385goog.object.add = function(obj, key, val) {
        386 if (key in obj) {
        387 throw Error('The object already contains the key "' + key + '"');
        388 }
        389 goog.object.set(obj, key, val);
        390};
        391
        392
        393/**
        394 * Returns the value for the given key.
        395 *
        396 * @param {Object.<K,V>} obj The object from which to get the value.
        397 * @param {string} key The key for which to get the value.
        398 * @param {R=} opt_val The value to return if no item is found for the given
        399 * key (default is undefined).
        400 * @return {V|R|undefined} The value for the given key.
        401 * @template K,V,R
        402 */
        403goog.object.get = function(obj, key, opt_val) {
        404 if (key in obj) {
        405 return obj[key];
        406 }
        407 return opt_val;
        408};
        409
        410
        411/**
        412 * Adds a key-value pair to the object/map/hash.
        413 *
        414 * @param {Object.<K,V>} obj The object to which to add the key-value pair.
        415 * @param {string} key The key to add.
        416 * @param {V} value The value to add.
        417 * @template K,V
        418 */
        419goog.object.set = function(obj, key, value) {
        420 obj[key] = value;
        421};
        422
        423
        424/**
        425 * Adds a key-value pair to the object/map/hash if it doesn't exist yet.
        426 *
        427 * @param {Object.<K,V>} obj The object to which to add the key-value pair.
        428 * @param {string} key The key to add.
        429 * @param {V} value The value to add if the key wasn't present.
        430 * @return {V} The value of the entry at the end of the function.
        431 * @template K,V
        432 */
        433goog.object.setIfUndefined = function(obj, key, value) {
        434 return key in obj ? obj[key] : (obj[key] = value);
        435};
        436
        437
        438/**
        439 * Compares two objects for equality using === on the values.
        440 *
        441 * @param {!Object.<K,V>} a
        442 * @param {!Object.<K,V>} b
        443 * @return {boolean}
        444 * @template K,V
        445 */
        446goog.object.equals = function(a, b) {
        447 if (!goog.array.equals(goog.object.getKeys(a), goog.object.getKeys(b))) {
        448 return false;
        449 }
        450 for (var k in a) {
        451 if (a[k] !== b[k]) {
        452 return false;
        453 }
        454 }
        455 return true;
        456};
        457
        458
        459/**
        460 * Does a flat clone of the object.
        461 *
        462 * @param {Object.<K,V>} obj Object to clone.
        463 * @return {!Object.<K,V>} Clone of the input object.
        464 * @template K,V
        465 */
        466goog.object.clone = function(obj) {
        467 // We cannot use the prototype trick because a lot of methods depend on where
        468 // the actual key is set.
        469
        470 var res = {};
        471 for (var key in obj) {
        472 res[key] = obj[key];
        473 }
        474 return res;
        475 // We could also use goog.mixin but I wanted this to be independent from that.
        476};
        477
        478
        479/**
        480 * Clones a value. The input may be an Object, Array, or basic type. Objects and
        481 * arrays will be cloned recursively.
        482 *
        483 * WARNINGS:
        484 * <code>goog.object.unsafeClone</code> does not detect reference loops. Objects
        485 * that refer to themselves will cause infinite recursion.
        486 *
        487 * <code>goog.object.unsafeClone</code> is unaware of unique identifiers, and
        488 * copies UIDs created by <code>getUid</code> into cloned results.
        489 *
        490 * @param {*} obj The value to clone.
        491 * @return {*} A clone of the input value.
        492 */
        493goog.object.unsafeClone = function(obj) {
        494 var type = goog.typeOf(obj);
        495 if (type == 'object' || type == 'array') {
        496 if (obj.clone) {
        497 return obj.clone();
        498 }
        499 var clone = type == 'array' ? [] : {};
        500 for (var key in obj) {
        501 clone[key] = goog.object.unsafeClone(obj[key]);
        502 }
        503 return clone;
        504 }
        505
        506 return obj;
        507};
        508
        509
        510/**
        511 * Returns a new object in which all the keys and values are interchanged
        512 * (keys become values and values become keys). If multiple keys map to the
        513 * same value, the chosen transposed value is implementation-dependent.
        514 *
        515 * @param {Object} obj The object to transpose.
        516 * @return {!Object} The transposed object.
        517 */
        518goog.object.transpose = function(obj) {
        519 var transposed = {};
        520 for (var key in obj) {
        521 transposed[obj[key]] = key;
        522 }
        523 return transposed;
        524};
        525
        526
        527/**
        528 * The names of the fields that are defined on Object.prototype.
        529 * @type {Array.<string>}
        530 * @private
        531 */
        532goog.object.PROTOTYPE_FIELDS_ = [
        533 'constructor',
        534 'hasOwnProperty',
        535 'isPrototypeOf',
        536 'propertyIsEnumerable',
        537 'toLocaleString',
        538 'toString',
        539 'valueOf'
        540];
        541
        542
        543/**
        544 * Extends an object with another object.
        545 * This operates 'in-place'; it does not create a new Object.
        546 *
        547 * Example:
        548 * var o = {};
        549 * goog.object.extend(o, {a: 0, b: 1});
        550 * o; // {a: 0, b: 1}
        551 * goog.object.extend(o, {b: 2, c: 3});
        552 * o; // {a: 0, b: 2, c: 3}
        553 *
        554 * @param {Object} target The object to modify. Existing properties will be
        555 * overwritten if they are also present in one of the objects in
        556 * {@code var_args}.
        557 * @param {...Object} var_args The objects from which values will be copied.
        558 */
        559goog.object.extend = function(target, var_args) {
        560 var key, source;
        561 for (var i = 1; i < arguments.length; i++) {
        562 source = arguments[i];
        563 for (key in source) {
        564 target[key] = source[key];
        565 }
        566
        567 // For IE the for-in-loop does not contain any properties that are not
        568 // enumerable on the prototype object (for example isPrototypeOf from
        569 // Object.prototype) and it will also not include 'replace' on objects that
        570 // extend String and change 'replace' (not that it is common for anyone to
        571 // extend anything except Object).
        572
        573 for (var j = 0; j < goog.object.PROTOTYPE_FIELDS_.length; j++) {
        574 key = goog.object.PROTOTYPE_FIELDS_[j];
        575 if (Object.prototype.hasOwnProperty.call(source, key)) {
        576 target[key] = source[key];
        577 }
        578 }
        579 }
        580};
        581
        582
        583/**
        584 * Creates a new object built from the key-value pairs provided as arguments.
        585 * @param {...*} var_args If only one argument is provided and it is an array
        586 * then this is used as the arguments, otherwise even arguments are used as
        587 * the property names and odd arguments are used as the property values.
        588 * @return {!Object} The new object.
        589 * @throws {Error} If there are uneven number of arguments or there is only one
        590 * non array argument.
        591 */
        592goog.object.create = function(var_args) {
        593 var argLength = arguments.length;
        594 if (argLength == 1 && goog.isArray(arguments[0])) {
        595 return goog.object.create.apply(null, arguments[0]);
        596 }
        597
        598 if (argLength % 2) {
        599 throw Error('Uneven number of arguments');
        600 }
        601
        602 var rv = {};
        603 for (var i = 0; i < argLength; i += 2) {
        604 rv[arguments[i]] = arguments[i + 1];
        605 }
        606 return rv;
        607};
        608
        609
        610/**
        611 * Creates a new object where the property names come from the arguments but
        612 * the value is always set to true
        613 * @param {...*} var_args If only one argument is provided and it is an array
        614 * then this is used as the arguments, otherwise the arguments are used
        615 * as the property names.
        616 * @return {!Object} The new object.
        617 */
        618goog.object.createSet = function(var_args) {
        619 var argLength = arguments.length;
        620 if (argLength == 1 && goog.isArray(arguments[0])) {
        621 return goog.object.createSet.apply(null, arguments[0]);
        622 }
        623
        624 var rv = {};
        625 for (var i = 0; i < argLength; i++) {
        626 rv[arguments[i]] = true;
        627 }
        628 return rv;
        629};
        630
        631
        632/**
        633 * Creates an immutable view of the underlying object, if the browser
        634 * supports immutable objects.
        635 *
        636 * In default mode, writes to this view will fail silently. In strict mode,
        637 * they will throw an error.
        638 *
        639 * @param {!Object.<K,V>} obj An object.
        640 * @return {!Object.<K,V>} An immutable view of that object, or the
        641 * original object if this browser does not support immutables.
        642 * @template K,V
        643 */
        644goog.object.createImmutableView = function(obj) {
        645 var result = obj;
        646 if (Object.isFrozen && !Object.isFrozen(obj)) {
        647 result = Object.create(obj);
        648 Object.freeze(result);
        649 }
        650 return result;
        651};
        652
        653
        654/**
        655 * @param {!Object} obj An object.
        656 * @return {boolean} Whether this is an immutable view of the object.
        657 */
        658goog.object.isImmutableView = function(obj) {
        659 return !!Object.isFrozen && Object.isFrozen(obj);
        660};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/reflect/reflect.js.src.html b/docs/api/javascript/source/lib/goog/reflect/reflect.js.src.html new file mode 100644 index 0000000000000..96e523da1d9fc --- /dev/null +++ b/docs/api/javascript/source/lib/goog/reflect/reflect.js.src.html @@ -0,0 +1 @@ +reflect.js

        lib/goog/reflect/reflect.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 Useful compiler idioms.
        17 *
        18 */
        19
        20goog.provide('goog.reflect');
        21
        22
        23/**
        24 * Syntax for object literal casts.
        25 * @see http://go/jscompiler-renaming
        26 * @see http://code.google.com/p/closure-compiler/wiki/
        27 * ExperimentalTypeBasedPropertyRenaming
        28 *
        29 * Use this if you have an object literal whose keys need to have the same names
        30 * as the properties of some class even after they are renamed by the compiler.
        31 *
        32 * @param {!Function} type Type to cast to.
        33 * @param {Object} object Object literal to cast.
        34 * @return {Object} The object literal.
        35 */
        36goog.reflect.object = function(type, object) {
        37 return object;
        38};
        39
        40
        41/**
        42 * To assert to the compiler that an operation is needed when it would
        43 * otherwise be stripped. For example:
        44 * <code>
        45 * // Force a layout
        46 * goog.reflect.sinkValue(dialog.offsetHeight);
        47 * </code>
        48 * @type {!Function}
        49 */
        50goog.reflect.sinkValue = function(x) {
        51 goog.reflect.sinkValue[' '](x);
        52 return x;
        53};
        54
        55
        56/**
        57 * The compiler should optimize this function away iff no one ever uses
        58 * goog.reflect.sinkValue.
        59 */
        60goog.reflect.sinkValue[' '] = goog.nullFunction;
        61
        62
        63/**
        64 * Check if a property can be accessed without throwing an exception.
        65 * @param {Object} obj The owner of the property.
        66 * @param {string} prop The property name.
        67 * @return {boolean} Whether the property is accessible. Will also return true
        68 * if obj is null.
        69 */
        70goog.reflect.canAccessProperty = function(obj, prop) {
        71 /** @preserveTry */
        72 try {
        73 goog.reflect.sinkValue(obj[prop]);
        74 return true;
        75 } catch (e) {}
        76 return false;
        77};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/string/string.js.src.html b/docs/api/javascript/source/lib/goog/string/string.js.src.html index 2f743d5eb4f7f..3b56dc42e84df 100644 --- a/docs/api/javascript/source/lib/goog/string/string.js.src.html +++ b/docs/api/javascript/source/lib/goog/string/string.js.src.html @@ -1 +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 +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 * Determines whether a string contains a substring.
        970 * @param {string} str The string to search.
        971 * @param {string} subString The substring to search for.
        972 * @return {boolean} Whether {@code str} contains {@code subString}.
        973 */
        974goog.string.contains = function(str, subString) {
        975 return str.indexOf(subString) != -1;
        976};
        977
        978
        979/**
        980 * Determines whether a string contains a substring, ignoring case.
        981 * @param {string} str The string to search.
        982 * @param {string} subString The substring to search for.
        983 * @return {boolean} Whether {@code str} contains {@code subString}.
        984 */
        985goog.string.caseInsensitiveContains = function(str, subString) {
        986 return goog.string.contains(str.toLowerCase(), subString.toLowerCase());
        987};
        988
        989
        990/**
        991 * Returns the non-overlapping occurrences of ss in s.
        992 * If either s or ss evalutes to false, then returns zero.
        993 * @param {string} s The string to look in.
        994 * @param {string} ss The string to look for.
        995 * @return {number} Number of occurrences of ss in s.
        996 */
        997goog.string.countOf = function(s, ss) {
        998 return s && ss ? s.split(ss).length - 1 : 0;
        999};
        1000
        1001
        1002/**
        1003 * Removes a substring of a specified length at a specific
        1004 * index in a string.
        1005 * @param {string} s The base string from which to remove.
        1006 * @param {number} index The index at which to remove the substring.
        1007 * @param {number} stringLength The length of the substring to remove.
        1008 * @return {string} A copy of {@code s} with the substring removed or the full
        1009 * string if nothing is removed or the input is invalid.
        1010 */
        1011goog.string.removeAt = function(s, index, stringLength) {
        1012 var resultStr = s;
        1013 // If the index is greater or equal to 0 then remove substring
        1014 if (index >= 0 && index < s.length && stringLength > 0) {
        1015 resultStr = s.substr(0, index) +
        1016 s.substr(index + stringLength, s.length - index - stringLength);
        1017 }
        1018 return resultStr;
        1019};
        1020
        1021
        1022/**
        1023 * Removes the first occurrence of a substring from a string.
        1024 * @param {string} s The base string from which to remove.
        1025 * @param {string} ss The string to remove.
        1026 * @return {string} A copy of {@code s} with {@code ss} removed or the full
        1027 * string if nothing is removed.
        1028 */
        1029goog.string.remove = function(s, ss) {
        1030 var re = new RegExp(goog.string.regExpEscape(ss), '');
        1031 return s.replace(re, '');
        1032};
        1033
        1034
        1035/**
        1036 * Removes all occurrences of a substring from a string.
        1037 * @param {string} s The base string from which to remove.
        1038 * @param {string} ss The string to remove.
        1039 * @return {string} A copy of {@code s} with {@code ss} removed or the full
        1040 * string if nothing is removed.
        1041 */
        1042goog.string.removeAll = function(s, ss) {
        1043 var re = new RegExp(goog.string.regExpEscape(ss), 'g');
        1044 return s.replace(re, '');
        1045};
        1046
        1047
        1048/**
        1049 * Escapes characters in the string that are not safe to use in a RegExp.
        1050 * @param {*} s The string to escape. If not a string, it will be casted
        1051 * to one.
        1052 * @return {string} A RegExp safe, escaped copy of {@code s}.
        1053 */
        1054goog.string.regExpEscape = function(s) {
        1055 return String(s).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1').
        1056 replace(/\x08/g, '\\x08');
        1057};
        1058
        1059
        1060/**
        1061 * Repeats a string n times.
        1062 * @param {string} string The string to repeat.
        1063 * @param {number} length The number of times to repeat.
        1064 * @return {string} A string containing {@code length} repetitions of
        1065 * {@code string}.
        1066 */
        1067goog.string.repeat = function(string, length) {
        1068 return new Array(length + 1).join(string);
        1069};
        1070
        1071
        1072/**
        1073 * Pads number to given length and optionally rounds it to a given precision.
        1074 * For example:
        1075 * <pre>padNumber(1.25, 2, 3) -> '01.250'
        1076 * padNumber(1.25, 2) -> '01.25'
        1077 * padNumber(1.25, 2, 1) -> '01.3'
        1078 * padNumber(1.25, 0) -> '1.25'</pre>
        1079 *
        1080 * @param {number} num The number to pad.
        1081 * @param {number} length The desired length.
        1082 * @param {number=} opt_precision The desired precision.
        1083 * @return {string} {@code num} as a string with the given options.
        1084 */
        1085goog.string.padNumber = function(num, length, opt_precision) {
        1086 var s = goog.isDef(opt_precision) ? num.toFixed(opt_precision) : String(num);
        1087 var index = s.indexOf('.');
        1088 if (index == -1) {
        1089 index = s.length;
        1090 }
        1091 return goog.string.repeat('0', Math.max(0, length - index)) + s;
        1092};
        1093
        1094
        1095/**
        1096 * Returns a string representation of the given object, with
        1097 * null and undefined being returned as the empty string.
        1098 *
        1099 * @param {*} obj The object to convert.
        1100 * @return {string} A string representation of the {@code obj}.
        1101 */
        1102goog.string.makeSafe = function(obj) {
        1103 return obj == null ? '' : String(obj);
        1104};
        1105
        1106
        1107/**
        1108 * Concatenates string expressions. This is useful
        1109 * since some browsers are very inefficient when it comes to using plus to
        1110 * concat strings. Be careful when using null and undefined here since
        1111 * these will not be included in the result. If you need to represent these
        1112 * be sure to cast the argument to a String first.
        1113 * For example:
        1114 * <pre>buildString('a', 'b', 'c', 'd') -> 'abcd'
        1115 * buildString(null, undefined) -> ''
        1116 * </pre>
        1117 * @param {...*} var_args A list of strings to concatenate. If not a string,
        1118 * it will be casted to one.
        1119 * @return {string} The concatenation of {@code var_args}.
        1120 */
        1121goog.string.buildString = function(var_args) {
        1122 return Array.prototype.join.call(arguments, '');
        1123};
        1124
        1125
        1126/**
        1127 * Returns a string with at least 64-bits of randomness.
        1128 *
        1129 * Doesn't trust Javascript's random function entirely. Uses a combination of
        1130 * random and current timestamp, and then encodes the string in base-36 to
        1131 * make it shorter.
        1132 *
        1133 * @return {string} A random string, e.g. sn1s7vb4gcic.
        1134 */
        1135goog.string.getRandomString = function() {
        1136 var x = 2147483648;
        1137 return Math.floor(Math.random() * x).toString(36) +
        1138 Math.abs(Math.floor(Math.random() * x) ^ goog.now()).toString(36);
        1139};
        1140
        1141
        1142/**
        1143 * Compares two version numbers.
        1144 *
        1145 * @param {string|number} version1 Version of first item.
        1146 * @param {string|number} version2 Version of second item.
        1147 *
        1148 * @return {number} 1 if {@code version1} is higher.
        1149 * 0 if arguments are equal.
        1150 * -1 if {@code version2} is higher.
        1151 */
        1152goog.string.compareVersions = function(version1, version2) {
        1153 var order = 0;
        1154 // Trim leading and trailing whitespace and split the versions into
        1155 // subversions.
        1156 var v1Subs = goog.string.trim(String(version1)).split('.');
        1157 var v2Subs = goog.string.trim(String(version2)).split('.');
        1158 var subCount = Math.max(v1Subs.length, v2Subs.length);
        1159
        1160 // Iterate over the subversions, as long as they appear to be equivalent.
        1161 for (var subIdx = 0; order == 0 && subIdx < subCount; subIdx++) {
        1162 var v1Sub = v1Subs[subIdx] || '';
        1163 var v2Sub = v2Subs[subIdx] || '';
        1164
        1165 // Split the subversions into pairs of numbers and qualifiers (like 'b').
        1166 // Two different RegExp objects are needed because they are both using
        1167 // the 'g' flag.
        1168 var v1CompParser = new RegExp('(\\d*)(\\D*)', 'g');
        1169 var v2CompParser = new RegExp('(\\d*)(\\D*)', 'g');
        1170 do {
        1171 var v1Comp = v1CompParser.exec(v1Sub) || ['', '', ''];
        1172 var v2Comp = v2CompParser.exec(v2Sub) || ['', '', ''];
        1173 // Break if there are no more matches.
        1174 if (v1Comp[0].length == 0 && v2Comp[0].length == 0) {
        1175 break;
        1176 }
        1177
        1178 // Parse the numeric part of the subversion. A missing number is
        1179 // equivalent to 0.
        1180 var v1CompNum = v1Comp[1].length == 0 ? 0 : parseInt(v1Comp[1], 10);
        1181 var v2CompNum = v2Comp[1].length == 0 ? 0 : parseInt(v2Comp[1], 10);
        1182
        1183 // Compare the subversion components. The number has the highest
        1184 // precedence. Next, if the numbers are equal, a subversion without any
        1185 // qualifier is always higher than a subversion with any qualifier. Next,
        1186 // the qualifiers are compared as strings.
        1187 order = goog.string.compareElements_(v1CompNum, v2CompNum) ||
        1188 goog.string.compareElements_(v1Comp[2].length == 0,
        1189 v2Comp[2].length == 0) ||
        1190 goog.string.compareElements_(v1Comp[2], v2Comp[2]);
        1191 // Stop as soon as an inequality is discovered.
        1192 } while (order == 0);
        1193 }
        1194
        1195 return order;
        1196};
        1197
        1198
        1199/**
        1200 * Compares elements of a version number.
        1201 *
        1202 * @param {string|number|boolean} left An element from a version number.
        1203 * @param {string|number|boolean} right An element from a version number.
        1204 *
        1205 * @return {number} 1 if {@code left} is higher.
        1206 * 0 if arguments are equal.
        1207 * -1 if {@code right} is higher.
        1208 * @private
        1209 */
        1210goog.string.compareElements_ = function(left, right) {
        1211 if (left < right) {
        1212 return -1;
        1213 } else if (left > right) {
        1214 return 1;
        1215 }
        1216 return 0;
        1217};
        1218
        1219
        1220/**
        1221 * Maximum value of #goog.string.hashCode, exclusive. 2^32.
        1222 * @type {number}
        1223 * @private
        1224 */
        1225goog.string.HASHCODE_MAX_ = 0x100000000;
        1226
        1227
        1228/**
        1229 * String hash function similar to java.lang.String.hashCode().
        1230 * The hash code for a string is computed as
        1231 * s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1],
        1232 * where s[i] is the ith character of the string and n is the length of
        1233 * the string. We mod the result to make it between 0 (inclusive) and 2^32
        1234 * (exclusive).
        1235 * @param {string} str A string.
        1236 * @return {number} Hash value for {@code str}, between 0 (inclusive) and 2^32
        1237 * (exclusive). The empty string returns 0.
        1238 */
        1239goog.string.hashCode = function(str) {
        1240 var result = 0;
        1241 for (var i = 0; i < str.length; ++i) {
        1242 result = 31 * result + str.charCodeAt(i);
        1243 // Normalize to 4 byte range, 0 ... 2^32.
        1244 result %= goog.string.HASHCODE_MAX_;
        1245 }
        1246 return result;
        1247};
        1248
        1249
        1250/**
        1251 * The most recent unique ID. |0 is equivalent to Math.floor in this case.
        1252 * @type {number}
        1253 * @private
        1254 */
        1255goog.string.uniqueStringCounter_ = Math.random() * 0x80000000 | 0;
        1256
        1257
        1258/**
        1259 * Generates and returns a string which is unique in the current document.
        1260 * This is useful, for example, to create unique IDs for DOM elements.
        1261 * @return {string} A unique id.
        1262 */
        1263goog.string.createUniqueString = function() {
        1264 return 'goog_' + goog.string.uniqueStringCounter_++;
        1265};
        1266
        1267
        1268/**
        1269 * Converts the supplied string to a number, which may be Infinity or NaN.
        1270 * This function strips whitespace: (toNumber(' 123') === 123)
        1271 * This function accepts scientific notation: (toNumber('1e1') === 10)
        1272 *
        1273 * This is better than Javascript's built-in conversions because, sadly:
        1274 * (Number(' ') === 0) and (parseFloat('123a') === 123)
        1275 *
        1276 * @param {string} str The string to convert.
        1277 * @return {number} The number the supplied string represents, or NaN.
        1278 */
        1279goog.string.toNumber = function(str) {
        1280 var num = Number(str);
        1281 if (num == 0 && goog.string.isEmpty(str)) {
        1282 return NaN;
        1283 }
        1284 return num;
        1285};
        1286
        1287
        1288/**
        1289 * Returns whether the given string is lower camel case (e.g. "isFooBar").
        1290 *
        1291 * Note that this assumes the string is entirely letters.
        1292 * @see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms
        1293 *
        1294 * @param {string} str String to test.
        1295 * @return {boolean} Whether the string is lower camel case.
        1296 */
        1297goog.string.isLowerCamelCase = function(str) {
        1298 return /^[a-z]+([A-Z][a-z]*)*$/.test(str);
        1299};
        1300
        1301
        1302/**
        1303 * Returns whether the given string is upper camel case (e.g. "FooBarBaz").
        1304 *
        1305 * Note that this assumes the string is entirely letters.
        1306 * @see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms
        1307 *
        1308 * @param {string} str String to test.
        1309 * @return {boolean} Whether the string is upper camel case.
        1310 */
        1311goog.string.isUpperCamelCase = function(str) {
        1312 return /^([A-Z][a-z]*)+$/.test(str);
        1313};
        1314
        1315
        1316/**
        1317 * Converts a string from selector-case to camelCase (e.g. from
        1318 * "multi-part-string" to "multiPartString"), useful for converting
        1319 * CSS selectors and HTML dataset keys to their equivalent JS properties.
        1320 * @param {string} str The string in selector-case form.
        1321 * @return {string} The string in camelCase form.
        1322 */
        1323goog.string.toCamelCase = function(str) {
        1324 return String(str).replace(/\-([a-z])/g, function(all, match) {
        1325 return match.toUpperCase();
        1326 });
        1327};
        1328
        1329
        1330/**
        1331 * Converts a string from camelCase to selector-case (e.g. from
        1332 * "multiPartString" to "multi-part-string"), useful for converting JS
        1333 * style and dataset properties to equivalent CSS selectors and HTML keys.
        1334 * @param {string} str The string in camelCase form.
        1335 * @return {string} The string in selector-case form.
        1336 */
        1337goog.string.toSelectorCase = function(str) {
        1338 return String(str).replace(/([A-Z])/g, '-$1').toLowerCase();
        1339};
        1340
        1341
        1342/**
        1343 * Converts a string into TitleCase. First character of the string is always
        1344 * capitalized in addition to the first letter of every subsequent word.
        1345 * Words are delimited by one or more whitespaces by default. Custom delimiters
        1346 * can optionally be specified to replace the default, which doesn't preserve
        1347 * whitespace delimiters and instead must be explicitly included if needed.
        1348 *
        1349 * Default delimiter => " ":
        1350 * goog.string.toTitleCase('oneTwoThree') => 'OneTwoThree'
        1351 * goog.string.toTitleCase('one two three') => 'One Two Three'
        1352 * goog.string.toTitleCase(' one two ') => ' One Two '
        1353 * goog.string.toTitleCase('one_two_three') => 'One_two_three'
        1354 * goog.string.toTitleCase('one-two-three') => 'One-two-three'
        1355 *
        1356 * Custom delimiter => "_-.":
        1357 * goog.string.toTitleCase('oneTwoThree', '_-.') => 'OneTwoThree'
        1358 * goog.string.toTitleCase('one two three', '_-.') => 'One two three'
        1359 * goog.string.toTitleCase(' one two ', '_-.') => ' one two '
        1360 * goog.string.toTitleCase('one_two_three', '_-.') => 'One_Two_Three'
        1361 * goog.string.toTitleCase('one-two-three', '_-.') => 'One-Two-Three'
        1362 * goog.string.toTitleCase('one...two...three', '_-.') => 'One...Two...Three'
        1363 * goog.string.toTitleCase('one. two. three', '_-.') => 'One. two. three'
        1364 * goog.string.toTitleCase('one-two.three', '_-.') => 'One-Two.Three'
        1365 *
        1366 * @param {string} str String value in camelCase form.
        1367 * @param {string=} opt_delimiters Custom delimiter character set used to
        1368 * distinguish words in the string value. Each character represents a
        1369 * single delimiter. When provided, default whitespace delimiter is
        1370 * overridden and must be explicitly included if needed.
        1371 * @return {string} String value in TitleCase form.
        1372 */
        1373goog.string.toTitleCase = function(str, opt_delimiters) {
        1374 var delimiters = goog.isString(opt_delimiters) ?
        1375 goog.string.regExpEscape(opt_delimiters) : '\\s';
        1376
        1377 // For IE8, we need to prevent using an empty character set. Otherwise,
        1378 // incorrect matching will occur.
        1379 delimiters = delimiters ? '|[' + delimiters + ']+' : '';
        1380
        1381 var regexp = new RegExp('(^' + delimiters + ')([a-z])', 'g');
        1382 return str.replace(regexp, function(all, p1, p2) {
        1383 return p1 + p2.toUpperCase();
        1384 });
        1385};
        1386
        1387
        1388/**
        1389 * Parse a string in decimal or hexidecimal ('0xFFFF') form.
        1390 *
        1391 * To parse a particular radix, please use parseInt(string, radix) directly. See
        1392 * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/parseInt
        1393 *
        1394 * This is a wrapper for the built-in parseInt function that will only parse
        1395 * numbers as base 10 or base 16. Some JS implementations assume strings
        1396 * starting with "0" are intended to be octal. ES3 allowed but discouraged
        1397 * this behavior. ES5 forbids it. This function emulates the ES5 behavior.
        1398 *
        1399 * For more information, see Mozilla JS Reference: http://goo.gl/8RiFj
        1400 *
        1401 * @param {string|number|null|undefined} value The value to be parsed.
        1402 * @return {number} The number, parsed. If the string failed to parse, this
        1403 * will be NaN.
        1404 */
        1405goog.string.parseInt = function(value) {
        1406 // Force finite numbers to strings.
        1407 if (isFinite(value)) {
        1408 value = String(value);
        1409 }
        1410
        1411 if (goog.isString(value)) {
        1412 // If the string starts with '0x' or '-0x', parse as hex.
        1413 return /^\s*-?0x/i.test(value) ?
        1414 parseInt(value, 16) : parseInt(value, 10);
        1415 }
        1416
        1417 return NaN;
        1418};
        1419
        1420
        1421/**
        1422 * Splits a string on a separator a limited number of times.
        1423 *
        1424 * This implementation is more similar to Python or Java, where the limit
        1425 * parameter specifies the maximum number of splits rather than truncating
        1426 * the number of results.
        1427 *
        1428 * See http://docs.python.org/2/library/stdtypes.html#str.split
        1429 * See JavaDoc: http://goo.gl/F2AsY
        1430 * See Mozilla reference: http://goo.gl/dZdZs
        1431 *
        1432 * @param {string} str String to split.
        1433 * @param {string} separator The separator.
        1434 * @param {number} limit The limit to the number of splits. The resulting array
        1435 * will have a maximum length of limit+1. Negative numbers are the same
        1436 * as zero.
        1437 * @return {!Array.<string>} The string, split.
        1438 */
        1439
        1440goog.string.splitLimit = function(str, separator, limit) {
        1441 var parts = str.split(separator);
        1442 var returnVal = [];
        1443
        1444 // Only continue doing this while we haven't hit the limit and we have
        1445 // parts left.
        1446 while (limit > 0 && parts.length) {
        1447 returnVal.push(parts.shift());
        1448 limit--;
        1449 }
        1450
        1451 // If there are remaining parts, append them to the end.
        1452 if (parts.length) {
        1453 returnVal.push(parts.join(separator));
        1454 }
        1455
        1456 return returnVal;
        1457};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/structs/collection.js.src.html b/docs/api/javascript/source/lib/goog/structs/collection.js.src.html new file mode 100644 index 0000000000000..1dec5f70c733d --- /dev/null +++ b/docs/api/javascript/source/lib/goog/structs/collection.js.src.html @@ -0,0 +1 @@ +collection.js

        lib/goog/structs/collection.js

        1// Copyright 2011 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 Defines the collection interface.
        17 *
        18 * @author nnaze@google.com (Nathan Naze)
        19 */
        20
        21goog.provide('goog.structs.Collection');
        22
        23
        24
        25/**
        26 * An interface for a collection of values.
        27 * @interface
        28 * @template T
        29 */
        30goog.structs.Collection = function() {};
        31
        32
        33/**
        34 * @param {T} value Value to add to the collection.
        35 */
        36goog.structs.Collection.prototype.add;
        37
        38
        39/**
        40 * @param {T} value Value to remove from the collection.
        41 */
        42goog.structs.Collection.prototype.remove;
        43
        44
        45/**
        46 * @param {T} value Value to find in the collection.
        47 * @return {boolean} Whether the collection contains the specified value.
        48 */
        49goog.structs.Collection.prototype.contains;
        50
        51
        52/**
        53 * @return {number} The number of values stored in the collection.
        54 */
        55goog.structs.Collection.prototype.getCount;
        56
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/structs/map.js.src.html b/docs/api/javascript/source/lib/goog/structs/map.js.src.html index 4ad842a4bf18c..d1e4bb0fd2eba 100644 --- a/docs/api/javascript/source/lib/goog/structs/map.js.src.html +++ b/docs/api/javascript/source/lib/goog/structs/map.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/structs/set.js.src.html b/docs/api/javascript/source/lib/goog/structs/set.js.src.html new file mode 100644 index 0000000000000..e5566ef188402 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/structs/set.js.src.html @@ -0,0 +1 @@ +set.js

        lib/goog/structs/set.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: Set.
        17 *
        18 * @author arv@google.com (Erik Arvidsson)
        19 * @author pallosp@google.com (Peter Pallos)
        20 *
        21 * This class implements a set data structure. Adding and removing is O(1). It
        22 * supports both object and primitive values. Be careful because you can add
        23 * both 1 and new Number(1), because these are not the same. You can even add
        24 * multiple new Number(1) because these are not equal.
        25 */
        26
        27
        28goog.provide('goog.structs.Set');
        29
        30goog.require('goog.structs');
        31goog.require('goog.structs.Collection');
        32goog.require('goog.structs.Map');
        33
        34
        35
        36/**
        37 * A set that can contain both primitives and objects. Adding and removing
        38 * elements is O(1). Primitives are treated as identical if they have the same
        39 * type and convert to the same string. Objects are treated as identical only
        40 * if they are references to the same object. WARNING: A goog.structs.Set can
        41 * contain both 1 and (new Number(1)), because they are not the same. WARNING:
        42 * Adding (new Number(1)) twice will yield two distinct elements, because they
        43 * are two different objects. WARNING: Any object that is added to a
        44 * goog.structs.Set will be modified! Because goog.getUid() is used to
        45 * identify objects, every object in the set will be mutated.
        46 * @param {Array.<T>|Object.<?,T>=} opt_values Initial values to start with.
        47 * @constructor
        48 * @implements {goog.structs.Collection.<T>}
        49 * @final
        50 * @template T
        51 */
        52goog.structs.Set = function(opt_values) {
        53 this.map_ = new goog.structs.Map;
        54 if (opt_values) {
        55 this.addAll(opt_values);
        56 }
        57};
        58
        59
        60/**
        61 * Obtains a unique key for an element of the set. Primitives will yield the
        62 * same key if they have the same type and convert to the same string. Object
        63 * references will yield the same key only if they refer to the same object.
        64 * @param {*} val Object or primitive value to get a key for.
        65 * @return {string} A unique key for this value/object.
        66 * @private
        67 */
        68goog.structs.Set.getKey_ = function(val) {
        69 var type = typeof val;
        70 if (type == 'object' && val || type == 'function') {
        71 return 'o' + goog.getUid(/** @type {Object} */ (val));
        72 } else {
        73 return type.substr(0, 1) + val;
        74 }
        75};
        76
        77
        78/**
        79 * @return {number} The number of elements in the set.
        80 * @override
        81 */
        82goog.structs.Set.prototype.getCount = function() {
        83 return this.map_.getCount();
        84};
        85
        86
        87/**
        88 * Add a primitive or an object to the set.
        89 * @param {T} element The primitive or object to add.
        90 * @override
        91 */
        92goog.structs.Set.prototype.add = function(element) {
        93 this.map_.set(goog.structs.Set.getKey_(element), element);
        94};
        95
        96
        97/**
        98 * Adds all the values in the given collection to this set.
        99 * @param {Array.<T>|goog.structs.Collection.<T>|Object.<?,T>} col A collection
        100 * containing the elements to add.
        101 */
        102goog.structs.Set.prototype.addAll = function(col) {
        103 var values = goog.structs.getValues(col);
        104 var l = values.length;
        105 for (var i = 0; i < l; i++) {
        106 this.add(values[i]);
        107 }
        108};
        109
        110
        111/**
        112 * Removes all values in the given collection from this set.
        113 * @param {Array.<T>|goog.structs.Collection.<T>|Object.<?,T>} col A collection
        114 * containing the elements to remove.
        115 */
        116goog.structs.Set.prototype.removeAll = function(col) {
        117 var values = goog.structs.getValues(col);
        118 var l = values.length;
        119 for (var i = 0; i < l; i++) {
        120 this.remove(values[i]);
        121 }
        122};
        123
        124
        125/**
        126 * Removes the given element from this set.
        127 * @param {T} element The primitive or object to remove.
        128 * @return {boolean} Whether the element was found and removed.
        129 * @override
        130 */
        131goog.structs.Set.prototype.remove = function(element) {
        132 return this.map_.remove(goog.structs.Set.getKey_(element));
        133};
        134
        135
        136/**
        137 * Removes all elements from this set.
        138 */
        139goog.structs.Set.prototype.clear = function() {
        140 this.map_.clear();
        141};
        142
        143
        144/**
        145 * Tests whether this set is empty.
        146 * @return {boolean} True if there are no elements in this set.
        147 */
        148goog.structs.Set.prototype.isEmpty = function() {
        149 return this.map_.isEmpty();
        150};
        151
        152
        153/**
        154 * Tests whether this set contains the given element.
        155 * @param {T} element The primitive or object to test for.
        156 * @return {boolean} True if this set contains the given element.
        157 * @override
        158 */
        159goog.structs.Set.prototype.contains = function(element) {
        160 return this.map_.containsKey(goog.structs.Set.getKey_(element));
        161};
        162
        163
        164/**
        165 * Tests whether this set contains all the values in a given collection.
        166 * Repeated elements in the collection are ignored, e.g. (new
        167 * goog.structs.Set([1, 2])).containsAll([1, 1]) is True.
        168 * @param {goog.structs.Collection.<T>|Object} col A collection-like object.
        169 * @return {boolean} True if the set contains all elements.
        170 */
        171goog.structs.Set.prototype.containsAll = function(col) {
        172 return goog.structs.every(col, this.contains, this);
        173};
        174
        175
        176/**
        177 * Finds all values that are present in both this set and the given collection.
        178 * @param {Array.<S>|Object.<?,S>} col A collection.
        179 * @return {!goog.structs.Set.<T|S>} A new set containing all the values
        180 * (primitives or objects) present in both this set and the given
        181 * collection.
        182 * @template S
        183 */
        184goog.structs.Set.prototype.intersection = function(col) {
        185 var result = new goog.structs.Set();
        186
        187 var values = goog.structs.getValues(col);
        188 for (var i = 0; i < values.length; i++) {
        189 var value = values[i];
        190 if (this.contains(value)) {
        191 result.add(value);
        192 }
        193 }
        194
        195 return result;
        196};
        197
        198
        199/**
        200 * Finds all values that are present in this set and not in the given
        201 * collection.
        202 * @param {Array.<T>|goog.structs.Collection.<T>|Object.<?,T>} col A collection.
        203 * @return {!goog.structs.Set} A new set containing all the values
        204 * (primitives or objects) present in this set but not in the given
        205 * collection.
        206 */
        207goog.structs.Set.prototype.difference = function(col) {
        208 var result = this.clone();
        209 result.removeAll(col);
        210 return result;
        211};
        212
        213
        214/**
        215 * Returns an array containing all the elements in this set.
        216 * @return {!Array.<T>} An array containing all the elements in this set.
        217 */
        218goog.structs.Set.prototype.getValues = function() {
        219 return this.map_.getValues();
        220};
        221
        222
        223/**
        224 * Creates a shallow clone of this set.
        225 * @return {!goog.structs.Set.<T>} A new set containing all the same elements as
        226 * this set.
        227 */
        228goog.structs.Set.prototype.clone = function() {
        229 return new goog.structs.Set(this);
        230};
        231
        232
        233/**
        234 * Tests whether the given collection consists of the same elements as this set,
        235 * regardless of order, without repetition. Primitives are treated as equal if
        236 * they have the same type and convert to the same string; objects are treated
        237 * as equal if they are references to the same object. This operation is O(n).
        238 * @param {goog.structs.Collection.<T>|Object} col A collection.
        239 * @return {boolean} True if the given collection consists of the same elements
        240 * as this set, regardless of order, without repetition.
        241 */
        242goog.structs.Set.prototype.equals = function(col) {
        243 return this.getCount() == goog.structs.getCount(col) && this.isSubsetOf(col);
        244};
        245
        246
        247/**
        248 * Tests whether the given collection contains all the elements in this set.
        249 * Primitives are treated as equal if they have the same type and convert to the
        250 * same string; objects are treated as equal if they are references to the same
        251 * object. This operation is O(n).
        252 * @param {goog.structs.Collection.<T>|Object} col A collection.
        253 * @return {boolean} True if this set is a subset of the given collection.
        254 */
        255goog.structs.Set.prototype.isSubsetOf = function(col) {
        256 var colCount = goog.structs.getCount(col);
        257 if (this.getCount() > colCount) {
        258 return false;
        259 }
        260 // TODO(user) Find the minimal collection size where the conversion makes
        261 // the contains() method faster.
        262 if (!(col instanceof goog.structs.Set) && colCount > 5) {
        263 // Convert to a goog.structs.Set so that goog.structs.contains runs in
        264 // O(1) time instead of O(n) time.
        265 col = new goog.structs.Set(col);
        266 }
        267 return goog.structs.every(this, function(value) {
        268 return goog.structs.contains(col, value);
        269 });
        270};
        271
        272
        273/**
        274 * Returns an iterator that iterates over the elements in this set.
        275 * @param {boolean=} opt_keys This argument is ignored.
        276 * @return {!goog.iter.Iterator} An iterator over the elements in this set.
        277 */
        278goog.structs.Set.prototype.__iterator__ = function(opt_keys) {
        279 return this.map_.__iterator__(false);
        280};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/structs/structs.js.src.html b/docs/api/javascript/source/lib/goog/structs/structs.js.src.html index 57aa493891a1c..aa633fa36b9e9 100644 --- a/docs/api/javascript/source/lib/goog/structs/structs.js.src.html +++ b/docs/api/javascript/source/lib/goog/structs/structs.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/style/style.js.src.html b/docs/api/javascript/source/lib/goog/style/style.js.src.html new file mode 100644 index 0000000000000..124235ab29fc5 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/style/style.js.src.html @@ -0,0 +1 @@ +style.js

        lib/goog/style/style.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 element styles.
        17 *
        18 * @see ../demos/inline_block_quirks.html
        19 * @see ../demos/inline_block_standards.html
        20 * @see ../demos/style_viewport.html
        21 */
        22
        23goog.provide('goog.style');
        24
        25
        26goog.require('goog.array');
        27goog.require('goog.asserts');
        28goog.require('goog.dom');
        29goog.require('goog.dom.NodeType');
        30goog.require('goog.dom.vendor');
        31goog.require('goog.math.Box');
        32goog.require('goog.math.Coordinate');
        33goog.require('goog.math.Rect');
        34goog.require('goog.math.Size');
        35goog.require('goog.object');
        36goog.require('goog.string');
        37goog.require('goog.userAgent');
        38
        39
        40/**
        41 * @define {boolean} Whether we know at compile time that
        42 * getBoundingClientRect() is present and bug-free on the browser.
        43 */
        44goog.define('goog.style.GET_BOUNDING_CLIENT_RECT_ALWAYS_EXISTS', false);
        45
        46
        47/**
        48 * Sets a style value on an element.
        49 *
        50 * This function is not indended to patch issues in the browser's style
        51 * handling, but to allow easy programmatic access to setting dash-separated
        52 * style properties. An example is setting a batch of properties from a data
        53 * object without overwriting old styles. When possible, use native APIs:
        54 * elem.style.propertyKey = 'value' or (if obliterating old styles is fine)
        55 * elem.style.cssText = 'property1: value1; property2: value2'.
        56 *
        57 * @param {Element} element The element to change.
        58 * @param {string|Object} style If a string, a style name. If an object, a hash
        59 * of style names to style values.
        60 * @param {string|number|boolean=} opt_value If style was a string, then this
        61 * should be the value.
        62 */
        63goog.style.setStyle = function(element, style, opt_value) {
        64 if (goog.isString(style)) {
        65 goog.style.setStyle_(element, opt_value, style);
        66 } else {
        67 for (var key in style) {
        68 goog.style.setStyle_(element, style[key], key);
        69 }
        70 }
        71};
        72
        73
        74/**
        75 * Sets a style value on an element, with parameters swapped to work with
        76 * {@code goog.object.forEach()}. Prepends a vendor-specific prefix when
        77 * necessary.
        78 * @param {Element} element The element to change.
        79 * @param {string|number|boolean|undefined} value Style value.
        80 * @param {string} style Style name.
        81 * @private
        82 */
        83goog.style.setStyle_ = function(element, value, style) {
        84 var propertyName = goog.style.getVendorJsStyleName_(element, style);
        85
        86 if (propertyName) {
        87 element.style[propertyName] = value;
        88 }
        89};
        90
        91
        92/**
        93 * Returns the style property name in camel-case. If it does not exist and a
        94 * vendor-specific version of the property does exist, then return the vendor-
        95 * specific property name instead.
        96 * @param {Element} element The element to change.
        97 * @param {string} style Style name.
        98 * @return {string} Vendor-specific style.
        99 * @private
        100 */
        101goog.style.getVendorJsStyleName_ = function(element, style) {
        102 var camelStyle = goog.string.toCamelCase(style);
        103
        104 if (element.style[camelStyle] === undefined) {
        105 var prefixedStyle = goog.dom.vendor.getVendorJsPrefix() +
        106 goog.string.toTitleCase(camelStyle);
        107
        108 if (element.style[prefixedStyle] !== undefined) {
        109 return prefixedStyle;
        110 }
        111 }
        112
        113 return camelStyle;
        114};
        115
        116
        117/**
        118 * Returns the style property name in CSS notation. If it does not exist and a
        119 * vendor-specific version of the property does exist, then return the vendor-
        120 * specific property name instead.
        121 * @param {Element} element The element to change.
        122 * @param {string} style Style name.
        123 * @return {string} Vendor-specific style.
        124 * @private
        125 */
        126goog.style.getVendorStyleName_ = function(element, style) {
        127 var camelStyle = goog.string.toCamelCase(style);
        128
        129 if (element.style[camelStyle] === undefined) {
        130 var prefixedStyle = goog.dom.vendor.getVendorJsPrefix() +
        131 goog.string.toTitleCase(camelStyle);
        132
        133 if (element.style[prefixedStyle] !== undefined) {
        134 return goog.dom.vendor.getVendorPrefix() + '-' + style;
        135 }
        136 }
        137
        138 return style;
        139};
        140
        141
        142/**
        143 * Retrieves an explicitly-set style value of a node. This returns '' if there
        144 * isn't a style attribute on the element or if this style property has not been
        145 * explicitly set in script.
        146 *
        147 * @param {Element} element Element to get style of.
        148 * @param {string} property Property to get, css-style (if you have a camel-case
        149 * property, use element.style[style]).
        150 * @return {string} Style value.
        151 */
        152goog.style.getStyle = function(element, property) {
        153 // element.style is '' for well-known properties which are unset.
        154 // For for browser specific styles as 'filter' is undefined
        155 // so we need to return '' explicitly to make it consistent across
        156 // browsers.
        157 var styleValue = element.style[goog.string.toCamelCase(property)];
        158
        159 // Using typeof here because of a bug in Safari 5.1, where this value
        160 // was undefined, but === undefined returned false.
        161 if (typeof(styleValue) !== 'undefined') {
        162 return styleValue;
        163 }
        164
        165 return element.style[goog.style.getVendorJsStyleName_(element, property)] ||
        166 '';
        167};
        168
        169
        170/**
        171 * Retrieves a computed style value of a node. It returns empty string if the
        172 * value cannot be computed (which will be the case in Internet Explorer) or
        173 * "none" if the property requested is an SVG one and it has not been
        174 * explicitly set (firefox and webkit).
        175 *
        176 * @param {Element} element Element to get style of.
        177 * @param {string} property Property to get (camel-case).
        178 * @return {string} Style value.
        179 */
        180goog.style.getComputedStyle = function(element, property) {
        181 var doc = goog.dom.getOwnerDocument(element);
        182 if (doc.defaultView && doc.defaultView.getComputedStyle) {
        183 var styles = doc.defaultView.getComputedStyle(element, null);
        184 if (styles) {
        185 // element.style[..] is undefined for browser specific styles
        186 // as 'filter'.
        187 return styles[property] || styles.getPropertyValue(property) || '';
        188 }
        189 }
        190
        191 return '';
        192};
        193
        194
        195/**
        196 * Gets the cascaded style value of a node, or null if the value cannot be
        197 * computed (only Internet Explorer can do this).
        198 *
        199 * @param {Element} element Element to get style of.
        200 * @param {string} style Property to get (camel-case).
        201 * @return {string} Style value.
        202 */
        203goog.style.getCascadedStyle = function(element, style) {
        204 // TODO(nicksantos): This should be documented to return null. #fixTypes
        205 return element.currentStyle ? element.currentStyle[style] : null;
        206};
        207
        208
        209/**
        210 * Cross-browser pseudo get computed style. It returns the computed style where
        211 * available. If not available it tries the cascaded style value (IE
        212 * currentStyle) and in worst case the inline style value. It shouldn't be
        213 * called directly, see http://wiki/Main/ComputedStyleVsCascadedStyle for
        214 * discussion.
        215 *
        216 * @param {Element} element Element to get style of.
        217 * @param {string} style Property to get (must be camelCase, not css-style.).
        218 * @return {string} Style value.
        219 * @private
        220 */
        221goog.style.getStyle_ = function(element, style) {
        222 return goog.style.getComputedStyle(element, style) ||
        223 goog.style.getCascadedStyle(element, style) ||
        224 (element.style && element.style[style]);
        225};
        226
        227
        228/**
        229 * Retrieves the computed value of the box-sizing CSS attribute.
        230 * Browser support: http://caniuse.com/css3-boxsizing.
        231 * @param {!Element} element The element whose box-sizing to get.
        232 * @return {?string} 'content-box', 'border-box' or 'padding-box'. null if
        233 * box-sizing is not supported (IE7 and below).
        234 */
        235goog.style.getComputedBoxSizing = function(element) {
        236 return goog.style.getStyle_(element, 'boxSizing') ||
        237 goog.style.getStyle_(element, 'MozBoxSizing') ||
        238 goog.style.getStyle_(element, 'WebkitBoxSizing') || null;
        239};
        240
        241
        242/**
        243 * Retrieves the computed value of the position CSS attribute.
        244 * @param {Element} element The element to get the position of.
        245 * @return {string} Position value.
        246 */
        247goog.style.getComputedPosition = function(element) {
        248 return goog.style.getStyle_(element, 'position');
        249};
        250
        251
        252/**
        253 * Retrieves the computed background color string for a given element. The
        254 * string returned is suitable for assigning to another element's
        255 * background-color, but is not guaranteed to be in any particular string
        256 * format. Accessing the color in a numeric form may not be possible in all
        257 * browsers or with all input.
        258 *
        259 * If the background color for the element is defined as a hexadecimal value,
        260 * the resulting string can be parsed by goog.color.parse in all supported
        261 * browsers.
        262 *
        263 * Whether named colors like "red" or "lightblue" get translated into a
        264 * format which can be parsed is browser dependent. Calling this function on
        265 * transparent elements will return "transparent" in most browsers or
        266 * "rgba(0, 0, 0, 0)" in WebKit.
        267 * @param {Element} element The element to get the background color of.
        268 * @return {string} The computed string value of the background color.
        269 */
        270goog.style.getBackgroundColor = function(element) {
        271 return goog.style.getStyle_(element, 'backgroundColor');
        272};
        273
        274
        275/**
        276 * Retrieves the computed value of the overflow-x CSS attribute.
        277 * @param {Element} element The element to get the overflow-x of.
        278 * @return {string} The computed string value of the overflow-x attribute.
        279 */
        280goog.style.getComputedOverflowX = function(element) {
        281 return goog.style.getStyle_(element, 'overflowX');
        282};
        283
        284
        285/**
        286 * Retrieves the computed value of the overflow-y CSS attribute.
        287 * @param {Element} element The element to get the overflow-y of.
        288 * @return {string} The computed string value of the overflow-y attribute.
        289 */
        290goog.style.getComputedOverflowY = function(element) {
        291 return goog.style.getStyle_(element, 'overflowY');
        292};
        293
        294
        295/**
        296 * Retrieves the computed value of the z-index CSS attribute.
        297 * @param {Element} element The element to get the z-index of.
        298 * @return {string|number} The computed value of the z-index attribute.
        299 */
        300goog.style.getComputedZIndex = function(element) {
        301 return goog.style.getStyle_(element, 'zIndex');
        302};
        303
        304
        305/**
        306 * Retrieves the computed value of the text-align CSS attribute.
        307 * @param {Element} element The element to get the text-align of.
        308 * @return {string} The computed string value of the text-align attribute.
        309 */
        310goog.style.getComputedTextAlign = function(element) {
        311 return goog.style.getStyle_(element, 'textAlign');
        312};
        313
        314
        315/**
        316 * Retrieves the computed value of the cursor CSS attribute.
        317 * @param {Element} element The element to get the cursor of.
        318 * @return {string} The computed string value of the cursor attribute.
        319 */
        320goog.style.getComputedCursor = function(element) {
        321 return goog.style.getStyle_(element, 'cursor');
        322};
        323
        324
        325/**
        326 * Retrieves the computed value of the CSS transform attribute.
        327 * @param {Element} element The element to get the transform of.
        328 * @return {string} The computed string representation of the transform matrix.
        329 */
        330goog.style.getComputedTransform = function(element) {
        331 var property = goog.style.getVendorStyleName_(element, 'transform');
        332 return goog.style.getStyle_(element, property) ||
        333 goog.style.getStyle_(element, 'transform');
        334};
        335
        336
        337/**
        338 * Sets the top/left values of an element. If no unit is specified in the
        339 * argument then it will add px. The second argument is required if the first
        340 * argument is a string or number and is ignored if the first argument
        341 * is a coordinate.
        342 * @param {Element} el Element to move.
        343 * @param {string|number|goog.math.Coordinate} arg1 Left position or coordinate.
        344 * @param {string|number=} opt_arg2 Top position.
        345 */
        346goog.style.setPosition = function(el, arg1, opt_arg2) {
        347 var x, y;
        348 var buggyGeckoSubPixelPos = goog.userAgent.GECKO &&
        349 (goog.userAgent.MAC || goog.userAgent.X11) &&
        350 goog.userAgent.isVersionOrHigher('1.9');
        351
        352 if (arg1 instanceof goog.math.Coordinate) {
        353 x = arg1.x;
        354 y = arg1.y;
        355 } else {
        356 x = arg1;
        357 y = opt_arg2;
        358 }
        359
        360 // Round to the nearest pixel for buggy sub-pixel support.
        361 el.style.left = goog.style.getPixelStyleValue_(
        362 /** @type {number|string} */ (x), buggyGeckoSubPixelPos);
        363 el.style.top = goog.style.getPixelStyleValue_(
        364 /** @type {number|string} */ (y), buggyGeckoSubPixelPos);
        365};
        366
        367
        368/**
        369 * Gets the offsetLeft and offsetTop properties of an element and returns them
        370 * in a Coordinate object
        371 * @param {Element} element Element.
        372 * @return {!goog.math.Coordinate} The position.
        373 */
        374goog.style.getPosition = function(element) {
        375 return new goog.math.Coordinate(element.offsetLeft, element.offsetTop);
        376};
        377
        378
        379/**
        380 * Returns the viewport element for a particular document
        381 * @param {Node=} opt_node DOM node (Document is OK) to get the viewport element
        382 * of.
        383 * @return {Element} document.documentElement or document.body.
        384 */
        385goog.style.getClientViewportElement = function(opt_node) {
        386 var doc;
        387 if (opt_node) {
        388 doc = goog.dom.getOwnerDocument(opt_node);
        389 } else {
        390 doc = goog.dom.getDocument();
        391 }
        392
        393 // In old IE versions the document.body represented the viewport
        394 if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9) &&
        395 !goog.dom.getDomHelper(doc).isCss1CompatMode()) {
        396 return doc.body;
        397 }
        398 return doc.documentElement;
        399};
        400
        401
        402/**
        403 * Calculates the viewport coordinates relative to the page/document
        404 * containing the node. The viewport may be the browser viewport for
        405 * non-iframe document, or the iframe container for iframe'd document.
        406 * @param {!Document} doc The document to use as the reference point.
        407 * @return {!goog.math.Coordinate} The page offset of the viewport.
        408 */
        409goog.style.getViewportPageOffset = function(doc) {
        410 var body = doc.body;
        411 var documentElement = doc.documentElement;
        412 var scrollLeft = body.scrollLeft || documentElement.scrollLeft;
        413 var scrollTop = body.scrollTop || documentElement.scrollTop;
        414 return new goog.math.Coordinate(scrollLeft, scrollTop);
        415};
        416
        417
        418/**
        419 * Gets the client rectangle of the DOM element.
        420 *
        421 * getBoundingClientRect is part of a new CSS object model draft (with a
        422 * long-time presence in IE), replacing the error-prone parent offset
        423 * computation and the now-deprecated Gecko getBoxObjectFor.
        424 *
        425 * This utility patches common browser bugs in getBoundingClientRect. It
        426 * will fail if getBoundingClientRect is unsupported.
        427 *
        428 * If the element is not in the DOM, the result is undefined, and an error may
        429 * be thrown depending on user agent.
        430 *
        431 * @param {!Element} el The element whose bounding rectangle is being queried.
        432 * @return {Object} A native bounding rectangle with numerical left, top,
        433 * right, and bottom. Reported by Firefox to be of object type ClientRect.
        434 * @private
        435 */
        436goog.style.getBoundingClientRect_ = function(el) {
        437 var rect;
        438 try {
        439 rect = el.getBoundingClientRect();
        440 } catch (e) {
        441 // In IE < 9, calling getBoundingClientRect on an orphan element raises an
        442 // "Unspecified Error". All other browsers return zeros.
        443 return {'left': 0, 'top': 0, 'right': 0, 'bottom': 0};
        444 }
        445
        446 // Patch the result in IE only, so that this function can be inlined if
        447 // compiled for non-IE.
        448 if (goog.userAgent.IE && el.ownerDocument.body) {
        449
        450 // In IE, most of the time, 2 extra pixels are added to the top and left
        451 // due to the implicit 2-pixel inset border. In IE6/7 quirks mode and
        452 // IE6 standards mode, this border can be overridden by setting the
        453 // document element's border to zero -- thus, we cannot rely on the
        454 // offset always being 2 pixels.
        455
        456 // In quirks mode, the offset can be determined by querying the body's
        457 // clientLeft/clientTop, but in standards mode, it is found by querying
        458 // the document element's clientLeft/clientTop. Since we already called
        459 // getBoundingClientRect we have already forced a reflow, so it is not
        460 // too expensive just to query them all.
        461
        462 // See: http://msdn.microsoft.com/en-us/library/ms536433(VS.85).aspx
        463 var doc = el.ownerDocument;
        464 rect.left -= doc.documentElement.clientLeft + doc.body.clientLeft;
        465 rect.top -= doc.documentElement.clientTop + doc.body.clientTop;
        466 }
        467 return /** @type {Object} */ (rect);
        468};
        469
        470
        471/**
        472 * Returns the first parent that could affect the position of a given element.
        473 * @param {Element} element The element to get the offset parent for.
        474 * @return {Element} The first offset parent or null if one cannot be found.
        475 */
        476goog.style.getOffsetParent = function(element) {
        477 // element.offsetParent does the right thing in IE7 and below. In other
        478 // browsers it only includes elements with position absolute, relative or
        479 // fixed, not elements with overflow set to auto or scroll.
        480 if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(8)) {
        481 return element.offsetParent;
        482 }
        483
        484 var doc = goog.dom.getOwnerDocument(element);
        485 var positionStyle = goog.style.getStyle_(element, 'position');
        486 var skipStatic = positionStyle == 'fixed' || positionStyle == 'absolute';
        487 for (var parent = element.parentNode; parent && parent != doc;
        488 parent = parent.parentNode) {
        489 positionStyle =
        490 goog.style.getStyle_(/** @type {!Element} */ (parent), 'position');
        491 skipStatic = skipStatic && positionStyle == 'static' &&
        492 parent != doc.documentElement && parent != doc.body;
        493 if (!skipStatic && (parent.scrollWidth > parent.clientWidth ||
        494 parent.scrollHeight > parent.clientHeight ||
        495 positionStyle == 'fixed' ||
        496 positionStyle == 'absolute' ||
        497 positionStyle == 'relative')) {
        498 return /** @type {!Element} */ (parent);
        499 }
        500 }
        501 return null;
        502};
        503
        504
        505/**
        506 * Calculates and returns the visible rectangle for a given element. Returns a
        507 * box describing the visible portion of the nearest scrollable offset ancestor.
        508 * Coordinates are given relative to the document.
        509 *
        510 * @param {Element} element Element to get the visible rect for.
        511 * @return {goog.math.Box} Bounding elementBox describing the visible rect or
        512 * null if scrollable ancestor isn't inside the visible viewport.
        513 */
        514goog.style.getVisibleRectForElement = function(element) {
        515 var visibleRect = new goog.math.Box(0, Infinity, Infinity, 0);
        516 var dom = goog.dom.getDomHelper(element);
        517 var body = dom.getDocument().body;
        518 var documentElement = dom.getDocument().documentElement;
        519 var scrollEl = dom.getDocumentScrollElement();
        520
        521 // Determine the size of the visible rect by climbing the dom accounting for
        522 // all scrollable containers.
        523 for (var el = element; el = goog.style.getOffsetParent(el); ) {
        524 // clientWidth is zero for inline block elements in IE.
        525 // on WEBKIT, body element can have clientHeight = 0 and scrollHeight > 0
        526 if ((!goog.userAgent.IE || el.clientWidth != 0) &&
        527 (!goog.userAgent.WEBKIT || el.clientHeight != 0 || el != body) &&
        528 // body may have overflow set on it, yet we still get the entire
        529 // viewport. In some browsers, el.offsetParent may be
        530 // document.documentElement, so check for that too.
        531 (el != body && el != documentElement &&
        532 goog.style.getStyle_(el, 'overflow') != 'visible')) {
        533 var pos = goog.style.getPageOffset(el);
        534 var client = goog.style.getClientLeftTop(el);
        535 pos.x += client.x;
        536 pos.y += client.y;
        537
        538 visibleRect.top = Math.max(visibleRect.top, pos.y);
        539 visibleRect.right = Math.min(visibleRect.right,
        540 pos.x + el.clientWidth);
        541 visibleRect.bottom = Math.min(visibleRect.bottom,
        542 pos.y + el.clientHeight);
        543 visibleRect.left = Math.max(visibleRect.left, pos.x);
        544 }
        545 }
        546
        547 // Clip by window's viewport.
        548 var scrollX = scrollEl.scrollLeft, scrollY = scrollEl.scrollTop;
        549 visibleRect.left = Math.max(visibleRect.left, scrollX);
        550 visibleRect.top = Math.max(visibleRect.top, scrollY);
        551 var winSize = dom.getViewportSize();
        552 visibleRect.right = Math.min(visibleRect.right, scrollX + winSize.width);
        553 visibleRect.bottom = Math.min(visibleRect.bottom, scrollY + winSize.height);
        554 return visibleRect.top >= 0 && visibleRect.left >= 0 &&
        555 visibleRect.bottom > visibleRect.top &&
        556 visibleRect.right > visibleRect.left ?
        557 visibleRect : null;
        558};
        559
        560
        561/**
        562 * Calculate the scroll position of {@code container} with the minimum amount so
        563 * that the content and the borders of the given {@code element} become visible.
        564 * If the element is bigger than the container, its top left corner will be
        565 * aligned as close to the container's top left corner as possible.
        566 *
        567 * @param {Element} element The element to make visible.
        568 * @param {Element} container The container to scroll.
        569 * @param {boolean=} opt_center Whether to center the element in the container.
        570 * Defaults to false.
        571 * @return {!goog.math.Coordinate} The new scroll position of the container,
        572 * in form of goog.math.Coordinate(scrollLeft, scrollTop).
        573 */
        574goog.style.getContainerOffsetToScrollInto =
        575 function(element, container, opt_center) {
        576 // Absolute position of the element's border's top left corner.
        577 var elementPos = goog.style.getPageOffset(element);
        578 // Absolute position of the container's border's top left corner.
        579 var containerPos = goog.style.getPageOffset(container);
        580 var containerBorder = goog.style.getBorderBox(container);
        581 // Relative pos. of the element's border box to the container's content box.
        582 var relX = elementPos.x - containerPos.x - containerBorder.left;
        583 var relY = elementPos.y - containerPos.y - containerBorder.top;
        584 // How much the element can move in the container, i.e. the difference between
        585 // the element's bottom-right-most and top-left-most position where it's
        586 // fully visible.
        587 var spaceX = container.clientWidth - element.offsetWidth;
        588 var spaceY = container.clientHeight - element.offsetHeight;
        589
        590 var scrollLeft = container.scrollLeft;
        591 var scrollTop = container.scrollTop;
        592 if (opt_center) {
        593 // All browsers round non-integer scroll positions down.
        594 scrollLeft += relX - spaceX / 2;
        595 scrollTop += relY - spaceY / 2;
        596 } else {
        597 // This formula was designed to give the correct scroll values in the
        598 // following cases:
        599 // - element is higher than container (spaceY < 0) => scroll down by relY
        600 // - element is not higher that container (spaceY >= 0):
        601 // - it is above container (relY < 0) => scroll up by abs(relY)
        602 // - it is below container (relY > spaceY) => scroll down by relY - spaceY
        603 // - it is in the container => don't scroll
        604 scrollLeft += Math.min(relX, Math.max(relX - spaceX, 0));
        605 scrollTop += Math.min(relY, Math.max(relY - spaceY, 0));
        606 }
        607 return new goog.math.Coordinate(scrollLeft, scrollTop);
        608};
        609
        610
        611/**
        612 * Changes the scroll position of {@code container} with the minimum amount so
        613 * that the content and the borders of the given {@code element} become visible.
        614 * If the element is bigger than the container, its top left corner will be
        615 * aligned as close to the container's top left corner as possible.
        616 *
        617 * @param {Element} element The element to make visible.
        618 * @param {Element} container The container to scroll.
        619 * @param {boolean=} opt_center Whether to center the element in the container.
        620 * Defaults to false.
        621 */
        622goog.style.scrollIntoContainerView = function(element, container, opt_center) {
        623 var offset =
        624 goog.style.getContainerOffsetToScrollInto(element, container, opt_center);
        625 container.scrollLeft = offset.x;
        626 container.scrollTop = offset.y;
        627};
        628
        629
        630/**
        631 * Returns clientLeft (width of the left border and, if the directionality is
        632 * right to left, the vertical scrollbar) and clientTop as a coordinate object.
        633 *
        634 * @param {Element} el Element to get clientLeft for.
        635 * @return {!goog.math.Coordinate} Client left and top.
        636 */
        637goog.style.getClientLeftTop = function(el) {
        638 // NOTE(eae): Gecko prior to 1.9 doesn't support clientTop/Left, see
        639 // https://bugzilla.mozilla.org/show_bug.cgi?id=111207
        640 if (goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('1.9')) {
        641 var left = parseFloat(goog.style.getComputedStyle(el, 'borderLeftWidth'));
        642 if (goog.style.isRightToLeft(el)) {
        643 var scrollbarWidth = el.offsetWidth - el.clientWidth - left -
        644 parseFloat(goog.style.getComputedStyle(el, 'borderRightWidth'));
        645 left += scrollbarWidth;
        646 }
        647 return new goog.math.Coordinate(left,
        648 parseFloat(goog.style.getComputedStyle(el, 'borderTopWidth')));
        649 }
        650
        651 return new goog.math.Coordinate(el.clientLeft, el.clientTop);
        652};
        653
        654
        655/**
        656 * Returns a Coordinate object relative to the top-left of the HTML document.
        657 * Implemented as a single function to save having to do two recursive loops in
        658 * opera and safari just to get both coordinates. If you just want one value do
        659 * use goog.style.getPageOffsetLeft() and goog.style.getPageOffsetTop(), but
        660 * note if you call both those methods the tree will be analysed twice.
        661 *
        662 * @param {Element} el Element to get the page offset for.
        663 * @return {!goog.math.Coordinate} The page offset.
        664 */
        665goog.style.getPageOffset = function(el) {
        666 var box, doc = goog.dom.getOwnerDocument(el);
        667 var positionStyle = goog.style.getStyle_(el, 'position');
        668 // TODO(gboyer): Update the jsdoc in a way that doesn't break the universe.
        669 goog.asserts.assertObject(el, 'Parameter is required');
        670
        671 // NOTE(eae): Gecko pre 1.9 normally use getBoxObjectFor to calculate the
        672 // position. When invoked for an element with position absolute and a negative
        673 // position though it can be off by one. Therefor the recursive implementation
        674 // is used in those (relatively rare) cases.
        675 var BUGGY_GECKO_BOX_OBJECT =
        676 !goog.style.GET_BOUNDING_CLIENT_RECT_ALWAYS_EXISTS &&
        677 goog.userAgent.GECKO && doc.getBoxObjectFor &&
        678 !el.getBoundingClientRect && positionStyle == 'absolute' &&
        679 (box = doc.getBoxObjectFor(el)) && (box.screenX < 0 || box.screenY < 0);
        680
        681 // NOTE(arv): If element is hidden (display none or disconnected or any the
        682 // ancestors are hidden) we get (0,0) by default but we still do the
        683 // accumulation of scroll position.
        684
        685 // TODO(arv): Should we check if the node is disconnected and in that case
        686 // return (0,0)?
        687
        688 var pos = new goog.math.Coordinate(0, 0);
        689 var viewportElement = goog.style.getClientViewportElement(doc);
        690 if (el == viewportElement) {
        691 // viewport is always at 0,0 as that defined the coordinate system for this
        692 // function - this avoids special case checks in the code below
        693 return pos;
        694 }
        695
        696 // IE, Gecko 1.9+, and most modern WebKit.
        697 if (goog.style.GET_BOUNDING_CLIENT_RECT_ALWAYS_EXISTS ||
        698 el.getBoundingClientRect) {
        699 box = goog.style.getBoundingClientRect_(el);
        700 // Must add the scroll coordinates in to get the absolute page offset
        701 // of element since getBoundingClientRect returns relative coordinates to
        702 // the viewport.
        703 var scrollCoord = goog.dom.getDomHelper(doc).getDocumentScroll();
        704 pos.x = box.left + scrollCoord.x;
        705 pos.y = box.top + scrollCoord.y;
        706
        707 // Gecko prior to 1.9.
        708 } else if (doc.getBoxObjectFor && !BUGGY_GECKO_BOX_OBJECT) {
        709 // Gecko ignores the scroll values for ancestors, up to 1.9. See:
        710 // https://bugzilla.mozilla.org/show_bug.cgi?id=328881 and
        711 // https://bugzilla.mozilla.org/show_bug.cgi?id=330619
        712
        713 box = doc.getBoxObjectFor(el);
        714 // TODO(user): Fix the off-by-one error when window is scrolled down
        715 // or right more than 1 pixel. The viewport offset does not move in lock
        716 // step with the window scroll; it moves in increments of 2px and at
        717 // somewhat random intervals.
        718 var vpBox = doc.getBoxObjectFor(viewportElement);
        719 pos.x = box.screenX - vpBox.screenX;
        720 pos.y = box.screenY - vpBox.screenY;
        721
        722 // Safari, Opera and Camino up to 1.0.4.
        723 } else {
        724 var parent = el;
        725 do {
        726 pos.x += parent.offsetLeft;
        727 pos.y += parent.offsetTop;
        728 // For safari/chrome, we need to add parent's clientLeft/Top as well.
        729 if (parent != el) {
        730 pos.x += parent.clientLeft || 0;
        731 pos.y += parent.clientTop || 0;
        732 }
        733 // In Safari when hit a position fixed element the rest of the offsets
        734 // are not correct.
        735 if (goog.userAgent.WEBKIT &&
        736 goog.style.getComputedPosition(parent) == 'fixed') {
        737 pos.x += doc.body.scrollLeft;
        738 pos.y += doc.body.scrollTop;
        739 break;
        740 }
        741 parent = parent.offsetParent;
        742 } while (parent && parent != el);
        743
        744 // Opera & (safari absolute) incorrectly account for body offsetTop.
        745 if (goog.userAgent.OPERA || (goog.userAgent.WEBKIT &&
        746 positionStyle == 'absolute')) {
        747 pos.y -= doc.body.offsetTop;
        748 }
        749
        750 for (parent = el; (parent = goog.style.getOffsetParent(parent)) &&
        751 parent != doc.body && parent != viewportElement; ) {
        752 pos.x -= parent.scrollLeft;
        753 // Workaround for a bug in Opera 9.2 (and earlier) where table rows may
        754 // report an invalid scroll top value. The bug was fixed in Opera 9.5
        755 // however as that version supports getBoundingClientRect it won't
        756 // trigger this code path. https://bugs.opera.com/show_bug.cgi?id=249965
        757 if (!goog.userAgent.OPERA || parent.tagName != 'TR') {
        758 pos.y -= parent.scrollTop;
        759 }
        760 }
        761 }
        762
        763 return pos;
        764};
        765
        766
        767/**
        768 * Returns the left coordinate of an element relative to the HTML document
        769 * @param {Element} el Elements.
        770 * @return {number} The left coordinate.
        771 */
        772goog.style.getPageOffsetLeft = function(el) {
        773 return goog.style.getPageOffset(el).x;
        774};
        775
        776
        777/**
        778 * Returns the top coordinate of an element relative to the HTML document
        779 * @param {Element} el Elements.
        780 * @return {number} The top coordinate.
        781 */
        782goog.style.getPageOffsetTop = function(el) {
        783 return goog.style.getPageOffset(el).y;
        784};
        785
        786
        787/**
        788 * Returns a Coordinate object relative to the top-left of an HTML document
        789 * in an ancestor frame of this element. Used for measuring the position of
        790 * an element inside a frame relative to a containing frame.
        791 *
        792 * @param {Element} el Element to get the page offset for.
        793 * @param {Window} relativeWin The window to measure relative to. If relativeWin
        794 * is not in the ancestor frame chain of the element, we measure relative to
        795 * the top-most window.
        796 * @return {!goog.math.Coordinate} The page offset.
        797 */
        798goog.style.getFramedPageOffset = function(el, relativeWin) {
        799 var position = new goog.math.Coordinate(0, 0);
        800
        801 // Iterate up the ancestor frame chain, keeping track of the current window
        802 // and the current element in that window.
        803 var currentWin = goog.dom.getWindow(goog.dom.getOwnerDocument(el));
        804 var currentEl = el;
        805 do {
        806 // if we're at the top window, we want to get the page offset.
        807 // if we're at an inner frame, we only want to get the window position
        808 // so that we can determine the actual page offset in the context of
        809 // the outer window.
        810 var offset = currentWin == relativeWin ?
        811 goog.style.getPageOffset(currentEl) :
        812 goog.style.getClientPositionForElement_(
        813 goog.asserts.assert(currentEl));
        814
        815 position.x += offset.x;
        816 position.y += offset.y;
        817 } while (currentWin && currentWin != relativeWin &&
        818 (currentEl = currentWin.frameElement) &&
        819 (currentWin = currentWin.parent));
        820
        821 return position;
        822};
        823
        824
        825/**
        826 * Translates the specified rect relative to origBase page, for newBase page.
        827 * If origBase and newBase are the same, this function does nothing.
        828 *
        829 * @param {goog.math.Rect} rect The source rectangle relative to origBase page,
        830 * and it will have the translated result.
        831 * @param {goog.dom.DomHelper} origBase The DomHelper for the input rectangle.
        832 * @param {goog.dom.DomHelper} newBase The DomHelper for the resultant
        833 * coordinate. This must be a DOM for an ancestor frame of origBase
        834 * or the same as origBase.
        835 */
        836goog.style.translateRectForAnotherFrame = function(rect, origBase, newBase) {
        837 if (origBase.getDocument() != newBase.getDocument()) {
        838 var body = origBase.getDocument().body;
        839 var pos = goog.style.getFramedPageOffset(body, newBase.getWindow());
        840
        841 // Adjust Body's margin.
        842 pos = goog.math.Coordinate.difference(pos, goog.style.getPageOffset(body));
        843
        844 if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9) &&
        845 !origBase.isCss1CompatMode()) {
        846 pos = goog.math.Coordinate.difference(pos, origBase.getDocumentScroll());
        847 }
        848
        849 rect.left += pos.x;
        850 rect.top += pos.y;
        851 }
        852};
        853
        854
        855/**
        856 * Returns the position of an element relative to another element in the
        857 * document. A relative to B
        858 * @param {Element|Event|goog.events.Event} a Element or mouse event whose
        859 * position we're calculating.
        860 * @param {Element|Event|goog.events.Event} b Element or mouse event position
        861 * is relative to.
        862 * @return {!goog.math.Coordinate} The relative position.
        863 */
        864goog.style.getRelativePosition = function(a, b) {
        865 var ap = goog.style.getClientPosition(a);
        866 var bp = goog.style.getClientPosition(b);
        867 return new goog.math.Coordinate(ap.x - bp.x, ap.y - bp.y);
        868};
        869
        870
        871/**
        872 * Returns the position of the event or the element's border box relative to
        873 * the client viewport.
        874 * @param {!Element} el Element whose position to get.
        875 * @return {!goog.math.Coordinate} The position.
        876 * @private
        877 */
        878goog.style.getClientPositionForElement_ = function(el) {
        879 var pos;
        880 if (goog.style.GET_BOUNDING_CLIENT_RECT_ALWAYS_EXISTS ||
        881 el.getBoundingClientRect) {
        882 // IE, Gecko 1.9+, and most modern WebKit
        883 var box = goog.style.getBoundingClientRect_(el);
        884 pos = new goog.math.Coordinate(box.left, box.top);
        885 } else {
        886 var scrollCoord = goog.dom.getDomHelper(el).getDocumentScroll();
        887 var pageCoord = goog.style.getPageOffset(el);
        888 pos = new goog.math.Coordinate(
        889 pageCoord.x - scrollCoord.x,
        890 pageCoord.y - scrollCoord.y);
        891 }
        892
        893 // Gecko below version 12 doesn't add CSS translation to the client position
        894 // (using either getBoundingClientRect or getBoxOffsetFor) so we need to do
        895 // so manually.
        896 if (goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher(12)) {
        897 return goog.math.Coordinate.sum(pos, goog.style.getCssTranslation(el));
        898 } else {
        899 return pos;
        900 }
        901};
        902
        903
        904/**
        905 * Returns the position of the event or the element's border box relative to
        906 * the client viewport.
        907 * @param {Element|Event|goog.events.Event} el Element or a mouse / touch event.
        908 * @return {!goog.math.Coordinate} The position.
        909 */
        910goog.style.getClientPosition = function(el) {
        911 goog.asserts.assert(el);
        912 if (el.nodeType == goog.dom.NodeType.ELEMENT) {
        913 return goog.style.getClientPositionForElement_(
        914 /** @type {!Element} */ (el));
        915 } else {
        916 var isAbstractedEvent = goog.isFunction(el.getBrowserEvent);
        917 var be = /** @type {!goog.events.BrowserEvent} */ (el);
        918 var targetEvent = el;
        919
        920 if (el.targetTouches && el.targetTouches.length) {
        921 targetEvent = el.targetTouches[0];
        922 } else if (isAbstractedEvent && be.getBrowserEvent().targetTouches &&
        923 be.getBrowserEvent().targetTouches.length) {
        924 targetEvent = be.getBrowserEvent().targetTouches[0];
        925 }
        926
        927 return new goog.math.Coordinate(
        928 targetEvent.clientX,
        929 targetEvent.clientY);
        930 }
        931};
        932
        933
        934/**
        935 * Moves an element to the given coordinates relative to the client viewport.
        936 * @param {Element} el Absolutely positioned element to set page offset for.
        937 * It must be in the document.
        938 * @param {number|goog.math.Coordinate} x Left position of the element's margin
        939 * box or a coordinate object.
        940 * @param {number=} opt_y Top position of the element's margin box.
        941 */
        942goog.style.setPageOffset = function(el, x, opt_y) {
        943 // Get current pageoffset
        944 var cur = goog.style.getPageOffset(el);
        945
        946 if (x instanceof goog.math.Coordinate) {
        947 opt_y = x.y;
        948 x = x.x;
        949 }
        950
        951 // NOTE(arv): We cannot allow strings for x and y. We could but that would
        952 // require us to manually transform between different units
        953
        954 // Work out deltas
        955 var dx = x - cur.x;
        956 var dy = opt_y - cur.y;
        957
        958 // Set position to current left/top + delta
        959 goog.style.setPosition(el, el.offsetLeft + dx, el.offsetTop + dy);
        960};
        961
        962
        963/**
        964 * Sets the width/height values of an element. If an argument is numeric,
        965 * or a goog.math.Size is passed, it is assumed to be pixels and will add
        966 * 'px' after converting it to an integer in string form. (This just sets the
        967 * CSS width and height properties so it might set content-box or border-box
        968 * size depending on the box model the browser is using.)
        969 *
        970 * @param {Element} element Element to set the size of.
        971 * @param {string|number|goog.math.Size} w Width of the element, or a
        972 * size object.
        973 * @param {string|number=} opt_h Height of the element. Required if w is not a
        974 * size object.
        975 */
        976goog.style.setSize = function(element, w, opt_h) {
        977 var h;
        978 if (w instanceof goog.math.Size) {
        979 h = w.height;
        980 w = w.width;
        981 } else {
        982 if (opt_h == undefined) {
        983 throw Error('missing height argument');
        984 }
        985 h = opt_h;
        986 }
        987
        988 goog.style.setWidth(element, /** @type {string|number} */ (w));
        989 goog.style.setHeight(element, /** @type {string|number} */ (h));
        990};
        991
        992
        993/**
        994 * Helper function to create a string to be set into a pixel-value style
        995 * property of an element. Can round to the nearest integer value.
        996 *
        997 * @param {string|number} value The style value to be used. If a number,
        998 * 'px' will be appended, otherwise the value will be applied directly.
        999 * @param {boolean} round Whether to round the nearest integer (if property
        1000 * is a number).
        1001 * @return {string} The string value for the property.
        1002 * @private
        1003 */
        1004goog.style.getPixelStyleValue_ = function(value, round) {
        1005 if (typeof value == 'number') {
        1006 value = (round ? Math.round(value) : value) + 'px';
        1007 }
        1008
        1009 return value;
        1010};
        1011
        1012
        1013/**
        1014 * Set the height of an element. Sets the element's style property.
        1015 * @param {Element} element Element to set the height of.
        1016 * @param {string|number} height The height value to set. If a number, 'px'
        1017 * will be appended, otherwise the value will be applied directly.
        1018 */
        1019goog.style.setHeight = function(element, height) {
        1020 element.style.height = goog.style.getPixelStyleValue_(height, true);
        1021};
        1022
        1023
        1024/**
        1025 * Set the width of an element. Sets the element's style property.
        1026 * @param {Element} element Element to set the width of.
        1027 * @param {string|number} width The width value to set. If a number, 'px'
        1028 * will be appended, otherwise the value will be applied directly.
        1029 */
        1030goog.style.setWidth = function(element, width) {
        1031 element.style.width = goog.style.getPixelStyleValue_(width, true);
        1032};
        1033
        1034
        1035/**
        1036 * Gets the height and width of an element, even if its display is none.
        1037 *
        1038 * Specifically, this returns the height and width of the border box,
        1039 * irrespective of the box model in effect.
        1040 *
        1041 * Note that this function does not take CSS transforms into account. Please see
        1042 * {@code goog.style.getTransformedSize}.
        1043 * @param {Element} element Element to get size of.
        1044 * @return {!goog.math.Size} Object with width/height properties.
        1045 */
        1046goog.style.getSize = function(element) {
        1047 return goog.style.evaluateWithTemporaryDisplay_(
        1048 goog.style.getSizeWithDisplay_, /** @type {!Element} */ (element));
        1049};
        1050
        1051
        1052/**
        1053 * Call {@code fn} on {@code element} such that {@code element}'s dimensions are
        1054 * accurate when it's passed to {@code fn}.
        1055 * @param {function(!Element): T} fn Function to call with {@code element} as
        1056 * an argument after temporarily changing {@code element}'s display such
        1057 * that its dimensions are accurate.
        1058 * @param {!Element} element Element (which may have display none) to use as
        1059 * argument to {@code fn}.
        1060 * @return {T} Value returned by calling {@code fn} with {@code element}.
        1061 * @template T
        1062 * @private
        1063 */
        1064goog.style.evaluateWithTemporaryDisplay_ = function(fn, element) {
        1065 if (goog.style.getStyle_(element, 'display') != 'none') {
        1066 return fn(element);
        1067 }
        1068
        1069 var style = element.style;
        1070 var originalDisplay = style.display;
        1071 var originalVisibility = style.visibility;
        1072 var originalPosition = style.position;
        1073
        1074 style.visibility = 'hidden';
        1075 style.position = 'absolute';
        1076 style.display = 'inline';
        1077
        1078 var retVal = fn(element);
        1079
        1080 style.display = originalDisplay;
        1081 style.position = originalPosition;
        1082 style.visibility = originalVisibility;
        1083
        1084 return retVal;
        1085};
        1086
        1087
        1088/**
        1089 * Gets the height and width of an element when the display is not none.
        1090 * @param {Element} element Element to get size of.
        1091 * @return {!goog.math.Size} Object with width/height properties.
        1092 * @private
        1093 */
        1094goog.style.getSizeWithDisplay_ = function(element) {
        1095 var offsetWidth = element.offsetWidth;
        1096 var offsetHeight = element.offsetHeight;
        1097 var webkitOffsetsZero =
        1098 goog.userAgent.WEBKIT && !offsetWidth && !offsetHeight;
        1099 if ((!goog.isDef(offsetWidth) || webkitOffsetsZero) &&
        1100 element.getBoundingClientRect) {
        1101 // Fall back to calling getBoundingClientRect when offsetWidth or
        1102 // offsetHeight are not defined, or when they are zero in WebKit browsers.
        1103 // This makes sure that we return for the correct size for SVG elements, but
        1104 // will still return 0 on Webkit prior to 534.8, see
        1105 // http://trac.webkit.org/changeset/67252.
        1106 var clientRect = goog.style.getBoundingClientRect_(element);
        1107 return new goog.math.Size(clientRect.right - clientRect.left,
        1108 clientRect.bottom - clientRect.top);
        1109 }
        1110 return new goog.math.Size(offsetWidth, offsetHeight);
        1111};
        1112
        1113
        1114/**
        1115 * Gets the height and width of an element, post transform, even if its display
        1116 * is none.
        1117 *
        1118 * This is like {@code goog.style.getSize}, except:
        1119 * <ol>
        1120 * <li>Takes webkitTransforms such as rotate and scale into account.
        1121 * <li>Will return null if {@code element} doesn't respond to
        1122 * {@code getBoundingClientRect}.
        1123 * <li>Currently doesn't make sense on non-WebKit browsers which don't support
        1124 * webkitTransforms.
        1125 * </ol>
        1126 * @param {!Element} element Element to get size of.
        1127 * @return {goog.math.Size} Object with width/height properties.
        1128 */
        1129goog.style.getTransformedSize = function(element) {
        1130 if (!element.getBoundingClientRect) {
        1131 return null;
        1132 }
        1133
        1134 var clientRect = goog.style.evaluateWithTemporaryDisplay_(
        1135 goog.style.getBoundingClientRect_, element);
        1136 return new goog.math.Size(clientRect.right - clientRect.left,
        1137 clientRect.bottom - clientRect.top);
        1138};
        1139
        1140
        1141/**
        1142 * Returns a bounding rectangle for a given element in page space.
        1143 * @param {Element} element Element to get bounds of. Must not be display none.
        1144 * @return {!goog.math.Rect} Bounding rectangle for the element.
        1145 */
        1146goog.style.getBounds = function(element) {
        1147 var o = goog.style.getPageOffset(element);
        1148 var s = goog.style.getSize(element);
        1149 return new goog.math.Rect(o.x, o.y, s.width, s.height);
        1150};
        1151
        1152
        1153/**
        1154 * Converts a CSS selector in the form style-property to styleProperty.
        1155 * @param {*} selector CSS Selector.
        1156 * @return {string} Camel case selector.
        1157 * @deprecated Use goog.string.toCamelCase instead.
        1158 */
        1159goog.style.toCamelCase = function(selector) {
        1160 return goog.string.toCamelCase(String(selector));
        1161};
        1162
        1163
        1164/**
        1165 * Converts a CSS selector in the form styleProperty to style-property.
        1166 * @param {string} selector Camel case selector.
        1167 * @return {string} Selector cased.
        1168 * @deprecated Use goog.string.toSelectorCase instead.
        1169 */
        1170goog.style.toSelectorCase = function(selector) {
        1171 return goog.string.toSelectorCase(selector);
        1172};
        1173
        1174
        1175/**
        1176 * Gets the opacity of a node (x-browser). This gets the inline style opacity
        1177 * of the node, and does not take into account the cascaded or the computed
        1178 * style for this node.
        1179 * @param {Element} el Element whose opacity has to be found.
        1180 * @return {number|string} Opacity between 0 and 1 or an empty string {@code ''}
        1181 * if the opacity is not set.
        1182 */
        1183goog.style.getOpacity = function(el) {
        1184 var style = el.style;
        1185 var result = '';
        1186 if ('opacity' in style) {
        1187 result = style.opacity;
        1188 } else if ('MozOpacity' in style) {
        1189 result = style.MozOpacity;
        1190 } else if ('filter' in style) {
        1191 var match = style.filter.match(/alpha\(opacity=([\d.]+)\)/);
        1192 if (match) {
        1193 result = String(match[1] / 100);
        1194 }
        1195 }
        1196 return result == '' ? result : Number(result);
        1197};
        1198
        1199
        1200/**
        1201 * Sets the opacity of a node (x-browser).
        1202 * @param {Element} el Elements whose opacity has to be set.
        1203 * @param {number|string} alpha Opacity between 0 and 1 or an empty string
        1204 * {@code ''} to clear the opacity.
        1205 */
        1206goog.style.setOpacity = function(el, alpha) {
        1207 var style = el.style;
        1208 if ('opacity' in style) {
        1209 style.opacity = alpha;
        1210 } else if ('MozOpacity' in style) {
        1211 style.MozOpacity = alpha;
        1212 } else if ('filter' in style) {
        1213 // TODO(arv): Overwriting the filter might have undesired side effects.
        1214 if (alpha === '') {
        1215 style.filter = '';
        1216 } else {
        1217 style.filter = 'alpha(opacity=' + alpha * 100 + ')';
        1218 }
        1219 }
        1220};
        1221
        1222
        1223/**
        1224 * Sets the background of an element to a transparent image in a browser-
        1225 * independent manner.
        1226 *
        1227 * This function does not support repeating backgrounds or alternate background
        1228 * positions to match the behavior of Internet Explorer. It also does not
        1229 * support sizingMethods other than crop since they cannot be replicated in
        1230 * browsers other than Internet Explorer.
        1231 *
        1232 * @param {Element} el The element to set background on.
        1233 * @param {string} src The image source URL.
        1234 */
        1235goog.style.setTransparentBackgroundImage = function(el, src) {
        1236 var style = el.style;
        1237 // It is safe to use the style.filter in IE only. In Safari 'filter' is in
        1238 // style object but access to style.filter causes it to throw an exception.
        1239 // Note: IE8 supports images with an alpha channel.
        1240 if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('8')) {
        1241 // See TODO in setOpacity.
        1242 style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(' +
        1243 'src="' + src + '", sizingMethod="crop")';
        1244 } else {
        1245 // Set style properties individually instead of using background shorthand
        1246 // to prevent overwriting a pre-existing background color.
        1247 style.backgroundImage = 'url(' + src + ')';
        1248 style.backgroundPosition = 'top left';
        1249 style.backgroundRepeat = 'no-repeat';
        1250 }
        1251};
        1252
        1253
        1254/**
        1255 * Clears the background image of an element in a browser independent manner.
        1256 * @param {Element} el The element to clear background image for.
        1257 */
        1258goog.style.clearTransparentBackgroundImage = function(el) {
        1259 var style = el.style;
        1260 if ('filter' in style) {
        1261 // See TODO in setOpacity.
        1262 style.filter = '';
        1263 } else {
        1264 // Set style properties individually instead of using background shorthand
        1265 // to prevent overwriting a pre-existing background color.
        1266 style.backgroundImage = 'none';
        1267 }
        1268};
        1269
        1270
        1271/**
        1272 * Shows or hides an element from the page. Hiding the element is done by
        1273 * setting the display property to "none", removing the element from the
        1274 * rendering hierarchy so it takes up no space. To show the element, the default
        1275 * inherited display property is restored (defined either in stylesheets or by
        1276 * the browser's default style rules.)
        1277 *
        1278 * Caveat 1: if the inherited display property for the element is set to "none"
        1279 * by the stylesheets, that is the property that will be restored by a call to
        1280 * showElement(), effectively toggling the display between "none" and "none".
        1281 *
        1282 * Caveat 2: if the element display style is set inline (by setting either
        1283 * element.style.display or a style attribute in the HTML), a call to
        1284 * showElement will clear that setting and defer to the inherited style in the
        1285 * stylesheet.
        1286 * @param {Element} el Element to show or hide.
        1287 * @param {*} display True to render the element in its default style,
        1288 * false to disable rendering the element.
        1289 * @deprecated Use goog.style.setElementShown instead.
        1290 */
        1291goog.style.showElement = function(el, display) {
        1292 goog.style.setElementShown(el, display);
        1293};
        1294
        1295
        1296/**
        1297 * Shows or hides an element from the page. Hiding the element is done by
        1298 * setting the display property to "none", removing the element from the
        1299 * rendering hierarchy so it takes up no space. To show the element, the default
        1300 * inherited display property is restored (defined either in stylesheets or by
        1301 * the browser's default style rules).
        1302 *
        1303 * Caveat 1: if the inherited display property for the element is set to "none"
        1304 * by the stylesheets, that is the property that will be restored by a call to
        1305 * setElementShown(), effectively toggling the display between "none" and
        1306 * "none".
        1307 *
        1308 * Caveat 2: if the element display style is set inline (by setting either
        1309 * element.style.display or a style attribute in the HTML), a call to
        1310 * setElementShown will clear that setting and defer to the inherited style in
        1311 * the stylesheet.
        1312 * @param {Element} el Element to show or hide.
        1313 * @param {*} isShown True to render the element in its default style,
        1314 * false to disable rendering the element.
        1315 */
        1316goog.style.setElementShown = function(el, isShown) {
        1317 el.style.display = isShown ? '' : 'none';
        1318};
        1319
        1320
        1321/**
        1322 * Test whether the given element has been shown or hidden via a call to
        1323 * {@link #setElementShown}.
        1324 *
        1325 * Note this is strictly a companion method for a call
        1326 * to {@link #setElementShown} and the same caveats apply; in particular, this
        1327 * method does not guarantee that the return value will be consistent with
        1328 * whether or not the element is actually visible.
        1329 *
        1330 * @param {Element} el The element to test.
        1331 * @return {boolean} Whether the element has been shown.
        1332 * @see #setElementShown
        1333 */
        1334goog.style.isElementShown = function(el) {
        1335 return el.style.display != 'none';
        1336};
        1337
        1338
        1339/**
        1340 * Installs the styles string into the window that contains opt_element. If
        1341 * opt_element is null, the main window is used.
        1342 * @param {string} stylesString The style string to install.
        1343 * @param {Node=} opt_node Node whose parent document should have the
        1344 * styles installed.
        1345 * @return {Element|StyleSheet} The style element created.
        1346 */
        1347goog.style.installStyles = function(stylesString, opt_node) {
        1348 var dh = goog.dom.getDomHelper(opt_node);
        1349 var styleSheet = null;
        1350
        1351 // IE < 11 requires createStyleSheet. Note that doc.createStyleSheet will be
        1352 // undefined as of IE 11.
        1353 var doc = dh.getDocument();
        1354 if (goog.userAgent.IE && doc.createStyleSheet) {
        1355 styleSheet = doc.createStyleSheet();
        1356 goog.style.setStyles(styleSheet, stylesString);
        1357 } else {
        1358 var head = dh.getElementsByTagNameAndClass('head')[0];
        1359
        1360 // In opera documents are not guaranteed to have a head element, thus we
        1361 // have to make sure one exists before using it.
        1362 if (!head) {
        1363 var body = dh.getElementsByTagNameAndClass('body')[0];
        1364 head = dh.createDom('head');
        1365 body.parentNode.insertBefore(head, body);
        1366 }
        1367 styleSheet = dh.createDom('style');
        1368 // NOTE(user): Setting styles after the style element has been appended
        1369 // to the head results in a nasty Webkit bug in certain scenarios. Please
        1370 // refer to https://bugs.webkit.org/show_bug.cgi?id=26307 for additional
        1371 // details.
        1372 goog.style.setStyles(styleSheet, stylesString);
        1373 dh.appendChild(head, styleSheet);
        1374 }
        1375 return styleSheet;
        1376};
        1377
        1378
        1379/**
        1380 * Removes the styles added by {@link #installStyles}.
        1381 * @param {Element|StyleSheet} styleSheet The value returned by
        1382 * {@link #installStyles}.
        1383 */
        1384goog.style.uninstallStyles = function(styleSheet) {
        1385 var node = styleSheet.ownerNode || styleSheet.owningElement ||
        1386 /** @type {Element} */ (styleSheet);
        1387 goog.dom.removeNode(node);
        1388};
        1389
        1390
        1391/**
        1392 * Sets the content of a style element. The style element can be any valid
        1393 * style element. This element will have its content completely replaced by
        1394 * the new stylesString.
        1395 * @param {Element|StyleSheet} element A stylesheet element as returned by
        1396 * installStyles.
        1397 * @param {string} stylesString The new content of the stylesheet.
        1398 */
        1399goog.style.setStyles = function(element, stylesString) {
        1400 if (goog.userAgent.IE && goog.isDef(element.cssText)) {
        1401 // Adding the selectors individually caused the browser to hang if the
        1402 // selector was invalid or there were CSS comments. Setting the cssText of
        1403 // the style node works fine and ignores CSS that IE doesn't understand.
        1404 // However IE >= 11 doesn't support cssText any more, so we make sure that
        1405 // cssText is a defined property and otherwise fall back to innerHTML.
        1406 element.cssText = stylesString;
        1407 } else {
        1408 element.innerHTML = stylesString;
        1409 }
        1410};
        1411
        1412
        1413/**
        1414 * Sets 'white-space: pre-wrap' for a node (x-browser).
        1415 *
        1416 * There are as many ways of specifying pre-wrap as there are browsers.
        1417 *
        1418 * CSS3/IE8: white-space: pre-wrap;
        1419 * Mozilla: white-space: -moz-pre-wrap;
        1420 * Opera: white-space: -o-pre-wrap;
        1421 * IE6/7: white-space: pre; word-wrap: break-word;
        1422 *
        1423 * @param {Element} el Element to enable pre-wrap for.
        1424 */
        1425goog.style.setPreWrap = function(el) {
        1426 var style = el.style;
        1427 if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('8')) {
        1428 style.whiteSpace = 'pre';
        1429 style.wordWrap = 'break-word';
        1430 } else if (goog.userAgent.GECKO) {
        1431 style.whiteSpace = '-moz-pre-wrap';
        1432 } else {
        1433 style.whiteSpace = 'pre-wrap';
        1434 }
        1435};
        1436
        1437
        1438/**
        1439 * Sets 'display: inline-block' for an element (cross-browser).
        1440 * @param {Element} el Element to which the inline-block display style is to be
        1441 * applied.
        1442 * @see ../demos/inline_block_quirks.html
        1443 * @see ../demos/inline_block_standards.html
        1444 */
        1445goog.style.setInlineBlock = function(el) {
        1446 var style = el.style;
        1447 // Without position:relative, weirdness ensues. Just accept it and move on.
        1448 style.position = 'relative';
        1449
        1450 if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('8')) {
        1451 // IE8 supports inline-block so fall through to the else
        1452 // Zoom:1 forces hasLayout, display:inline gives inline behavior.
        1453 style.zoom = '1';
        1454 style.display = 'inline';
        1455 } else if (goog.userAgent.GECKO) {
        1456 // Pre-Firefox 3, Gecko doesn't support inline-block, but -moz-inline-box
        1457 // is close enough.
        1458 style.display = goog.userAgent.isVersionOrHigher('1.9a') ? 'inline-block' :
        1459 '-moz-inline-box';
        1460 } else {
        1461 // Opera, Webkit, and Safari seem to do OK with the standard inline-block
        1462 // style.
        1463 style.display = 'inline-block';
        1464 }
        1465};
        1466
        1467
        1468/**
        1469 * Returns true if the element is using right to left (rtl) direction.
        1470 * @param {Element} el The element to test.
        1471 * @return {boolean} True for right to left, false for left to right.
        1472 */
        1473goog.style.isRightToLeft = function(el) {
        1474 return 'rtl' == goog.style.getStyle_(el, 'direction');
        1475};
        1476
        1477
        1478/**
        1479 * The CSS style property corresponding to an element being
        1480 * unselectable on the current browser platform (null if none).
        1481 * Opera and IE instead use a DOM attribute 'unselectable'.
        1482 * @type {?string}
        1483 * @private
        1484 */
        1485goog.style.unselectableStyle_ =
        1486 goog.userAgent.GECKO ? 'MozUserSelect' :
        1487 goog.userAgent.WEBKIT ? 'WebkitUserSelect' :
        1488 null;
        1489
        1490
        1491/**
        1492 * Returns true if the element is set to be unselectable, false otherwise.
        1493 * Note that on some platforms (e.g. Mozilla), even if an element isn't set
        1494 * to be unselectable, it will behave as such if any of its ancestors is
        1495 * unselectable.
        1496 * @param {Element} el Element to check.
        1497 * @return {boolean} Whether the element is set to be unselectable.
        1498 */
        1499goog.style.isUnselectable = function(el) {
        1500 if (goog.style.unselectableStyle_) {
        1501 return el.style[goog.style.unselectableStyle_].toLowerCase() == 'none';
        1502 } else if (goog.userAgent.IE || goog.userAgent.OPERA) {
        1503 return el.getAttribute('unselectable') == 'on';
        1504 }
        1505 return false;
        1506};
        1507
        1508
        1509/**
        1510 * Makes the element and its descendants selectable or unselectable. Note
        1511 * that on some platforms (e.g. Mozilla), even if an element isn't set to
        1512 * be unselectable, it will behave as such if any of its ancestors is
        1513 * unselectable.
        1514 * @param {Element} el The element to alter.
        1515 * @param {boolean} unselectable Whether the element and its descendants
        1516 * should be made unselectable.
        1517 * @param {boolean=} opt_noRecurse Whether to only alter the element's own
        1518 * selectable state, and leave its descendants alone; defaults to false.
        1519 */
        1520goog.style.setUnselectable = function(el, unselectable, opt_noRecurse) {
        1521 // TODO(attila): Do we need all of TR_DomUtil.makeUnselectable() in Closure?
        1522 var descendants = !opt_noRecurse ? el.getElementsByTagName('*') : null;
        1523 var name = goog.style.unselectableStyle_;
        1524 if (name) {
        1525 // Add/remove the appropriate CSS style to/from the element and its
        1526 // descendants.
        1527 var value = unselectable ? 'none' : '';
        1528 el.style[name] = value;
        1529 if (descendants) {
        1530 for (var i = 0, descendant; descendant = descendants[i]; i++) {
        1531 descendant.style[name] = value;
        1532 }
        1533 }
        1534 } else if (goog.userAgent.IE || goog.userAgent.OPERA) {
        1535 // Toggle the 'unselectable' attribute on the element and its descendants.
        1536 var value = unselectable ? 'on' : '';
        1537 el.setAttribute('unselectable', value);
        1538 if (descendants) {
        1539 for (var i = 0, descendant; descendant = descendants[i]; i++) {
        1540 descendant.setAttribute('unselectable', value);
        1541 }
        1542 }
        1543 }
        1544};
        1545
        1546
        1547/**
        1548 * Gets the border box size for an element.
        1549 * @param {Element} element The element to get the size for.
        1550 * @return {!goog.math.Size} The border box size.
        1551 */
        1552goog.style.getBorderBoxSize = function(element) {
        1553 return new goog.math.Size(element.offsetWidth, element.offsetHeight);
        1554};
        1555
        1556
        1557/**
        1558 * Sets the border box size of an element. This is potentially expensive in IE
        1559 * if the document is CSS1Compat mode
        1560 * @param {Element} element The element to set the size on.
        1561 * @param {goog.math.Size} size The new size.
        1562 */
        1563goog.style.setBorderBoxSize = function(element, size) {
        1564 var doc = goog.dom.getOwnerDocument(element);
        1565 var isCss1CompatMode = goog.dom.getDomHelper(doc).isCss1CompatMode();
        1566
        1567 if (goog.userAgent.IE &&
        1568 !goog.userAgent.isVersionOrHigher('10') &&
        1569 (!isCss1CompatMode || !goog.userAgent.isVersionOrHigher('8'))) {
        1570 var style = element.style;
        1571 if (isCss1CompatMode) {
        1572 var paddingBox = goog.style.getPaddingBox(element);
        1573 var borderBox = goog.style.getBorderBox(element);
        1574 style.pixelWidth = size.width - borderBox.left - paddingBox.left -
        1575 paddingBox.right - borderBox.right;
        1576 style.pixelHeight = size.height - borderBox.top - paddingBox.top -
        1577 paddingBox.bottom - borderBox.bottom;
        1578 } else {
        1579 style.pixelWidth = size.width;
        1580 style.pixelHeight = size.height;
        1581 }
        1582 } else {
        1583 goog.style.setBoxSizingSize_(element, size, 'border-box');
        1584 }
        1585};
        1586
        1587
        1588/**
        1589 * Gets the content box size for an element. This is potentially expensive in
        1590 * all browsers.
        1591 * @param {Element} element The element to get the size for.
        1592 * @return {!goog.math.Size} The content box size.
        1593 */
        1594goog.style.getContentBoxSize = function(element) {
        1595 var doc = goog.dom.getOwnerDocument(element);
        1596 var ieCurrentStyle = goog.userAgent.IE && element.currentStyle;
        1597 if (ieCurrentStyle &&
        1598 goog.dom.getDomHelper(doc).isCss1CompatMode() &&
        1599 ieCurrentStyle.width != 'auto' && ieCurrentStyle.height != 'auto' &&
        1600 !ieCurrentStyle.boxSizing) {
        1601 // If IE in CSS1Compat mode than just use the width and height.
        1602 // If we have a boxSizing then fall back on measuring the borders etc.
        1603 var width = goog.style.getIePixelValue_(element, ieCurrentStyle.width,
        1604 'width', 'pixelWidth');
        1605 var height = goog.style.getIePixelValue_(element, ieCurrentStyle.height,
        1606 'height', 'pixelHeight');
        1607 return new goog.math.Size(width, height);
        1608 } else {
        1609 var borderBoxSize = goog.style.getBorderBoxSize(element);
        1610 var paddingBox = goog.style.getPaddingBox(element);
        1611 var borderBox = goog.style.getBorderBox(element);
        1612 return new goog.math.Size(borderBoxSize.width -
        1613 borderBox.left - paddingBox.left -
        1614 paddingBox.right - borderBox.right,
        1615 borderBoxSize.height -
        1616 borderBox.top - paddingBox.top -
        1617 paddingBox.bottom - borderBox.bottom);
        1618 }
        1619};
        1620
        1621
        1622/**
        1623 * Sets the content box size of an element. This is potentially expensive in IE
        1624 * if the document is BackCompat mode.
        1625 * @param {Element} element The element to set the size on.
        1626 * @param {goog.math.Size} size The new size.
        1627 */
        1628goog.style.setContentBoxSize = function(element, size) {
        1629 var doc = goog.dom.getOwnerDocument(element);
        1630 var isCss1CompatMode = goog.dom.getDomHelper(doc).isCss1CompatMode();
        1631 if (goog.userAgent.IE &&
        1632 !goog.userAgent.isVersionOrHigher('10') &&
        1633 (!isCss1CompatMode || !goog.userAgent.isVersionOrHigher('8'))) {
        1634 var style = element.style;
        1635 if (isCss1CompatMode) {
        1636 style.pixelWidth = size.width;
        1637 style.pixelHeight = size.height;
        1638 } else {
        1639 var paddingBox = goog.style.getPaddingBox(element);
        1640 var borderBox = goog.style.getBorderBox(element);
        1641 style.pixelWidth = size.width + borderBox.left + paddingBox.left +
        1642 paddingBox.right + borderBox.right;
        1643 style.pixelHeight = size.height + borderBox.top + paddingBox.top +
        1644 paddingBox.bottom + borderBox.bottom;
        1645 }
        1646 } else {
        1647 goog.style.setBoxSizingSize_(element, size, 'content-box');
        1648 }
        1649};
        1650
        1651
        1652/**
        1653 * Helper function that sets the box sizing as well as the width and height
        1654 * @param {Element} element The element to set the size on.
        1655 * @param {goog.math.Size} size The new size to set.
        1656 * @param {string} boxSizing The box-sizing value.
        1657 * @private
        1658 */
        1659goog.style.setBoxSizingSize_ = function(element, size, boxSizing) {
        1660 var style = element.style;
        1661 if (goog.userAgent.GECKO) {
        1662 style.MozBoxSizing = boxSizing;
        1663 } else if (goog.userAgent.WEBKIT) {
        1664 style.WebkitBoxSizing = boxSizing;
        1665 } else {
        1666 // Includes IE8 and Opera 9.50+
        1667 style.boxSizing = boxSizing;
        1668 }
        1669
        1670 // Setting this to a negative value will throw an exception on IE
        1671 // (and doesn't do anything different than setting it to 0).
        1672 style.width = Math.max(size.width, 0) + 'px';
        1673 style.height = Math.max(size.height, 0) + 'px';
        1674};
        1675
        1676
        1677/**
        1678 * IE specific function that converts a non pixel unit to pixels.
        1679 * @param {Element} element The element to convert the value for.
        1680 * @param {string} value The current value as a string. The value must not be
        1681 * ''.
        1682 * @param {string} name The CSS property name to use for the converstion. This
        1683 * should be 'left', 'top', 'width' or 'height'.
        1684 * @param {string} pixelName The CSS pixel property name to use to get the
        1685 * value in pixels.
        1686 * @return {number} The value in pixels.
        1687 * @private
        1688 */
        1689goog.style.getIePixelValue_ = function(element, value, name, pixelName) {
        1690 // Try if we already have a pixel value. IE does not do half pixels so we
        1691 // only check if it matches a number followed by 'px'.
        1692 if (/^\d+px?$/.test(value)) {
        1693 return parseInt(value, 10);
        1694 } else {
        1695 var oldStyleValue = element.style[name];
        1696 var oldRuntimeValue = element.runtimeStyle[name];
        1697 // set runtime style to prevent changes
        1698 element.runtimeStyle[name] = element.currentStyle[name];
        1699 element.style[name] = value;
        1700 var pixelValue = element.style[pixelName];
        1701 // restore
        1702 element.style[name] = oldStyleValue;
        1703 element.runtimeStyle[name] = oldRuntimeValue;
        1704 return pixelValue;
        1705 }
        1706};
        1707
        1708
        1709/**
        1710 * Helper function for getting the pixel padding or margin for IE.
        1711 * @param {Element} element The element to get the padding for.
        1712 * @param {string} propName The property name.
        1713 * @return {number} The pixel padding.
        1714 * @private
        1715 */
        1716goog.style.getIePixelDistance_ = function(element, propName) {
        1717 var value = goog.style.getCascadedStyle(element, propName);
        1718 return value ?
        1719 goog.style.getIePixelValue_(element, value, 'left', 'pixelLeft') : 0;
        1720};
        1721
        1722
        1723/**
        1724 * Gets the computed paddings or margins (on all sides) in pixels.
        1725 * @param {Element} element The element to get the padding for.
        1726 * @param {string} stylePrefix Pass 'padding' to retrieve the padding box,
        1727 * or 'margin' to retrieve the margin box.
        1728 * @return {!goog.math.Box} The computed paddings or margins.
        1729 * @private
        1730 */
        1731goog.style.getBox_ = function(element, stylePrefix) {
        1732 if (goog.userAgent.IE) {
        1733 var left = goog.style.getIePixelDistance_(element, stylePrefix + 'Left');
        1734 var right = goog.style.getIePixelDistance_(element, stylePrefix + 'Right');
        1735 var top = goog.style.getIePixelDistance_(element, stylePrefix + 'Top');
        1736 var bottom = goog.style.getIePixelDistance_(
        1737 element, stylePrefix + 'Bottom');
        1738 return new goog.math.Box(top, right, bottom, left);
        1739 } else {
        1740 // On non-IE browsers, getComputedStyle is always non-null.
        1741 var left = /** @type {string} */ (
        1742 goog.style.getComputedStyle(element, stylePrefix + 'Left'));
        1743 var right = /** @type {string} */ (
        1744 goog.style.getComputedStyle(element, stylePrefix + 'Right'));
        1745 var top = /** @type {string} */ (
        1746 goog.style.getComputedStyle(element, stylePrefix + 'Top'));
        1747 var bottom = /** @type {string} */ (
        1748 goog.style.getComputedStyle(element, stylePrefix + 'Bottom'));
        1749
        1750 // NOTE(arv): Gecko can return floating point numbers for the computed
        1751 // style values.
        1752 return new goog.math.Box(parseFloat(top),
        1753 parseFloat(right),
        1754 parseFloat(bottom),
        1755 parseFloat(left));
        1756 }
        1757};
        1758
        1759
        1760/**
        1761 * Gets the computed paddings (on all sides) in pixels.
        1762 * @param {Element} element The element to get the padding for.
        1763 * @return {!goog.math.Box} The computed paddings.
        1764 */
        1765goog.style.getPaddingBox = function(element) {
        1766 return goog.style.getBox_(element, 'padding');
        1767};
        1768
        1769
        1770/**
        1771 * Gets the computed margins (on all sides) in pixels.
        1772 * @param {Element} element The element to get the margins for.
        1773 * @return {!goog.math.Box} The computed margins.
        1774 */
        1775goog.style.getMarginBox = function(element) {
        1776 return goog.style.getBox_(element, 'margin');
        1777};
        1778
        1779
        1780/**
        1781 * A map used to map the border width keywords to a pixel width.
        1782 * @type {Object}
        1783 * @private
        1784 */
        1785goog.style.ieBorderWidthKeywords_ = {
        1786 'thin': 2,
        1787 'medium': 4,
        1788 'thick': 6
        1789};
        1790
        1791
        1792/**
        1793 * Helper function for IE to get the pixel border.
        1794 * @param {Element} element The element to get the pixel border for.
        1795 * @param {string} prop The part of the property name.
        1796 * @return {number} The value in pixels.
        1797 * @private
        1798 */
        1799goog.style.getIePixelBorder_ = function(element, prop) {
        1800 if (goog.style.getCascadedStyle(element, prop + 'Style') == 'none') {
        1801 return 0;
        1802 }
        1803 var width = goog.style.getCascadedStyle(element, prop + 'Width');
        1804 if (width in goog.style.ieBorderWidthKeywords_) {
        1805 return goog.style.ieBorderWidthKeywords_[width];
        1806 }
        1807 return goog.style.getIePixelValue_(element, width, 'left', 'pixelLeft');
        1808};
        1809
        1810
        1811/**
        1812 * Gets the computed border widths (on all sides) in pixels
        1813 * @param {Element} element The element to get the border widths for.
        1814 * @return {!goog.math.Box} The computed border widths.
        1815 */
        1816goog.style.getBorderBox = function(element) {
        1817 if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) {
        1818 var left = goog.style.getIePixelBorder_(element, 'borderLeft');
        1819 var right = goog.style.getIePixelBorder_(element, 'borderRight');
        1820 var top = goog.style.getIePixelBorder_(element, 'borderTop');
        1821 var bottom = goog.style.getIePixelBorder_(element, 'borderBottom');
        1822 return new goog.math.Box(top, right, bottom, left);
        1823 } else {
        1824 // On non-IE browsers, getComputedStyle is always non-null.
        1825 var left = /** @type {string} */ (
        1826 goog.style.getComputedStyle(element, 'borderLeftWidth'));
        1827 var right = /** @type {string} */ (
        1828 goog.style.getComputedStyle(element, 'borderRightWidth'));
        1829 var top = /** @type {string} */ (
        1830 goog.style.getComputedStyle(element, 'borderTopWidth'));
        1831 var bottom = /** @type {string} */ (
        1832 goog.style.getComputedStyle(element, 'borderBottomWidth'));
        1833
        1834 return new goog.math.Box(parseFloat(top),
        1835 parseFloat(right),
        1836 parseFloat(bottom),
        1837 parseFloat(left));
        1838 }
        1839};
        1840
        1841
        1842/**
        1843 * Returns the font face applied to a given node. Opera and IE should return
        1844 * the font actually displayed. Firefox returns the author's most-preferred
        1845 * font (whether the browser is capable of displaying it or not.)
        1846 * @param {Element} el The element whose font family is returned.
        1847 * @return {string} The font family applied to el.
        1848 */
        1849goog.style.getFontFamily = function(el) {
        1850 var doc = goog.dom.getOwnerDocument(el);
        1851 var font = '';
        1852 // The moveToElementText method from the TextRange only works if the element
        1853 // is attached to the owner document.
        1854 if (doc.body.createTextRange && goog.dom.contains(doc, el)) {
        1855 var range = doc.body.createTextRange();
        1856 range.moveToElementText(el);
        1857 /** @preserveTry */
        1858 try {
        1859 font = range.queryCommandValue('FontName');
        1860 } catch (e) {
        1861 // This is a workaround for a awkward exception.
        1862 // On some IE, there is an exception coming from it.
        1863 // The error description from this exception is:
        1864 // This window has already been registered as a drop target
        1865 // This is bogus description, likely due to a bug in ie.
        1866 font = '';
        1867 }
        1868 }
        1869 if (!font) {
        1870 // Note if for some reason IE can't derive FontName with a TextRange, we
        1871 // fallback to using currentStyle
        1872 font = goog.style.getStyle_(el, 'fontFamily');
        1873 }
        1874
        1875 // Firefox returns the applied font-family string (author's list of
        1876 // preferred fonts.) We want to return the most-preferred font, in lieu of
        1877 // the *actually* applied font.
        1878 var fontsArray = font.split(',');
        1879 if (fontsArray.length > 1) font = fontsArray[0];
        1880
        1881 // Sanitize for x-browser consistency:
        1882 // Strip quotes because browsers aren't consistent with how they're
        1883 // applied; Opera always encloses, Firefox sometimes, and IE never.
        1884 return goog.string.stripQuotes(font, '"\'');
        1885};
        1886
        1887
        1888/**
        1889 * Regular expression used for getLengthUnits.
        1890 * @type {RegExp}
        1891 * @private
        1892 */
        1893goog.style.lengthUnitRegex_ = /[^\d]+$/;
        1894
        1895
        1896/**
        1897 * Returns the units used for a CSS length measurement.
        1898 * @param {string} value A CSS length quantity.
        1899 * @return {?string} The units of measurement.
        1900 */
        1901goog.style.getLengthUnits = function(value) {
        1902 var units = value.match(goog.style.lengthUnitRegex_);
        1903 return units && units[0] || null;
        1904};
        1905
        1906
        1907/**
        1908 * Map of absolute CSS length units
        1909 * @type {Object}
        1910 * @private
        1911 */
        1912goog.style.ABSOLUTE_CSS_LENGTH_UNITS_ = {
        1913 'cm' : 1,
        1914 'in' : 1,
        1915 'mm' : 1,
        1916 'pc' : 1,
        1917 'pt' : 1
        1918};
        1919
        1920
        1921/**
        1922 * Map of relative CSS length units that can be accurately converted to px
        1923 * font-size values using getIePixelValue_. Only units that are defined in
        1924 * relation to a font size are convertible (%, small, etc. are not).
        1925 * @type {Object}
        1926 * @private
        1927 */
        1928goog.style.CONVERTIBLE_RELATIVE_CSS_UNITS_ = {
        1929 'em' : 1,
        1930 'ex' : 1
        1931};
        1932
        1933
        1934/**
        1935 * Returns the font size, in pixels, of text in an element.
        1936 * @param {Element} el The element whose font size is returned.
        1937 * @return {number} The font size (in pixels).
        1938 */
        1939goog.style.getFontSize = function(el) {
        1940 var fontSize = goog.style.getStyle_(el, 'fontSize');
        1941 var sizeUnits = goog.style.getLengthUnits(fontSize);
        1942 if (fontSize && 'px' == sizeUnits) {
        1943 // NOTE(user): This could be parseFloat instead, but IE doesn't return
        1944 // decimal fractions in getStyle_ and Firefox reports the fractions, but
        1945 // ignores them when rendering. Interestingly enough, when we force the
        1946 // issue and size something to e.g., 50% of 25px, the browsers round in
        1947 // opposite directions with Firefox reporting 12px and IE 13px. I punt.
        1948 return parseInt(fontSize, 10);
        1949 }
        1950
        1951 // In IE, we can convert absolute length units to a px value using
        1952 // goog.style.getIePixelValue_. Units defined in relation to a font size
        1953 // (em, ex) are applied relative to the element's parentNode and can also
        1954 // be converted.
        1955 if (goog.userAgent.IE) {
        1956 if (sizeUnits in goog.style.ABSOLUTE_CSS_LENGTH_UNITS_) {
        1957 return goog.style.getIePixelValue_(el,
        1958 fontSize,
        1959 'left',
        1960 'pixelLeft');
        1961 } else if (el.parentNode &&
        1962 el.parentNode.nodeType == goog.dom.NodeType.ELEMENT &&
        1963 sizeUnits in goog.style.CONVERTIBLE_RELATIVE_CSS_UNITS_) {
        1964 // Check the parent size - if it is the same it means the relative size
        1965 // value is inherited and we therefore don't want to count it twice. If
        1966 // it is different, this element either has explicit style or has a CSS
        1967 // rule applying to it.
        1968 var parentElement = /** @type {Element} */ (el.parentNode);
        1969 var parentSize = goog.style.getStyle_(parentElement, 'fontSize');
        1970 return goog.style.getIePixelValue_(parentElement,
        1971 fontSize == parentSize ?
        1972 '1em' : fontSize,
        1973 'left',
        1974 'pixelLeft');
        1975 }
        1976 }
        1977
        1978 // Sometimes we can't cleanly find the font size (some units relative to a
        1979 // node's parent's font size are difficult: %, smaller et al), so we create
        1980 // an invisible, absolutely-positioned span sized to be the height of an 'M'
        1981 // rendered in its parent's (i.e., our target element's) font size. This is
        1982 // the definition of CSS's font size attribute.
        1983 var sizeElement = goog.dom.createDom(
        1984 'span',
        1985 {'style': 'visibility:hidden;position:absolute;' +
        1986 'line-height:0;padding:0;margin:0;border:0;height:1em;'});
        1987 goog.dom.appendChild(el, sizeElement);
        1988 fontSize = sizeElement.offsetHeight;
        1989 goog.dom.removeNode(sizeElement);
        1990
        1991 return fontSize;
        1992};
        1993
        1994
        1995/**
        1996 * Parses a style attribute value. Converts CSS property names to camel case.
        1997 * @param {string} value The style attribute value.
        1998 * @return {!Object} Map of CSS properties to string values.
        1999 */
        2000goog.style.parseStyleAttribute = function(value) {
        2001 var result = {};
        2002 goog.array.forEach(value.split(/\s*;\s*/), function(pair) {
        2003 var keyValue = pair.split(/\s*:\s*/);
        2004 if (keyValue.length == 2) {
        2005 result[goog.string.toCamelCase(keyValue[0].toLowerCase())] = keyValue[1];
        2006 }
        2007 });
        2008 return result;
        2009};
        2010
        2011
        2012/**
        2013 * Reverse of parseStyleAttribute; that is, takes a style object and returns the
        2014 * corresponding attribute value. Converts camel case property names to proper
        2015 * CSS selector names.
        2016 * @param {Object} obj Map of CSS properties to values.
        2017 * @return {string} The style attribute value.
        2018 */
        2019goog.style.toStyleAttribute = function(obj) {
        2020 var buffer = [];
        2021 goog.object.forEach(obj, function(value, key) {
        2022 buffer.push(goog.string.toSelectorCase(key), ':', value, ';');
        2023 });
        2024 return buffer.join('');
        2025};
        2026
        2027
        2028/**
        2029 * Sets CSS float property on an element.
        2030 * @param {Element} el The element to set float property on.
        2031 * @param {string} value The value of float CSS property to set on this element.
        2032 */
        2033goog.style.setFloat = function(el, value) {
        2034 el.style[goog.userAgent.IE ? 'styleFloat' : 'cssFloat'] = value;
        2035};
        2036
        2037
        2038/**
        2039 * Gets value of explicitly-set float CSS property on an element.
        2040 * @param {Element} el The element to get float property of.
        2041 * @return {string} The value of explicitly-set float CSS property on this
        2042 * element.
        2043 */
        2044goog.style.getFloat = function(el) {
        2045 return el.style[goog.userAgent.IE ? 'styleFloat' : 'cssFloat'] || '';
        2046};
        2047
        2048
        2049/**
        2050 * Returns the scroll bar width (represents the width of both horizontal
        2051 * and vertical scroll).
        2052 *
        2053 * @param {string=} opt_className An optional class name (or names) to apply
        2054 * to the invisible div created to measure the scrollbar. This is necessary
        2055 * if some scrollbars are styled differently than others.
        2056 * @return {number} The scroll bar width in px.
        2057 */
        2058goog.style.getScrollbarWidth = function(opt_className) {
        2059 // Add two hidden divs. The child div is larger than the parent and
        2060 // forces scrollbars to appear on it.
        2061 // Using overflow:scroll does not work consistently with scrollbars that
        2062 // are styled with ::-webkit-scrollbar.
        2063 var outerDiv = goog.dom.createElement('div');
        2064 if (opt_className) {
        2065 outerDiv.className = opt_className;
        2066 }
        2067 outerDiv.style.cssText = 'overflow:auto;' +
        2068 'position:absolute;top:0;width:100px;height:100px';
        2069 var innerDiv = goog.dom.createElement('div');
        2070 goog.style.setSize(innerDiv, '200px', '200px');
        2071 outerDiv.appendChild(innerDiv);
        2072 goog.dom.appendChild(goog.dom.getDocument().body, outerDiv);
        2073 var width = outerDiv.offsetWidth - outerDiv.clientWidth;
        2074 goog.dom.removeNode(outerDiv);
        2075 return width;
        2076};
        2077
        2078
        2079/**
        2080 * Regular expression to extract x and y translation components from a CSS
        2081 * transform Matrix representation.
        2082 *
        2083 * @type {!RegExp}
        2084 * @const
        2085 * @private
        2086 */
        2087goog.style.MATRIX_TRANSLATION_REGEX_ =
        2088 new RegExp('matrix\\([0-9\\.\\-]+, [0-9\\.\\-]+, ' +
        2089 '[0-9\\.\\-]+, [0-9\\.\\-]+, ' +
        2090 '([0-9\\.\\-]+)p?x?, ([0-9\\.\\-]+)p?x?\\)');
        2091
        2092
        2093/**
        2094 * Returns the x,y translation component of any CSS transforms applied to the
        2095 * element, in pixels.
        2096 *
        2097 * @param {!Element} element The element to get the translation of.
        2098 * @return {!goog.math.Coordinate} The CSS translation of the element in px.
        2099 */
        2100goog.style.getCssTranslation = function(element) {
        2101 var transform = goog.style.getComputedTransform(element);
        2102 if (!transform) {
        2103 return new goog.math.Coordinate(0, 0);
        2104 }
        2105 var matches = transform.match(goog.style.MATRIX_TRANSLATION_REGEX_);
        2106 if (!matches) {
        2107 return new goog.math.Coordinate(0, 0);
        2108 }
        2109 return new goog.math.Coordinate(parseFloat(matches[1]),
        2110 parseFloat(matches[2]));
        2111};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/asserts.js.src.html b/docs/api/javascript/source/lib/goog/testing/asserts.js.src.html new file mode 100644 index 0000000000000..39df7020d6eff --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/asserts.js.src.html @@ -0,0 +1 @@ +asserts.js

        lib/goog/testing/asserts.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.
        14goog.provide('goog.testing.JsUnitException');
        15goog.provide('goog.testing.asserts');
        16
        17goog.require('goog.testing.stacktrace');
        18
        19// TODO(user): Copied from JsUnit with some small modifications, we should
        20// reimplement the asserters.
        21
        22
        23/**
        24 * @typedef {Array|NodeList|Arguments|{length: number}}
        25 */
        26goog.testing.asserts.ArrayLike;
        27
        28var DOUBLE_EQUALITY_PREDICATE = function(var1, var2) {
        29 return var1 == var2;
        30};
        31var JSUNIT_UNDEFINED_VALUE;
        32var TO_STRING_EQUALITY_PREDICATE = function(var1, var2) {
        33 return var1.toString() === var2.toString();
        34};
        35
        36var PRIMITIVE_EQUALITY_PREDICATES = {
        37 'String': DOUBLE_EQUALITY_PREDICATE,
        38 'Number': DOUBLE_EQUALITY_PREDICATE,
        39 'Boolean': DOUBLE_EQUALITY_PREDICATE,
        40 'Date': function(date1, date2) {
        41 return date1.getTime() == date2.getTime();
        42 },
        43 'RegExp': TO_STRING_EQUALITY_PREDICATE,
        44 'Function': TO_STRING_EQUALITY_PREDICATE
        45};
        46
        47
        48/**
        49 * Compares equality of two numbers, allowing them to differ up to a given
        50 * tolerance.
        51 * @param {number} var1 A number.
        52 * @param {number} var2 A number.
        53 * @param {number} tolerance the maximum allowed difference.
        54 * @return {boolean} Whether the two variables are sufficiently close.
        55 * @private
        56 */
        57goog.testing.asserts.numberRoughEqualityPredicate_ = function(
        58 var1, var2, tolerance) {
        59 return Math.abs(var1 - var2) <= tolerance;
        60};
        61
        62
        63/**
        64 * @type {Object.<string, function(*, *, number): boolean>}
        65 * @private
        66 */
        67goog.testing.asserts.primitiveRoughEqualityPredicates_ = {
        68 'Number': goog.testing.asserts.numberRoughEqualityPredicate_
        69};
        70
        71
        72var _trueTypeOf = function(something) {
        73 var result = typeof something;
        74 try {
        75 switch (result) {
        76 case 'string':
        77 break;
        78 case 'boolean':
        79 break;
        80 case 'number':
        81 break;
        82 case 'object':
        83 if (something == null) {
        84 result = 'null';
        85 break;
        86 }
        87 case 'function':
        88 switch (something.constructor) {
        89 case new String('').constructor:
        90 result = 'String';
        91 break;
        92 case new Boolean(true).constructor:
        93 result = 'Boolean';
        94 break;
        95 case new Number(0).constructor:
        96 result = 'Number';
        97 break;
        98 case new Array().constructor:
        99 result = 'Array';
        100 break;
        101 case new RegExp().constructor:
        102 result = 'RegExp';
        103 break;
        104 case new Date().constructor:
        105 result = 'Date';
        106 break;
        107 case Function:
        108 result = 'Function';
        109 break;
        110 default:
        111 var m = something.constructor.toString().match(
        112 /function\s*([^( ]+)\(/);
        113 if (m) {
        114 result = m[1];
        115 } else {
        116 break;
        117 }
        118 }
        119 break;
        120 }
        121 } catch (e) {
        122
        123 } finally {
        124 result = result.substr(0, 1).toUpperCase() + result.substr(1);
        125 }
        126 return result;
        127};
        128
        129var _displayStringForValue = function(aVar) {
        130 var result;
        131 try {
        132 result = '<' + String(aVar) + '>';
        133 } catch (ex) {
        134 result = '<toString failed: ' + ex.message + '>';
        135 // toString does not work on this object :-(
        136 }
        137 if (!(aVar === null || aVar === JSUNIT_UNDEFINED_VALUE)) {
        138 result += ' (' + _trueTypeOf(aVar) + ')';
        139 }
        140 return result;
        141};
        142
        143var fail = function(failureMessage) {
        144 goog.testing.asserts.raiseException('Call to fail()', failureMessage);
        145};
        146
        147var argumentsIncludeComments = function(expectedNumberOfNonCommentArgs, args) {
        148 return args.length == expectedNumberOfNonCommentArgs + 1;
        149};
        150
        151var commentArg = function(expectedNumberOfNonCommentArgs, args) {
        152 if (argumentsIncludeComments(expectedNumberOfNonCommentArgs, args)) {
        153 return args[0];
        154 }
        155
        156 return null;
        157};
        158
        159var nonCommentArg = function(desiredNonCommentArgIndex,
        160 expectedNumberOfNonCommentArgs, args) {
        161 return argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) ?
        162 args[desiredNonCommentArgIndex] :
        163 args[desiredNonCommentArgIndex - 1];
        164};
        165
        166var _validateArguments = function(expectedNumberOfNonCommentArgs, args) {
        167 var valid = args.length == expectedNumberOfNonCommentArgs ||
        168 args.length == expectedNumberOfNonCommentArgs + 1 &&
        169 goog.isString(args[0]);
        170 _assert(null, valid, 'Incorrect arguments passed to assert function');
        171};
        172
        173var _assert = function(comment, booleanValue, failureMessage) {
        174 if (!booleanValue) {
        175 goog.testing.asserts.raiseException(comment, failureMessage);
        176 }
        177};
        178
        179
        180/**
        181 * @param {*} expected The expected value.
        182 * @param {*} actual The actual value.
        183 * @return {string} A failure message of the values don't match.
        184 * @private
        185 */
        186goog.testing.asserts.getDefaultErrorMsg_ = function(expected, actual) {
        187 var msg = 'Expected ' + _displayStringForValue(expected) + ' but was ' +
        188 _displayStringForValue(actual);
        189 if ((typeof expected == 'string') && (typeof actual == 'string')) {
        190 // Try to find a human-readable difference.
        191 var limit = Math.min(expected.length, actual.length);
        192 var commonPrefix = 0;
        193 while (commonPrefix < limit &&
        194 expected.charAt(commonPrefix) == actual.charAt(commonPrefix)) {
        195 commonPrefix++;
        196 }
        197
        198 var commonSuffix = 0;
        199 while (commonSuffix < limit &&
        200 expected.charAt(expected.length - commonSuffix - 1) ==
        201 actual.charAt(actual.length - commonSuffix - 1)) {
        202 commonSuffix++;
        203 }
        204
        205 if (commonPrefix + commonSuffix > limit) {
        206 commonSuffix = 0;
        207 }
        208
        209 if (commonPrefix > 2 || commonSuffix > 2) {
        210 var printString = function(str) {
        211 var startIndex = Math.max(0, commonPrefix - 2);
        212 var endIndex = Math.min(str.length, str.length - (commonSuffix - 2));
        213 return (startIndex > 0 ? '...' : '') +
        214 str.substring(startIndex, endIndex) +
        215 (endIndex < str.length ? '...' : '');
        216 };
        217
        218 msg += '\nDifference was at position ' + commonPrefix +
        219 '. Expected [' + printString(expected) +
        220 '] vs. actual [' + printString(actual) + ']';
        221 }
        222 }
        223 return msg;
        224};
        225
        226
        227/**
        228 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        229 * @param {*=} opt_b The value to assert (2 args only).
        230 */
        231var assert = function(a, opt_b) {
        232 _validateArguments(1, arguments);
        233 var comment = commentArg(1, arguments);
        234 var booleanValue = nonCommentArg(1, 1, arguments);
        235
        236 _assert(comment, goog.isBoolean(booleanValue),
        237 'Bad argument to assert(boolean)');
        238 _assert(comment, booleanValue, 'Call to assert(boolean) with false');
        239};
        240
        241
        242/**
        243 * Asserts that the function throws an error.
        244 *
        245 * @param {!(string|Function)} a The assertion comment or the function to call.
        246 * @param {!Function=} opt_b The function to call (if the first argument of
        247 * {@code assertThrows} was the comment).
        248 * @return {*} The error thrown by the function.
        249 * @throws {goog.testing.JsUnitException} If the assertion failed.
        250 */
        251var assertThrows = function(a, opt_b) {
        252 _validateArguments(1, arguments);
        253 var func = nonCommentArg(1, 1, arguments);
        254 var comment = commentArg(1, arguments);
        255 _assert(comment, typeof func == 'function',
        256 'Argument passed to assertThrows is not a function');
        257
        258 try {
        259 func();
        260 } catch (e) {
        261 if (e && goog.isString(e['stacktrace']) && goog.isString(e['message'])) {
        262 // Remove the stack trace appended to the error message by Opera 10.0
        263 var startIndex = e['message'].length - e['stacktrace'].length;
        264 if (e['message'].indexOf(e['stacktrace'], startIndex) == startIndex) {
        265 e['message'] = e['message'].substr(0, startIndex - 14);
        266 }
        267 }
        268 return e;
        269 }
        270 goog.testing.asserts.raiseException(comment,
        271 'No exception thrown from function passed to assertThrows');
        272};
        273
        274
        275/**
        276 * Asserts that the function does not throw an error.
        277 *
        278 * @param {!(string|Function)} a The assertion comment or the function to call.
        279 * @param {!Function=} opt_b The function to call (if the first argument of
        280 * {@code assertNotThrows} was the comment).
        281 * @return {*} The return value of the function.
        282 * @throws {goog.testing.JsUnitException} If the assertion failed.
        283 */
        284var assertNotThrows = function(a, opt_b) {
        285 _validateArguments(1, arguments);
        286 var comment = commentArg(1, arguments);
        287 var func = nonCommentArg(1, 1, arguments);
        288 _assert(comment, typeof func == 'function',
        289 'Argument passed to assertNotThrows is not a function');
        290
        291 try {
        292 return func();
        293 } catch (e) {
        294 comment = comment ? (comment + '\n') : '';
        295 comment += 'A non expected exception was thrown from function passed to ' +
        296 'assertNotThrows';
        297 // Some browsers don't have a stack trace so at least have the error
        298 // description.
        299 var stackTrace = e['stack'] || e['stacktrace'] || e.toString();
        300 goog.testing.asserts.raiseException(comment, stackTrace);
        301 }
        302};
        303
        304
        305/**
        306 * Asserts that the given callback function results in a JsUnitException when
        307 * called, and that the resulting failure message matches the given expected
        308 * message.
        309 * @param {function() : void} callback Function to be run expected to result
        310 * in a JsUnitException (usually contains a call to an assert).
        311 * @param {string=} opt_expectedMessage Failure message expected to be given
        312 * with the exception.
        313 */
        314var assertThrowsJsUnitException = function(callback, opt_expectedMessage) {
        315 var failed = false;
        316 try {
        317 goog.testing.asserts.callWithoutLogging(callback);
        318 } catch (ex) {
        319 if (!ex.isJsUnitException) {
        320 fail('Expected a JsUnitException');
        321 }
        322 if (typeof opt_expectedMessage != 'undefined' &&
        323 ex.message != opt_expectedMessage) {
        324 fail('Expected message [' + opt_expectedMessage + '] but got [' +
        325 ex.message + ']');
        326 }
        327 failed = true;
        328 }
        329 if (!failed) {
        330 fail('Expected a failure: ' + opt_expectedMessage);
        331 }
        332};
        333
        334
        335/**
        336 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        337 * @param {*=} opt_b The value to assert (2 args only).
        338 */
        339var assertTrue = function(a, opt_b) {
        340 _validateArguments(1, arguments);
        341 var comment = commentArg(1, arguments);
        342 var booleanValue = nonCommentArg(1, 1, arguments);
        343
        344 _assert(comment, goog.isBoolean(booleanValue),
        345 'Bad argument to assertTrue(boolean)');
        346 _assert(comment, booleanValue, 'Call to assertTrue(boolean) with false');
        347};
        348
        349
        350/**
        351 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        352 * @param {*=} opt_b The value to assert (2 args only).
        353 */
        354var assertFalse = function(a, opt_b) {
        355 _validateArguments(1, arguments);
        356 var comment = commentArg(1, arguments);
        357 var booleanValue = nonCommentArg(1, 1, arguments);
        358
        359 _assert(comment, goog.isBoolean(booleanValue),
        360 'Bad argument to assertFalse(boolean)');
        361 _assert(comment, !booleanValue, 'Call to assertFalse(boolean) with true');
        362};
        363
        364
        365/**
        366 * @param {*} a The expected value (2 args) or the debug message (3 args).
        367 * @param {*} b The actual value (2 args) or the expected value (3 args).
        368 * @param {*=} opt_c The actual value (3 args only).
        369 */
        370var assertEquals = function(a, b, opt_c) {
        371 _validateArguments(2, arguments);
        372 var var1 = nonCommentArg(1, 2, arguments);
        373 var var2 = nonCommentArg(2, 2, arguments);
        374 _assert(commentArg(2, arguments), var1 === var2,
        375 goog.testing.asserts.getDefaultErrorMsg_(var1, var2));
        376};
        377
        378
        379/**
        380 * @param {*} a The expected value (2 args) or the debug message (3 args).
        381 * @param {*} b The actual value (2 args) or the expected value (3 args).
        382 * @param {*=} opt_c The actual value (3 args only).
        383 */
        384var assertNotEquals = function(a, b, opt_c) {
        385 _validateArguments(2, arguments);
        386 var var1 = nonCommentArg(1, 2, arguments);
        387 var var2 = nonCommentArg(2, 2, arguments);
        388 _assert(commentArg(2, arguments), var1 !== var2,
        389 'Expected not to be ' + _displayStringForValue(var2));
        390};
        391
        392
        393/**
        394 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        395 * @param {*=} opt_b The value to assert (2 args only).
        396 */
        397var assertNull = function(a, opt_b) {
        398 _validateArguments(1, arguments);
        399 var aVar = nonCommentArg(1, 1, arguments);
        400 _assert(commentArg(1, arguments), aVar === null,
        401 goog.testing.asserts.getDefaultErrorMsg_(null, aVar));
        402};
        403
        404
        405/**
        406 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        407 * @param {*=} opt_b The value to assert (2 args only).
        408 */
        409var assertNotNull = function(a, opt_b) {
        410 _validateArguments(1, arguments);
        411 var aVar = nonCommentArg(1, 1, arguments);
        412 _assert(commentArg(1, arguments), aVar !== null,
        413 'Expected not to be ' + _displayStringForValue(null));
        414};
        415
        416
        417/**
        418 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        419 * @param {*=} opt_b The value to assert (2 args only).
        420 */
        421var assertUndefined = function(a, opt_b) {
        422 _validateArguments(1, arguments);
        423 var aVar = nonCommentArg(1, 1, arguments);
        424 _assert(commentArg(1, arguments), aVar === JSUNIT_UNDEFINED_VALUE,
        425 goog.testing.asserts.getDefaultErrorMsg_(JSUNIT_UNDEFINED_VALUE, aVar));
        426};
        427
        428
        429/**
        430 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        431 * @param {*=} opt_b The value to assert (2 args only).
        432 */
        433var assertNotUndefined = function(a, opt_b) {
        434 _validateArguments(1, arguments);
        435 var aVar = nonCommentArg(1, 1, arguments);
        436 _assert(commentArg(1, arguments), aVar !== JSUNIT_UNDEFINED_VALUE,
        437 'Expected not to be ' + _displayStringForValue(JSUNIT_UNDEFINED_VALUE));
        438};
        439
        440
        441/**
        442 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        443 * @param {*=} opt_b The value to assert (2 args only).
        444 */
        445var assertNotNullNorUndefined = function(a, opt_b) {
        446 _validateArguments(1, arguments);
        447 assertNotNull.apply(null, arguments);
        448 assertNotUndefined.apply(null, arguments);
        449};
        450
        451
        452/**
        453 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        454 * @param {*=} opt_b The value to assert (2 args only).
        455 */
        456var assertNonEmptyString = function(a, opt_b) {
        457 _validateArguments(1, arguments);
        458 var aVar = nonCommentArg(1, 1, arguments);
        459 _assert(commentArg(1, arguments),
        460 aVar !== JSUNIT_UNDEFINED_VALUE && aVar !== null &&
        461 typeof aVar == 'string' && aVar !== '',
        462 'Expected non-empty string but was ' + _displayStringForValue(aVar));
        463};
        464
        465
        466/**
        467 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        468 * @param {*=} opt_b The value to assert (2 args only).
        469 */
        470var assertNaN = function(a, opt_b) {
        471 _validateArguments(1, arguments);
        472 var aVar = nonCommentArg(1, 1, arguments);
        473 _assert(commentArg(1, arguments), isNaN(aVar), 'Expected NaN');
        474};
        475
        476
        477/**
        478 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        479 * @param {*=} opt_b The value to assert (2 args only).
        480 */
        481var assertNotNaN = function(a, opt_b) {
        482 _validateArguments(1, arguments);
        483 var aVar = nonCommentArg(1, 1, arguments);
        484 _assert(commentArg(1, arguments), !isNaN(aVar), 'Expected not NaN');
        485};
        486
        487
        488/**
        489 * Runs a function in an environment where test failures are not logged. This is
        490 * useful for testing test code, where failures can be a normal part of a test.
        491 * @param {function() : void} fn Function to run without logging failures.
        492 */
        493goog.testing.asserts.callWithoutLogging = function(fn) {
        494 var testRunner = goog.global['G_testRunner'];
        495 var oldLogTestFailure = testRunner['logTestFailure'];
        496 try {
        497 // Any failures in the callback shouldn't be recorded.
        498 testRunner['logTestFailure'] = undefined;
        499 fn();
        500 } finally {
        501 testRunner['logTestFailure'] = oldLogTestFailure;
        502 }
        503};
        504
        505
        506/**
        507 * The return value of the equality predicate passed to findDifferences below,
        508 * in cases where the predicate can't test the input variables for equality.
        509 * @type {?string}
        510 */
        511goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS = null;
        512
        513
        514/**
        515 * The return value of the equality predicate passed to findDifferences below,
        516 * in cases where the input vriables are equal.
        517 * @type {?string}
        518 */
        519goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL = '';
        520
        521
        522/**
        523 * Determines if two items of any type match, and formulates an error message
        524 * if not.
        525 * @param {*} expected Expected argument to match.
        526 * @param {*} actual Argument as a result of performing the test.
        527 * @param {(function(string, *, *): ?string)=} opt_equalityPredicate An optional
        528 * function that can be used to check equality of variables. It accepts 3
        529 * arguments: type-of-variables, var1, var2 (in that order) and returns an
        530 * error message if the variables are not equal,
        531 * goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL if the variables
        532 * are equal, or
        533 * goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS if the predicate
        534 * couldn't check the input variables. The function will be called only if
        535 * the types of var1 and var2 are identical.
        536 * @return {?string} Null on success, error message on failure.
        537 */
        538goog.testing.asserts.findDifferences = function(expected, actual,
        539 opt_equalityPredicate) {
        540 var failures = [];
        541 var seen1 = [];
        542 var seen2 = [];
        543
        544 // To avoid infinite recursion when the two parameters are self-referential
        545 // along the same path of properties, keep track of the object pairs already
        546 // seen in this call subtree, and abort when a cycle is detected.
        547 function innerAssert(var1, var2, path) {
        548 // This is used for testing, so we can afford to be slow (but more
        549 // accurate). So we just check whether var1 is in seen1. If we
        550 // found var1 in index i, we simply need to check whether var2 is
        551 // in seen2[i]. If it is, we do not recurse to check var1/var2. If
        552 // it isn't, we know that the structures of the two objects must be
        553 // different.
        554 //
        555 // This is based on the fact that values at index i in seen1 and
        556 // seen2 will be checked for equality eventually (when
        557 // innerAssert_(seen1[i], seen2[i], path) finishes).
        558 for (var i = 0; i < seen1.length; ++i) {
        559 var match1 = seen1[i] === var1;
        560 var match2 = seen2[i] === var2;
        561 if (match1 || match2) {
        562 if (!match1 || !match2) {
        563 // Asymmetric cycles, so the objects have different structure.
        564 failures.push('Asymmetric cycle detected at ' + path);
        565 }
        566 return;
        567 }
        568 }
        569
        570 seen1.push(var1);
        571 seen2.push(var2);
        572 innerAssert_(var1, var2, path);
        573 seen1.pop();
        574 seen2.pop();
        575 }
        576
        577 var equalityPredicate = opt_equalityPredicate || function(type, var1, var2) {
        578 var typedPredicate = PRIMITIVE_EQUALITY_PREDICATES[type];
        579 if (!typedPredicate) {
        580 return goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS;
        581 }
        582 var equal = typedPredicate(var1, var2);
        583 return equal ? goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL :
        584 goog.testing.asserts.getDefaultErrorMsg_(var1, var2);
        585 };
        586
        587 /**
        588 * @param {*} var1 An item in the expected object.
        589 * @param {*} var2 The corresponding item in the actual object.
        590 * @param {string} path Their path in the objects.
        591 * @suppress {missingProperties} The map_ property is unknown to the compiler
        592 * unless goog.structs.Map is loaded.
        593 */
        594 function innerAssert_(var1, var2, path) {
        595 if (var1 === var2) {
        596 return;
        597 }
        598
        599 var typeOfVar1 = _trueTypeOf(var1);
        600 var typeOfVar2 = _trueTypeOf(var2);
        601
        602 if (typeOfVar1 == typeOfVar2) {
        603 var isArray = typeOfVar1 == 'Array';
        604 var errorMessage = equalityPredicate(typeOfVar1, var1, var2);
        605 if (errorMessage !=
        606 goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS) {
        607 if (errorMessage !=
        608 goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL) {
        609 failures.push(path + ': ' + errorMessage);
        610 }
        611 } else if (isArray && var1.length != var2.length) {
        612 failures.push(path + ': Expected ' + var1.length + '-element array ' +
        613 'but got a ' + var2.length + '-element array');
        614 } else {
        615 var childPath = path + (isArray ? '[%s]' : (path ? '.%s' : '%s'));
        616
        617 // if an object has an __iterator__ property, we have no way of
        618 // actually inspecting its raw properties, and JS 1.7 doesn't
        619 // overload [] to make it possible for someone to generically
        620 // use what the iterator returns to compare the object-managed
        621 // properties. This gets us into deep poo with things like
        622 // goog.structs.Map, at least on systems that support iteration.
        623 if (!var1['__iterator__']) {
        624 for (var prop in var1) {
        625 if (isArray && goog.testing.asserts.isArrayIndexProp_(prop)) {
        626 // Skip array indices for now. We'll handle them later.
        627 continue;
        628 }
        629
        630 if (prop in var2) {
        631 innerAssert(var1[prop], var2[prop],
        632 childPath.replace('%s', prop));
        633 } else {
        634 failures.push('property ' + prop +
        635 ' not present in actual ' + (path || typeOfVar2));
        636 }
        637 }
        638 // make sure there aren't properties in var2 that are missing
        639 // from var1. if there are, then by definition they don't
        640 // match.
        641 for (var prop in var2) {
        642 if (isArray && goog.testing.asserts.isArrayIndexProp_(prop)) {
        643 // Skip array indices for now. We'll handle them later.
        644 continue;
        645 }
        646
        647 if (!(prop in var1)) {
        648 failures.push('property ' + prop +
        649 ' not present in expected ' +
        650 (path || typeOfVar1));
        651 }
        652 }
        653
        654 // Handle array indices by iterating from 0 to arr.length.
        655 //
        656 // Although all browsers allow holes in arrays, browsers
        657 // are inconsistent in what they consider a hole. For example,
        658 // "[0,undefined,2]" has a hole on IE but not on Firefox.
        659 //
        660 // Because our style guide bans for...in iteration over arrays,
        661 // we assume that most users don't care about holes in arrays,
        662 // and that it is ok to say that a hole is equivalent to a slot
        663 // populated with 'undefined'.
        664 if (isArray) {
        665 for (prop = 0; prop < var1.length; prop++) {
        666 innerAssert(var1[prop], var2[prop],
        667 childPath.replace('%s', String(prop)));
        668 }
        669 }
        670 } else {
        671 // special-case for closure objects that have iterators
        672 if (goog.isFunction(var1.equals)) {
        673 // use the object's own equals function, assuming it accepts an
        674 // object and returns a boolean
        675 if (!var1.equals(var2)) {
        676 failures.push('equals() returned false for ' +
        677 (path || typeOfVar1));
        678 }
        679 } else if (var1.map_) {
        680 // assume goog.structs.Map or goog.structs.Set, where comparing
        681 // their private map_ field is sufficient
        682 innerAssert(var1.map_, var2.map_, childPath.replace('%s', 'map_'));
        683 } else {
        684 // else die, so user knows we can't do anything
        685 failures.push('unable to check ' + (path || typeOfVar1) +
        686 ' for equality: it has an iterator we do not ' +
        687 'know how to handle. please add an equals method');
        688 }
        689 }
        690 }
        691 } else {
        692 failures.push(path + ' ' +
        693 goog.testing.asserts.getDefaultErrorMsg_(var1, var2));
        694 }
        695 }
        696
        697 innerAssert(expected, actual, '');
        698 return failures.length == 0 ? null :
        699 goog.testing.asserts.getDefaultErrorMsg_(expected, actual) +
        700 '\n ' + failures.join('\n ');
        701};
        702
        703
        704/**
        705 * Notes:
        706 * Object equality has some nasty browser quirks, and this implementation is
        707 * not 100% correct. For example,
        708 *
        709 * <code>
        710 * var a = [0, 1, 2];
        711 * var b = [0, 1, 2];
        712 * delete a[1];
        713 * b[1] = undefined;
        714 * assertObjectEquals(a, b); // should fail, but currently passes
        715 * </code>
        716 *
        717 * See asserts_test.html for more interesting edge cases.
        718 *
        719 * The first comparison object provided is the expected value, the second is
        720 * the actual.
        721 *
        722 * @param {*} a Assertion message or comparison object.
        723 * @param {*} b Comparison object.
        724 * @param {*=} opt_c Comparison object, if an assertion message was provided.
        725 */
        726var assertObjectEquals = function(a, b, opt_c) {
        727 _validateArguments(2, arguments);
        728 var v1 = nonCommentArg(1, 2, arguments);
        729 var v2 = nonCommentArg(2, 2, arguments);
        730 var failureMessage = commentArg(2, arguments) ? commentArg(2, arguments) : '';
        731 var differences = goog.testing.asserts.findDifferences(v1, v2);
        732
        733 _assert(failureMessage, !differences, differences);
        734};
        735
        736
        737/**
        738 * Similar to assertObjectEquals above, but accepts a tolerance margin.
        739 *
        740 * @param {*} a Assertion message or comparison object.
        741 * @param {*} b Comparison object.
        742 * @param {*} c Comparison object or tolerance.
        743 * @param {*=} opt_d Tolerance, if an assertion message was provided.
        744 */
        745var assertObjectRoughlyEquals = function(a, b, c, opt_d) {
        746 _validateArguments(3, arguments);
        747 var v1 = nonCommentArg(1, 3, arguments);
        748 var v2 = nonCommentArg(2, 3, arguments);
        749 var tolerance = nonCommentArg(3, 3, arguments);
        750 var failureMessage = commentArg(3, arguments) ? commentArg(3, arguments) : '';
        751 var equalityPredicate = function(type, var1, var2) {
        752 var typedPredicate =
        753 goog.testing.asserts.primitiveRoughEqualityPredicates_[type];
        754 if (!typedPredicate) {
        755 return goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS;
        756 }
        757 var equal = typedPredicate(var1, var2, tolerance);
        758 return equal ? goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL :
        759 goog.testing.asserts.getDefaultErrorMsg_(var1, var2) +
        760 ' which was more than ' + tolerance + ' away';
        761 };
        762 var differences = goog.testing.asserts.findDifferences(
        763 v1, v2, equalityPredicate);
        764
        765 _assert(failureMessage, !differences, differences);
        766};
        767
        768
        769/**
        770 * Compares two arbitrary objects for non-equalness.
        771 *
        772 * All the same caveats as for assertObjectEquals apply here:
        773 * Undefined values may be confused for missing values, or vice versa.
        774 *
        775 * @param {*} a Assertion message or comparison object.
        776 * @param {*} b Comparison object.
        777 * @param {*=} opt_c Comparison object, if an assertion message was provided.
        778 */
        779var assertObjectNotEquals = function(a, b, opt_c) {
        780 _validateArguments(2, arguments);
        781 var v1 = nonCommentArg(1, 2, arguments);
        782 var v2 = nonCommentArg(2, 2, arguments);
        783 var failureMessage = commentArg(2, arguments) ? commentArg(2, arguments) : '';
        784 var differences = goog.testing.asserts.findDifferences(v1, v2);
        785
        786 _assert(failureMessage, differences, 'Objects should not be equal');
        787};
        788
        789
        790/**
        791 * Compares two arrays ignoring negative indexes and extra properties on the
        792 * array objects. Use case: Internet Explorer adds the index, lastIndex and
        793 * input enumerable fields to the result of string.match(/regexp/g), which makes
        794 * assertObjectEquals fail.
        795 * @param {*} a The expected array (2 args) or the debug message (3 args).
        796 * @param {*} b The actual array (2 args) or the expected array (3 args).
        797 * @param {*=} opt_c The actual array (3 args only).
        798 */
        799var assertArrayEquals = function(a, b, opt_c) {
        800 _validateArguments(2, arguments);
        801 var v1 = nonCommentArg(1, 2, arguments);
        802 var v2 = nonCommentArg(2, 2, arguments);
        803 var failureMessage = commentArg(2, arguments) ? commentArg(2, arguments) : '';
        804
        805 var typeOfVar1 = _trueTypeOf(v1);
        806 _assert(failureMessage,
        807 typeOfVar1 == 'Array',
        808 'Expected an array for assertArrayEquals but found a ' + typeOfVar1);
        809
        810 var typeOfVar2 = _trueTypeOf(v2);
        811 _assert(failureMessage,
        812 typeOfVar2 == 'Array',
        813 'Expected an array for assertArrayEquals but found a ' + typeOfVar2);
        814
        815 assertObjectEquals(failureMessage,
        816 Array.prototype.concat.call(v1), Array.prototype.concat.call(v2));
        817};
        818
        819
        820/**
        821 * Compares two objects that can be accessed like an array and assert that
        822 * each element is equal.
        823 * @param {string|Object} a Failure message (3 arguments)
        824 * or object #1 (2 arguments).
        825 * @param {Object} b Object #1 (2 arguments) or object #2 (3 arguments).
        826 * @param {Object=} opt_c Object #2 (3 arguments).
        827 */
        828var assertElementsEquals = function(a, b, opt_c) {
        829 _validateArguments(2, arguments);
        830
        831 var v1 = nonCommentArg(1, 2, arguments);
        832 var v2 = nonCommentArg(2, 2, arguments);
        833 var failureMessage = commentArg(2, arguments) ? commentArg(2, arguments) : '';
        834
        835 if (!v1) {
        836 assert(failureMessage, !v2);
        837 } else {
        838 assertEquals('length mismatch: ' + failureMessage, v1.length, v2.length);
        839 for (var i = 0; i < v1.length; ++i) {
        840 assertEquals(
        841 'mismatch at index ' + i + ': ' + failureMessage, v1[i], v2[i]);
        842 }
        843 }
        844};
        845
        846
        847/**
        848 * Compares two objects that can be accessed like an array and assert that
        849 * each element is roughly equal.
        850 * @param {string|Object} a Failure message (4 arguments)
        851 * or object #1 (3 arguments).
        852 * @param {Object} b Object #1 (4 arguments) or object #2 (3 arguments).
        853 * @param {Object|number} c Object #2 (4 arguments) or tolerance (3 arguments).
        854 * @param {number=} opt_d tolerance (4 arguments).
        855 */
        856var assertElementsRoughlyEqual = function(a, b, c, opt_d) {
        857 _validateArguments(3, arguments);
        858
        859 var v1 = nonCommentArg(1, 3, arguments);
        860 var v2 = nonCommentArg(2, 3, arguments);
        861 var tolerance = nonCommentArg(3, 3, arguments);
        862 var failureMessage = commentArg(3, arguments) ? commentArg(3, arguments) : '';
        863
        864 if (!v1) {
        865 assert(failureMessage, !v2);
        866 } else {
        867 assertEquals('length mismatch: ' + failureMessage, v1.length, v2.length);
        868 for (var i = 0; i < v1.length; ++i) {
        869 assertRoughlyEquals(failureMessage, v1[i], v2[i], tolerance);
        870 }
        871 }
        872};
        873
        874
        875/**
        876 * Compares two array-like objects without taking their order into account.
        877 * @param {string|goog.testing.asserts.ArrayLike} a Assertion message or the
        878 * expected elements.
        879 * @param {goog.testing.asserts.ArrayLike} b Expected elements or the actual
        880 * elements.
        881 * @param {goog.testing.asserts.ArrayLike=} opt_c Actual elements.
        882 */
        883var assertSameElements = function(a, b, opt_c) {
        884 _validateArguments(2, arguments);
        885 var expected = nonCommentArg(1, 2, arguments);
        886 var actual = nonCommentArg(2, 2, arguments);
        887 var message = commentArg(2, arguments);
        888
        889 assertTrue('Bad arguments to assertSameElements(opt_message, expected: ' +
        890 'ArrayLike, actual: ArrayLike)',
        891 goog.isArrayLike(expected) && goog.isArrayLike(actual));
        892
        893 // Clones expected and actual and converts them to real arrays.
        894 expected = goog.testing.asserts.toArray_(expected);
        895 actual = goog.testing.asserts.toArray_(actual);
        896 // TODO(user): It would be great to show only the difference
        897 // between the expected and actual elements.
        898 _assert(message, expected.length == actual.length,
        899 'Expected ' + expected.length + ' elements: [' + expected + '], ' +
        900 'got ' + actual.length + ' elements: [' + actual + ']');
        901
        902 var toFind = goog.testing.asserts.toArray_(expected);
        903 for (var i = 0; i < actual.length; i++) {
        904 var index = goog.testing.asserts.indexOf_(toFind, actual[i]);
        905 _assert(message, index != -1, 'Expected [' + expected + '], got [' +
        906 actual + ']');
        907 toFind.splice(index, 1);
        908 }
        909};
        910
        911
        912/**
        913 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        914 * @param {*=} opt_b The value to assert (2 args only).
        915 */
        916var assertEvaluatesToTrue = function(a, opt_b) {
        917 _validateArguments(1, arguments);
        918 var value = nonCommentArg(1, 1, arguments);
        919 if (!value) {
        920 _assert(commentArg(1, arguments), false, 'Expected to evaluate to true');
        921 }
        922};
        923
        924
        925/**
        926 * @param {*} a The value to assert (1 arg) or debug message (2 args).
        927 * @param {*=} opt_b The value to assert (2 args only).
        928 */
        929var assertEvaluatesToFalse = function(a, opt_b) {
        930 _validateArguments(1, arguments);
        931 var value = nonCommentArg(1, 1, arguments);
        932 if (value) {
        933 _assert(commentArg(1, arguments), false, 'Expected to evaluate to false');
        934 }
        935};
        936
        937
        938/**
        939 * Compares two HTML snippets.
        940 *
        941 * Take extra care if attributes are involved. {@code assertHTMLEquals}'s
        942 * implementation isn't prepared for complex cases. For example, the following
        943 * comparisons erroneously fail:
        944 * <pre>
        945 * assertHTMLEquals('<a href="x" target="y">', '<a target="y" href="x">');
        946 * assertHTMLEquals('<div classname="a b">', '<div classname="b a">');
        947 * assertHTMLEquals('<input disabled>', '<input disabled="disabled">');
        948 * </pre>
        949 *
        950 * When in doubt, use {@code goog.testing.dom.assertHtmlMatches}.
        951 *
        952 * @param {*} a The expected value (2 args) or the debug message (3 args).
        953 * @param {*} b The actual value (2 args) or the expected value (3 args).
        954 * @param {*=} opt_c The actual value (3 args only).
        955 */
        956var assertHTMLEquals = function(a, b, opt_c) {
        957 _validateArguments(2, arguments);
        958 var var1 = nonCommentArg(1, 2, arguments);
        959 var var2 = nonCommentArg(2, 2, arguments);
        960 var var1Standardized = standardizeHTML(var1);
        961 var var2Standardized = standardizeHTML(var2);
        962
        963 _assert(commentArg(2, arguments), var1Standardized === var2Standardized,
        964 goog.testing.asserts.getDefaultErrorMsg_(
        965 var1Standardized, var2Standardized));
        966};
        967
        968
        969/**
        970 * Compares two CSS property values to make sure that they represent the same
        971 * things. This will normalize values in the browser. For example, in Firefox,
        972 * this assertion will consider "rgb(0, 0, 255)" and "#0000ff" to be identical
        973 * values for the "color" property. This function won't normalize everything --
        974 * for example, in most browsers, "blue" will not match "#0000ff". It is
        975 * intended only to compensate for unexpected normalizations performed by
        976 * the browser that should also affect your expected value.
        977 * @param {string} a Assertion message, or the CSS property name.
        978 * @param {string} b CSS property name, or the expected value.
        979 * @param {string} c The expected value, or the actual value.
        980 * @param {string=} opt_d The actual value.
        981 */
        982var assertCSSValueEquals = function(a, b, c, opt_d) {
        983 _validateArguments(3, arguments);
        984 var propertyName = nonCommentArg(1, 3, arguments);
        985 var expectedValue = nonCommentArg(2, 3, arguments);
        986 var actualValue = nonCommentArg(3, 3, arguments);
        987 var expectedValueStandardized =
        988 standardizeCSSValue(propertyName, expectedValue);
        989 var actualValueStandardized =
        990 standardizeCSSValue(propertyName, actualValue);
        991
        992 _assert(commentArg(3, arguments),
        993 expectedValueStandardized == actualValueStandardized,
        994 goog.testing.asserts.getDefaultErrorMsg_(
        995 expectedValueStandardized, actualValueStandardized));
        996};
        997
        998
        999/**
        1000 * @param {*} a The expected value (2 args) or the debug message (3 args).
        1001 * @param {*} b The actual value (2 args) or the expected value (3 args).
        1002 * @param {*=} opt_c The actual value (3 args only).
        1003 */
        1004var assertHashEquals = function(a, b, opt_c) {
        1005 _validateArguments(2, arguments);
        1006 var var1 = nonCommentArg(1, 2, arguments);
        1007 var var2 = nonCommentArg(2, 2, arguments);
        1008 var message = commentArg(2, arguments);
        1009 for (var key in var1) {
        1010 _assert(message,
        1011 key in var2, 'Expected hash had key ' + key + ' that was not found');
        1012 _assert(message, var1[key] == var2[key], 'Value for key ' + key +
        1013 ' mismatch - expected = ' + var1[key] + ', actual = ' + var2[key]);
        1014 }
        1015
        1016 for (var key in var2) {
        1017 _assert(message, key in var1, 'Actual hash had key ' + key +
        1018 ' that was not expected');
        1019 }
        1020};
        1021
        1022
        1023/**
        1024 * @param {*} a The expected value (3 args) or the debug message (4 args).
        1025 * @param {*} b The actual value (3 args) or the expected value (4 args).
        1026 * @param {*} c The tolerance (3 args) or the actual value (4 args).
        1027 * @param {*=} opt_d The tolerance (4 args only).
        1028 */
        1029var assertRoughlyEquals = function(a, b, c, opt_d) {
        1030 _validateArguments(3, arguments);
        1031 var expected = nonCommentArg(1, 3, arguments);
        1032 var actual = nonCommentArg(2, 3, arguments);
        1033 var tolerance = nonCommentArg(3, 3, arguments);
        1034 _assert(commentArg(3, arguments),
        1035 goog.testing.asserts.numberRoughEqualityPredicate_(
        1036 expected, actual, tolerance),
        1037 'Expected ' + expected + ', but got ' + actual +
        1038 ' which was more than ' + tolerance + ' away');
        1039};
        1040
        1041
        1042/**
        1043 * Checks if the given element is the member of the given container.
        1044 * @param {*} a Failure message (3 arguments) or the contained element
        1045 * (2 arguments).
        1046 * @param {*} b The contained element (3 arguments) or the container
        1047 * (2 arguments).
        1048 * @param {*=} opt_c The container.
        1049 */
        1050var assertContains = function(a, b, opt_c) {
        1051 _validateArguments(2, arguments);
        1052 var contained = nonCommentArg(1, 2, arguments);
        1053 var container = nonCommentArg(2, 2, arguments);
        1054 _assert(commentArg(2, arguments),
        1055 goog.testing.asserts.contains_(container, contained),
        1056 'Expected \'' + container + '\' to contain \'' + contained + '\'');
        1057};
        1058
        1059
        1060/**
        1061 * Checks if the given element is not the member of the given container.
        1062 * @param {*} a Failure message (3 arguments) or the contained element
        1063 * (2 arguments).
        1064 * @param {*} b The contained element (3 arguments) or the container
        1065 * (2 arguments).
        1066 * @param {*=} opt_c The container.
        1067 */
        1068var assertNotContains = function(a, b, opt_c) {
        1069 _validateArguments(2, arguments);
        1070 var contained = nonCommentArg(1, 2, arguments);
        1071 var container = nonCommentArg(2, 2, arguments);
        1072 _assert(commentArg(2, arguments),
        1073 !goog.testing.asserts.contains_(container, contained),
        1074 'Expected \'' + container + '\' not to contain \'' + contained + '\'');
        1075};
        1076
        1077
        1078/**
        1079 * Checks if the given string matches the given regular expression.
        1080 * @param {*} a Failure message (3 arguments) or the expected regular
        1081 * expression as a string or RegExp (2 arguments).
        1082 * @param {*} b The regular expression (3 arguments) or the string to test
        1083 * (2 arguments).
        1084 * @param {*=} opt_c The string to test.
        1085 */
        1086var assertRegExp = function(a, b, opt_c) {
        1087 _validateArguments(2, arguments);
        1088 var regexp = nonCommentArg(1, 2, arguments);
        1089 var string = nonCommentArg(2, 2, arguments);
        1090 if (typeof(regexp) == 'string') {
        1091 regexp = new RegExp(regexp);
        1092 }
        1093 _assert(commentArg(2, arguments),
        1094 regexp.test(string),
        1095 'Expected \'' + string + '\' to match RegExp ' + regexp.toString());
        1096};
        1097
        1098
        1099/**
        1100 * Converts an array like object to array or clones it if it's already array.
        1101 * @param {goog.testing.asserts.ArrayLike} arrayLike The collection.
        1102 * @return {!Array} Copy of the collection as array.
        1103 * @private
        1104 */
        1105goog.testing.asserts.toArray_ = function(arrayLike) {
        1106 var ret = [];
        1107 for (var i = 0; i < arrayLike.length; i++) {
        1108 ret[i] = arrayLike[i];
        1109 }
        1110 return ret;
        1111};
        1112
        1113
        1114/**
        1115 * Finds the position of the first occurrence of an element in a container.
        1116 * @param {goog.testing.asserts.ArrayLike} container
        1117 * The array to find the element in.
        1118 * @param {*} contained Element to find.
        1119 * @return {number} Index of the first occurrence or -1 if not found.
        1120 * @private
        1121 */
        1122goog.testing.asserts.indexOf_ = function(container, contained) {
        1123 if (container.indexOf) {
        1124 return container.indexOf(contained);
        1125 } else {
        1126 // IE6/7 do not have indexOf so do a search.
        1127 for (var i = 0; i < container.length; i++) {
        1128 if (container[i] === contained) {
        1129 return i;
        1130 }
        1131 }
        1132 return -1;
        1133 }
        1134};
        1135
        1136
        1137/**
        1138 * Tells whether the array contains the given element.
        1139 * @param {goog.testing.asserts.ArrayLike} container The array to
        1140 * find the element in.
        1141 * @param {*} contained Element to find.
        1142 * @return {boolean} Whether the element is in the array.
        1143 * @private
        1144 */
        1145goog.testing.asserts.contains_ = function(container, contained) {
        1146 // TODO(user): Can we check for container.contains as well?
        1147 // That would give us support for most goog.structs (though weird results
        1148 // with anything else with a contains method, like goog.math.Range). Falling
        1149 // back with container.some would catch all iterables, too.
        1150 return goog.testing.asserts.indexOf_(container, contained) != -1;
        1151};
        1152
        1153var standardizeHTML = function(html) {
        1154 var translator = document.createElement('DIV');
        1155 translator.innerHTML = html;
        1156
        1157 // Trim whitespace from result (without relying on goog.string)
        1158 return translator.innerHTML.replace(/^\s+|\s+$/g, '');
        1159};
        1160
        1161
        1162/**
        1163 * Standardizes a CSS value for a given property by applying it to an element
        1164 * and then reading it back.
        1165 * @param {string} propertyName CSS property name.
        1166 * @param {string} value CSS value.
        1167 * @return {string} Normalized CSS value.
        1168 */
        1169var standardizeCSSValue = function(propertyName, value) {
        1170 var styleDeclaration = document.createElement('DIV').style;
        1171 styleDeclaration[propertyName] = value;
        1172 return styleDeclaration[propertyName];
        1173};
        1174
        1175
        1176/**
        1177 * Raises a JsUnit exception with the given comment.
        1178 * @param {string} comment A summary for the exception.
        1179 * @param {string=} opt_message A description of the exception.
        1180 */
        1181goog.testing.asserts.raiseException = function(comment, opt_message) {
        1182 throw new goog.testing.JsUnitException(comment, opt_message);
        1183};
        1184
        1185
        1186/**
        1187 * Helper function for assertObjectEquals.
        1188 * @param {string} prop A property name.
        1189 * @return {boolean} If the property name is an array index.
        1190 * @private
        1191 */
        1192goog.testing.asserts.isArrayIndexProp_ = function(prop) {
        1193 return (prop | 0) == prop;
        1194};
        1195
        1196
        1197
        1198/**
        1199 * @param {string} comment A summary for the exception.
        1200 * @param {?string=} opt_message A description of the exception.
        1201 * @constructor
        1202 * @extends {Error}
        1203 * @final
        1204 */
        1205goog.testing.JsUnitException = function(comment, opt_message) {
        1206 this.isJsUnitException = true;
        1207 this.message = (comment ? comment : '') +
        1208 (comment && opt_message ? '\n' : '') +
        1209 (opt_message ? opt_message : '');
        1210 this.stackTrace = goog.testing.stacktrace.get();
        1211 // These fields are for compatibility with jsUnitTestManager.
        1212 this.comment = comment || null;
        1213 this.jsUnitMessage = opt_message || '';
        1214
        1215 // Ensure there is a stack trace.
        1216 if (Error.captureStackTrace) {
        1217 Error.captureStackTrace(this, goog.testing.JsUnitException);
        1218 } else {
        1219 this.stack = new Error().stack || '';
        1220 }
        1221};
        1222goog.inherits(goog.testing.JsUnitException, Error);
        1223
        1224
        1225/** @override */
        1226goog.testing.JsUnitException.prototype.toString = function() {
        1227 return this.message;
        1228};
        1229
        1230
        1231goog.exportSymbol('fail', fail);
        1232goog.exportSymbol('assert', assert);
        1233goog.exportSymbol('assertThrows', assertThrows);
        1234goog.exportSymbol('assertNotThrows', assertNotThrows);
        1235goog.exportSymbol('assertTrue', assertTrue);
        1236goog.exportSymbol('assertFalse', assertFalse);
        1237goog.exportSymbol('assertEquals', assertEquals);
        1238goog.exportSymbol('assertNotEquals', assertNotEquals);
        1239goog.exportSymbol('assertNull', assertNull);
        1240goog.exportSymbol('assertNotNull', assertNotNull);
        1241goog.exportSymbol('assertUndefined', assertUndefined);
        1242goog.exportSymbol('assertNotUndefined', assertNotUndefined);
        1243goog.exportSymbol('assertNotNullNorUndefined', assertNotNullNorUndefined);
        1244goog.exportSymbol('assertNonEmptyString', assertNonEmptyString);
        1245goog.exportSymbol('assertNaN', assertNaN);
        1246goog.exportSymbol('assertNotNaN', assertNotNaN);
        1247goog.exportSymbol('assertObjectEquals', assertObjectEquals);
        1248goog.exportSymbol('assertObjectRoughlyEquals', assertObjectRoughlyEquals);
        1249goog.exportSymbol('assertObjectNotEquals', assertObjectNotEquals);
        1250goog.exportSymbol('assertArrayEquals', assertArrayEquals);
        1251goog.exportSymbol('assertElementsEquals', assertElementsEquals);
        1252goog.exportSymbol('assertElementsRoughlyEqual', assertElementsRoughlyEqual);
        1253goog.exportSymbol('assertSameElements', assertSameElements);
        1254goog.exportSymbol('assertEvaluatesToTrue', assertEvaluatesToTrue);
        1255goog.exportSymbol('assertEvaluatesToFalse', assertEvaluatesToFalse);
        1256goog.exportSymbol('assertHTMLEquals', assertHTMLEquals);
        1257goog.exportSymbol('assertHashEquals', assertHashEquals);
        1258goog.exportSymbol('assertRoughlyEquals', assertRoughlyEquals);
        1259goog.exportSymbol('assertContains', assertContains);
        1260goog.exportSymbol('assertNotContains', assertNotContains);
        1261goog.exportSymbol('assertRegExp', assertRegExp);
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/asynctestcase.js.src.html b/docs/api/javascript/source/lib/goog/testing/asynctestcase.js.src.html new file mode 100644 index 0000000000000..0c164e4c7bbd3 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/asynctestcase.js.src.html @@ -0,0 +1 @@ +asynctestcase.js

        lib/goog/testing/asynctestcase.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// All Rights Reserved.
        15
        16/**
        17 * @fileoverview A class representing a set of test functions that use
        18 * asynchronous functions that cannot be meaningfully mocked.
        19 *
        20 * To create a Google-compatable JsUnit test using this test case, put the
        21 * following snippet in your test:
        22 *
        23 * var asyncTestCase = goog.testing.AsyncTestCase.createAndInstall();
        24 *
        25 * To make the test runner wait for your asynchronous behaviour, use:
        26 *
        27 * asyncTestCase.waitForAsync('Waiting for xhr to respond');
        28 *
        29 * The next test will not start until the following call is made, or a
        30 * timeout occurs:
        31 *
        32 * asyncTestCase.continueTesting();
        33 *
        34 * There does NOT need to be a 1:1 mapping of waitForAsync calls and
        35 * continueTesting calls. The next test will be run after a single call to
        36 * continueTesting is made, as long as there is no subsequent call to
        37 * waitForAsync in the same thread.
        38 *
        39 * Example:
        40 * // Returning here would cause the next test to be run.
        41 * asyncTestCase.waitForAsync('description 1');
        42 * // Returning here would *not* cause the next test to be run.
        43 * // Only effect of additional waitForAsync() calls is an updated
        44 * // description in the case of a timeout.
        45 * asyncTestCase.waitForAsync('updated description');
        46 * asyncTestCase.continueTesting();
        47 * // Returning here would cause the next test to be run.
        48 * asyncTestCase.waitForAsync('just kidding, still running.');
        49 * // Returning here would *not* cause the next test to be run.
        50 *
        51 * The test runner can also be made to wait for more than one asynchronous
        52 * event with:
        53 *
        54 * asyncTestCase.waitForSignals(n);
        55 *
        56 * The next test will not start until asyncTestCase.signal() is called n times,
        57 * or the test step timeout is exceeded.
        58 *
        59 * This class supports asynchronous behaviour in all test functions except for
        60 * tearDownPage. If such support is needed, it can be added.
        61 *
        62 * Example Usage:
        63 *
        64 * var asyncTestCase = goog.testing.AsyncTestCase.createAndInstall();
        65 * // Optionally, set a longer-than-normal step timeout.
        66 * asyncTestCase.stepTimeout = 30 * 1000;
        67 *
        68 * function testSetTimeout() {
        69 * var step = 0;
        70 * function stepCallback() {
        71 * step++;
        72 * switch (step) {
        73 * case 1:
        74 * var startTime = goog.now();
        75 * asyncTestCase.waitForAsync('step 1');
        76 * window.setTimeout(stepCallback, 100);
        77 * break;
        78 * case 2:
        79 * assertTrue('Timeout fired too soon',
        80 * goog.now() - startTime >= 100);
        81 * asyncTestCase.waitForAsync('step 2');
        82 * window.setTimeout(stepCallback, 100);
        83 * break;
        84 * case 3:
        85 * assertTrue('Timeout fired too soon',
        86 * goog.now() - startTime >= 200);
        87 * asyncTestCase.continueTesting();
        88 * break;
        89 * default:
        90 * fail('Unexpected call to stepCallback');
        91 * }
        92 * }
        93 * stepCallback();
        94 * }
        95 *
        96 * Known Issues:
        97 * IE7 Exceptions:
        98 * As the failingtest.html will show, it appears as though ie7 does not
        99 * propagate an exception past a function called using the func.call()
        100 * syntax. This causes case 3 of the failing tests (exceptions) to show up
        101 * as timeouts in IE.
        102 * window.onerror:
        103 * This seems to catch errors only in ff2/ff3. It does not work in Safari or
        104 * IE7. The consequence of this is that exceptions that would have been
        105 * caught by window.onerror show up as timeouts.
        106 *
        107 * @author agrieve@google.com (Andrew Grieve)
        108 */
        109
        110goog.provide('goog.testing.AsyncTestCase');
        111goog.provide('goog.testing.AsyncTestCase.ControlBreakingException');
        112
        113goog.require('goog.testing.TestCase');
        114goog.require('goog.testing.TestCase.Test');
        115goog.require('goog.testing.asserts');
        116
        117
        118
        119/**
        120 * A test case that is capable of running tests the contain asynchronous logic.
        121 * @param {string=} opt_name A descriptive name for the test case.
        122 * @extends {goog.testing.TestCase}
        123 * @constructor
        124 */
        125goog.testing.AsyncTestCase = function(opt_name) {
        126 goog.testing.TestCase.call(this, opt_name);
        127};
        128goog.inherits(goog.testing.AsyncTestCase, goog.testing.TestCase);
        129
        130
        131/**
        132 * Represents result of top stack function call.
        133 * @typedef {{controlBreakingExceptionThrown: boolean, message: string}}
        134 * @private
        135 */
        136goog.testing.AsyncTestCase.TopStackFuncResult_;
        137
        138
        139
        140/**
        141 * An exception class used solely for control flow.
        142 * @param {string=} opt_message Error message.
        143 * @constructor
        144 * @final
        145 */
        146goog.testing.AsyncTestCase.ControlBreakingException = function(opt_message) {
        147 /**
        148 * The exception message.
        149 * @type {string}
        150 */
        151 this.message = opt_message || '';
        152};
        153
        154
        155/**
        156 * Return value for .toString().
        157 * @type {string}
        158 */
        159goog.testing.AsyncTestCase.ControlBreakingException.TO_STRING =
        160 '[AsyncTestCase.ControlBreakingException]';
        161
        162
        163/**
        164 * Marks this object as a ControlBreakingException
        165 * @type {boolean}
        166 */
        167goog.testing.AsyncTestCase.ControlBreakingException.prototype.
        168 isControlBreakingException = true;
        169
        170
        171/** @override */
        172goog.testing.AsyncTestCase.ControlBreakingException.prototype.toString =
        173 function() {
        174 // This shows up in the console when the exception is not caught.
        175 return goog.testing.AsyncTestCase.ControlBreakingException.TO_STRING;
        176};
        177
        178
        179/**
        180 * How long to wait for a single step of a test to complete in milliseconds.
        181 * A step starts when a call to waitForAsync() is made.
        182 * @type {number}
        183 */
        184goog.testing.AsyncTestCase.prototype.stepTimeout = 1000;
        185
        186
        187/**
        188 * How long to wait after a failed test before moving onto the next one.
        189 * The purpose of this is to allow any pending async callbacks from the failing
        190 * test to finish up and not cause the next test to fail.
        191 * @type {number}
        192 */
        193goog.testing.AsyncTestCase.prototype.timeToSleepAfterFailure = 500;
        194
        195
        196/**
        197 * Turn on extra logging to help debug failing async. tests.
        198 * @type {boolean}
        199 * @private
        200 */
        201goog.testing.AsyncTestCase.prototype.enableDebugLogs_ = false;
        202
        203
        204/**
        205 * A reference to the original asserts.js assert_() function.
        206 * @private
        207 */
        208goog.testing.AsyncTestCase.prototype.origAssert_;
        209
        210
        211/**
        212 * A reference to the original asserts.js fail() function.
        213 * @private
        214 */
        215goog.testing.AsyncTestCase.prototype.origFail_;
        216
        217
        218/**
        219 * A reference to the original window.onerror function.
        220 * @type {Function|undefined}
        221 * @private
        222 */
        223goog.testing.AsyncTestCase.prototype.origOnError_;
        224
        225
        226/**
        227 * The stage of the test we are currently on.
        228 * @type {Function|undefined}}
        229 * @private
        230 */
        231goog.testing.AsyncTestCase.prototype.curStepFunc_;
        232
        233
        234/**
        235 * The name of the stage of the test we are currently on.
        236 * @type {string}
        237 * @private
        238 */
        239goog.testing.AsyncTestCase.prototype.curStepName_ = '';
        240
        241
        242/**
        243 * The stage of the test we should run next.
        244 * @type {Function|undefined}
        245 * @private
        246 */
        247goog.testing.AsyncTestCase.prototype.nextStepFunc;
        248
        249
        250/**
        251 * The name of the stage of the test we should run next.
        252 * @type {string}
        253 * @private
        254 */
        255goog.testing.AsyncTestCase.prototype.nextStepName_ = '';
        256
        257
        258/**
        259 * The handle to the current setTimeout timer.
        260 * @type {number}
        261 * @private
        262 */
        263goog.testing.AsyncTestCase.prototype.timeoutHandle_ = 0;
        264
        265
        266/**
        267 * Marks if the cleanUp() function has been called for the currently running
        268 * test.
        269 * @type {boolean}
        270 * @private
        271 */
        272goog.testing.AsyncTestCase.prototype.cleanedUp_ = false;
        273
        274
        275/**
        276 * The currently active test.
        277 * @type {goog.testing.TestCase.Test|undefined}
        278 * @protected
        279 */
        280goog.testing.AsyncTestCase.prototype.activeTest;
        281
        282
        283/**
        284 * A flag to prevent recursive exception handling.
        285 * @type {boolean}
        286 * @private
        287 */
        288goog.testing.AsyncTestCase.prototype.inException_ = false;
        289
        290
        291/**
        292 * Flag used to determine if we can move to the next step in the testing loop.
        293 * @type {boolean}
        294 * @private
        295 */
        296goog.testing.AsyncTestCase.prototype.isReady_ = true;
        297
        298
        299/**
        300 * Number of signals to wait for before continuing testing when waitForSignals
        301 * is used.
        302 * @type {number}
        303 * @private
        304 */
        305goog.testing.AsyncTestCase.prototype.expectedSignalCount_ = 0;
        306
        307
        308/**
        309 * Number of signals received.
        310 * @type {number}
        311 * @private
        312 */
        313goog.testing.AsyncTestCase.prototype.receivedSignalCount_ = 0;
        314
        315
        316/**
        317 * Flag that tells us if there is a function in the call stack that will make
        318 * a call to pump_().
        319 * @type {boolean}
        320 * @private
        321 */
        322goog.testing.AsyncTestCase.prototype.returnWillPump_ = false;
        323
        324
        325/**
        326 * The number of times we have thrown a ControlBreakingException so that we
        327 * know not to complain in our window.onerror handler. In Webkit, window.onerror
        328 * is not supported, and so this counter will keep going up but we won't care
        329 * about it.
        330 * @type {number}
        331 * @private
        332 */
        333goog.testing.AsyncTestCase.prototype.numControlExceptionsExpected_ = 0;
        334
        335
        336/**
        337 * The current step name.
        338 * @return {!string} Step name.
        339 * @protected
        340 */
        341goog.testing.AsyncTestCase.prototype.getCurrentStepName = function() {
        342 return this.curStepName_;
        343};
        344
        345
        346/**
        347 * Preferred way of creating an AsyncTestCase. Creates one and initializes it
        348 * with the G_testRunner.
        349 * @param {string=} opt_name A descriptive name for the test case.
        350 * @return {!goog.testing.AsyncTestCase} The created AsyncTestCase.
        351 */
        352goog.testing.AsyncTestCase.createAndInstall = function(opt_name) {
        353 var asyncTestCase = new goog.testing.AsyncTestCase(opt_name);
        354 goog.testing.TestCase.initializeTestRunner(asyncTestCase);
        355 return asyncTestCase;
        356};
        357
        358
        359/**
        360 * Informs the testcase not to continue to the next step in the test cycle
        361 * until continueTesting is called.
        362 * @param {string=} opt_name A description of what we are waiting for.
        363 */
        364goog.testing.AsyncTestCase.prototype.waitForAsync = function(opt_name) {
        365 this.isReady_ = false;
        366 this.curStepName_ = opt_name || this.curStepName_;
        367
        368 // Reset the timer that tracks if the async test takes too long.
        369 this.stopTimeoutTimer_();
        370 this.startTimeoutTimer_();
        371};
        372
        373
        374/**
        375 * Continue with the next step in the test cycle.
        376 */
        377goog.testing.AsyncTestCase.prototype.continueTesting = function() {
        378 if (this.receivedSignalCount_ < this.expectedSignalCount_) {
        379 var remaining = this.expectedSignalCount_ - this.receivedSignalCount_;
        380 throw Error('Still waiting for ' + remaining + ' signals.');
        381 }
        382 this.endCurrentStep_();
        383};
        384
        385
        386/**
        387 * Ends the current test step and queues the next test step to run.
        388 * @private
        389 */
        390goog.testing.AsyncTestCase.prototype.endCurrentStep_ = function() {
        391 if (!this.isReady_) {
        392 // We are a potential entry point, so we pump.
        393 this.isReady_ = true;
        394 this.stopTimeoutTimer_();
        395 // Run this in a setTimeout so that the caller has a chance to call
        396 // waitForAsync() again before we continue.
        397 this.timeout(goog.bind(this.pump_, this, null), 0);
        398 }
        399};
        400
        401
        402/**
        403 * Informs the testcase not to continue to the next step in the test cycle
        404 * until signal is called the specified number of times. Within a test, this
        405 * function behaves additively if called multiple times; the number of signals
        406 * to wait for will be the sum of all expected number of signals this function
        407 * was called with.
        408 * @param {number} times The number of signals to receive before
        409 * continuing testing.
        410 * @param {string=} opt_name A description of what we are waiting for.
        411 */
        412goog.testing.AsyncTestCase.prototype.waitForSignals =
        413 function(times, opt_name) {
        414 this.expectedSignalCount_ += times;
        415 if (this.receivedSignalCount_ < this.expectedSignalCount_) {
        416 this.waitForAsync(opt_name);
        417 }
        418};
        419
        420
        421/**
        422 * Signals once to continue with the test. If this is the last signal that the
        423 * test was waiting on, call continueTesting.
        424 */
        425goog.testing.AsyncTestCase.prototype.signal = function() {
        426 if (++this.receivedSignalCount_ === this.expectedSignalCount_ &&
        427 this.expectedSignalCount_ > 0) {
        428 this.endCurrentStep_();
        429 }
        430};
        431
        432
        433/**
        434 * Handles an exception thrown by a test.
        435 * @param {*=} opt_e The exception object associated with the failure
        436 * or a string.
        437 * @throws Always throws a ControlBreakingException.
        438 */
        439goog.testing.AsyncTestCase.prototype.doAsyncError = function(opt_e) {
        440 // If we've caught an exception that we threw, then just pass it along. This
        441 // can happen if doAsyncError() was called from a call to assert and then
        442 // again by pump_().
        443 if (opt_e && opt_e.isControlBreakingException) {
        444 throw opt_e;
        445 }
        446
        447 // Prevent another timeout error from triggering for this test step.
        448 this.stopTimeoutTimer_();
        449
        450 // doError() uses test.name. Here, we create a dummy test and give it a more
        451 // helpful name based on the step we're currently on.
        452 var fakeTestObj = new goog.testing.TestCase.Test(this.curStepName_,
        453 goog.nullFunction);
        454 if (this.activeTest) {
        455 fakeTestObj.name = this.activeTest.name + ' [' + fakeTestObj.name + ']';
        456 }
        457
        458 if (this.activeTest) {
        459 // Note: if the test has an error, and then tearDown has an error, they will
        460 // both be reported.
        461 this.doError(fakeTestObj, opt_e);
        462 } else {
        463 this.exceptionBeforeTest = opt_e;
        464 }
        465
        466 // This is a potential entry point, so we pump. We also add in a bit of a
        467 // delay to try and prevent any async behavior from the failed test from
        468 // causing the next test to fail.
        469 this.timeout(goog.bind(this.pump_, this, this.doAsyncErrorTearDown_),
        470 this.timeToSleepAfterFailure);
        471
        472 // We just caught an exception, so we do not want the code above us on the
        473 // stack to continue executing. If pump_ is in our call-stack, then it will
        474 // batch together multiple errors, so we only increment the count if pump_ is
        475 // not in the stack and let pump_ increment the count when it batches them.
        476 if (!this.returnWillPump_) {
        477 this.numControlExceptionsExpected_ += 1;
        478 this.dbgLog_('doAsynError: numControlExceptionsExpected_ = ' +
        479 this.numControlExceptionsExpected_ + ' and throwing exception.');
        480 }
        481
        482 // Copy the error message to ControlBreakingException.
        483 var message = '';
        484 if (typeof opt_e == 'string') {
        485 message = opt_e;
        486 } else if (opt_e && opt_e.message) {
        487 message = opt_e.message;
        488 }
        489 throw new goog.testing.AsyncTestCase.ControlBreakingException(message);
        490};
        491
        492
        493/**
        494 * Sets up the test page and then waits until the test case has been marked
        495 * as ready before executing the tests.
        496 * @override
        497 */
        498goog.testing.AsyncTestCase.prototype.runTests = function() {
        499 this.hookAssert_();
        500 this.hookOnError_();
        501
        502 this.setNextStep_(this.doSetUpPage_, 'setUpPage');
        503 // We are an entry point, so we pump.
        504 this.pump_();
        505};
        506
        507
        508/**
        509 * Starts the tests.
        510 * @override
        511 */
        512goog.testing.AsyncTestCase.prototype.cycleTests = function() {
        513 // We are an entry point, so we pump.
        514 this.saveMessage('Start');
        515 this.setNextStep_(this.doIteration_, 'doIteration');
        516 this.pump_();
        517};
        518
        519
        520/**
        521 * Finalizes the test case, called when the tests have finished executing.
        522 * @override
        523 */
        524goog.testing.AsyncTestCase.prototype.finalize = function() {
        525 this.unhookAll_();
        526 this.setNextStep_(null, 'finalized');
        527 goog.testing.AsyncTestCase.superClass_.finalize.call(this);
        528};
        529
        530
        531/**
        532 * Enables verbose logging of what is happening inside of the AsyncTestCase.
        533 */
        534goog.testing.AsyncTestCase.prototype.enableDebugLogging = function() {
        535 this.enableDebugLogs_ = true;
        536};
        537
        538
        539/**
        540 * Logs the given debug message to the console (when enabled).
        541 * @param {string} message The message to log.
        542 * @private
        543 */
        544goog.testing.AsyncTestCase.prototype.dbgLog_ = function(message) {
        545 if (this.enableDebugLogs_) {
        546 this.log('AsyncTestCase - ' + message);
        547 }
        548};
        549
        550
        551/**
        552 * Wraps doAsyncError() for when we are sure that the test runner has no user
        553 * code above it in the stack.
        554 * @param {string|Error=} opt_e The exception object associated with the
        555 * failure or a string.
        556 * @private
        557 */
        558goog.testing.AsyncTestCase.prototype.doTopOfStackAsyncError_ =
        559 function(opt_e) {
        560 /** @preserveTry */
        561 try {
        562 this.doAsyncError(opt_e);
        563 } catch (e) {
        564 // We know that we are on the top of the stack, so there is no need to
        565 // throw this exception in this case.
        566 if (e.isControlBreakingException) {
        567 this.numControlExceptionsExpected_ -= 1;
        568 this.dbgLog_('doTopOfStackAsyncError_: numControlExceptionsExpected_ = ' +
        569 this.numControlExceptionsExpected_ + ' and catching exception.');
        570 } else {
        571 throw e;
        572 }
        573 }
        574};
        575
        576
        577/**
        578 * Calls the tearDown function, catching any errors, and then moves on to
        579 * the next step in the testing cycle.
        580 * @private
        581 */
        582goog.testing.AsyncTestCase.prototype.doAsyncErrorTearDown_ = function() {
        583 if (this.inException_) {
        584 // We get here if tearDown is throwing the error.
        585 // Upon calling continueTesting, the inline function 'doAsyncError' (set
        586 // below) is run.
        587 this.endCurrentStep_();
        588 } else {
        589 this.inException_ = true;
        590 this.isReady_ = true;
        591
        592 // The continue point is different depending on if the error happened in
        593 // setUpPage() or in setUp()/test*()/tearDown().
        594 var stepFuncAfterError = this.nextStepFunc_;
        595 var stepNameAfterError = 'TestCase.execute (after error)';
        596 if (this.activeTest) {
        597 stepFuncAfterError = this.doIteration_;
        598 stepNameAfterError = 'doIteration (after error)';
        599 }
        600
        601 // We must set the next step before calling tearDown.
        602 this.setNextStep_(function() {
        603 this.inException_ = false;
        604 // This is null when an error happens in setUpPage.
        605 this.setNextStep_(stepFuncAfterError, stepNameAfterError);
        606 }, 'doAsyncError');
        607
        608 // Call the test's tearDown().
        609 if (!this.cleanedUp_) {
        610 this.cleanedUp_ = true;
        611 this.tearDown();
        612 }
        613 }
        614};
        615
        616
        617/**
        618 * Replaces the asserts.js assert_() and fail() functions with a wrappers to
        619 * catch the exceptions.
        620 * @private
        621 */
        622goog.testing.AsyncTestCase.prototype.hookAssert_ = function() {
        623 if (!this.origAssert_) {
        624 this.origAssert_ = _assert;
        625 this.origFail_ = fail;
        626 var self = this;
        627 _assert = function() {
        628 /** @preserveTry */
        629 try {
        630 self.origAssert_.apply(this, arguments);
        631 } catch (e) {
        632 self.dbgLog_('Wrapping failed assert()');
        633 self.doAsyncError(e);
        634 }
        635 };
        636 fail = function() {
        637 /** @preserveTry */
        638 try {
        639 self.origFail_.apply(this, arguments);
        640 } catch (e) {
        641 self.dbgLog_('Wrapping fail()');
        642 self.doAsyncError(e);
        643 }
        644 };
        645 }
        646};
        647
        648
        649/**
        650 * Sets a window.onerror handler for catching exceptions that happen in async
        651 * callbacks. Note that as of Safari 3.1, Safari does not support this.
        652 * @private
        653 */
        654goog.testing.AsyncTestCase.prototype.hookOnError_ = function() {
        655 if (!this.origOnError_) {
        656 this.origOnError_ = window.onerror;
        657 var self = this;
        658 window.onerror = function(error, url, line) {
        659 // Ignore exceptions that we threw on purpose.
        660 var cbe =
        661 goog.testing.AsyncTestCase.ControlBreakingException.TO_STRING;
        662 if (String(error).indexOf(cbe) != -1 &&
        663 self.numControlExceptionsExpected_) {
        664 self.numControlExceptionsExpected_ -= 1;
        665 self.dbgLog_('window.onerror: numControlExceptionsExpected_ = ' +
        666 self.numControlExceptionsExpected_ + ' and ignoring exception. ' +
        667 error);
        668 // Tell the browser not to compain about the error.
        669 return true;
        670 } else {
        671 self.dbgLog_('window.onerror caught exception.');
        672 var message = error + '\nURL: ' + url + '\nLine: ' + line;
        673 self.doTopOfStackAsyncError_(message);
        674 // Tell the browser to complain about the error.
        675 return false;
        676 }
        677 };
        678 }
        679};
        680
        681
        682/**
        683 * Unhooks window.onerror and _assert.
        684 * @private
        685 */
        686goog.testing.AsyncTestCase.prototype.unhookAll_ = function() {
        687 if (this.origOnError_) {
        688 window.onerror = this.origOnError_;
        689 this.origOnError_ = null;
        690 _assert = this.origAssert_;
        691 this.origAssert_ = null;
        692 fail = this.origFail_;
        693 this.origFail_ = null;
        694 }
        695};
        696
        697
        698/**
        699 * Enables the timeout timer. This timer fires unless continueTesting is
        700 * called.
        701 * @private
        702 */
        703goog.testing.AsyncTestCase.prototype.startTimeoutTimer_ = function() {
        704 if (!this.timeoutHandle_ && this.stepTimeout > 0) {
        705 this.timeoutHandle_ = this.timeout(goog.bind(function() {
        706 this.dbgLog_('Timeout timer fired with id ' + this.timeoutHandle_);
        707 this.timeoutHandle_ = 0;
        708
        709 this.doTopOfStackAsyncError_('Timed out while waiting for ' +
        710 'continueTesting() to be called.');
        711 }, this, null), this.stepTimeout);
        712 this.dbgLog_('Started timeout timer with id ' + this.timeoutHandle_);
        713 }
        714};
        715
        716
        717/**
        718 * Disables the timeout timer.
        719 * @private
        720 */
        721goog.testing.AsyncTestCase.prototype.stopTimeoutTimer_ = function() {
        722 if (this.timeoutHandle_) {
        723 this.dbgLog_('Clearing timeout timer with id ' + this.timeoutHandle_);
        724 this.clearTimeout(this.timeoutHandle_);
        725 this.timeoutHandle_ = 0;
        726 }
        727};
        728
        729
        730/**
        731 * Sets the next function to call in our sequence of async callbacks.
        732 * @param {Function} func The function that executes the next step.
        733 * @param {string} name A description of the next step.
        734 * @private
        735 */
        736goog.testing.AsyncTestCase.prototype.setNextStep_ = function(func, name) {
        737 this.nextStepFunc_ = func && goog.bind(func, this);
        738 this.nextStepName_ = name;
        739};
        740
        741
        742/**
        743 * Calls the given function, redirecting any exceptions to doAsyncError.
        744 * @param {Function} func The function to call.
        745 * @return {!goog.testing.AsyncTestCase.TopStackFuncResult_} Returns a
        746 * TopStackFuncResult_.
        747 * @private
        748 */
        749goog.testing.AsyncTestCase.prototype.callTopOfStackFunc_ = function(func) {
        750 /** @preserveTry */
        751 try {
        752 func.call(this);
        753 return {controlBreakingExceptionThrown: false, message: ''};
        754 } catch (e) {
        755 this.dbgLog_('Caught exception in callTopOfStackFunc_');
        756 /** @preserveTry */
        757 try {
        758 this.doAsyncError(e);
        759 return {controlBreakingExceptionThrown: false, message: ''};
        760 } catch (e2) {
        761 if (!e2.isControlBreakingException) {
        762 throw e2;
        763 }
        764 return {controlBreakingExceptionThrown: true, message: e2.message};
        765 }
        766 }
        767};
        768
        769
        770/**
        771 * Calls the next callback when the isReady_ flag is true.
        772 * @param {Function=} opt_doFirst A function to call before pumping.
        773 * @private
        774 * @throws Throws a ControlBreakingException if there were any failing steps.
        775 */
        776goog.testing.AsyncTestCase.prototype.pump_ = function(opt_doFirst) {
        777 // If this function is already above us in the call-stack, then we should
        778 // return rather than pumping in order to minimize call-stack depth.
        779 if (!this.returnWillPump_) {
        780 this.setBatchTime(this.now());
        781 this.returnWillPump_ = true;
        782 var topFuncResult = {};
        783
        784 if (opt_doFirst) {
        785 topFuncResult = this.callTopOfStackFunc_(opt_doFirst);
        786 }
        787 // Note: we don't check for this.running here because it is not set to true
        788 // while executing setUpPage and tearDownPage.
        789 // Also, if isReady_ is false, then one of two things will happen:
        790 // 1. Our timeout callback will be called.
        791 // 2. The tests will call continueTesting(), which will call pump_() again.
        792 while (this.isReady_ && this.nextStepFunc_ &&
        793 !topFuncResult.controlBreakingExceptionThrown) {
        794 this.curStepFunc_ = this.nextStepFunc_;
        795 this.curStepName_ = this.nextStepName_;
        796 this.nextStepFunc_ = null;
        797 this.nextStepName_ = '';
        798
        799 this.dbgLog_('Performing step: ' + this.curStepName_);
        800 topFuncResult =
        801 this.callTopOfStackFunc_(/** @type {Function} */(this.curStepFunc_));
        802
        803 // If the max run time is exceeded call this function again async so as
        804 // not to block the browser.
        805 var delta = this.now() - this.getBatchTime();
        806 if (delta > goog.testing.TestCase.maxRunTime &&
        807 !topFuncResult.controlBreakingExceptionThrown) {
        808 this.saveMessage('Breaking async');
        809 var self = this;
        810 this.timeout(function() { self.pump_(); }, 100);
        811 break;
        812 }
        813 }
        814 this.returnWillPump_ = false;
        815 } else if (opt_doFirst) {
        816 opt_doFirst.call(this);
        817 }
        818};
        819
        820
        821/**
        822 * Sets up the test page and then waits untill the test case has been marked
        823 * as ready before executing the tests.
        824 * @private
        825 */
        826goog.testing.AsyncTestCase.prototype.doSetUpPage_ = function() {
        827 this.setNextStep_(this.execute, 'TestCase.execute');
        828 this.setUpPage();
        829};
        830
        831
        832/**
        833 * Step 1: Move to the next test.
        834 * @private
        835 */
        836goog.testing.AsyncTestCase.prototype.doIteration_ = function() {
        837 this.expectedSignalCount_ = 0;
        838 this.receivedSignalCount_ = 0;
        839 this.activeTest = this.next();
        840 if (this.activeTest && this.running) {
        841 this.result_.runCount++;
        842 // If this test should be marked as having failed, doIteration will go
        843 // straight to the next test.
        844 if (this.maybeFailTestEarly(this.activeTest)) {
        845 this.setNextStep_(this.doIteration_, 'doIteration');
        846 } else {
        847 this.setNextStep_(this.doSetUp_, 'setUp');
        848 }
        849 } else {
        850 // All tests done.
        851 this.finalize();
        852 }
        853};
        854
        855
        856/**
        857 * Step 2: Call setUp().
        858 * @private
        859 */
        860goog.testing.AsyncTestCase.prototype.doSetUp_ = function() {
        861 this.log('Running test: ' + this.activeTest.name);
        862 this.cleanedUp_ = false;
        863 this.setNextStep_(this.doExecute_, this.activeTest.name);
        864 this.setUp();
        865};
        866
        867
        868/**
        869 * Step 3: Call test.execute().
        870 * @private
        871 */
        872goog.testing.AsyncTestCase.prototype.doExecute_ = function() {
        873 this.setNextStep_(this.doTearDown_, 'tearDown');
        874 this.activeTest.execute();
        875};
        876
        877
        878/**
        879 * Step 4: Call tearDown().
        880 * @private
        881 */
        882goog.testing.AsyncTestCase.prototype.doTearDown_ = function() {
        883 this.cleanedUp_ = true;
        884 this.setNextStep_(this.doNext_, 'doNext');
        885 this.tearDown();
        886};
        887
        888
        889/**
        890 * Step 5: Call doSuccess()
        891 * @private
        892 */
        893goog.testing.AsyncTestCase.prototype.doNext_ = function() {
        894 this.setNextStep_(this.doIteration_, 'doIteration');
        895 this.doSuccess(/** @type {goog.testing.TestCase.Test} */(this.activeTest));
        896};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/events/events.js.src.html b/docs/api/javascript/source/lib/goog/testing/events/events.js.src.html new file mode 100644 index 0000000000000..f20dea4e6218a --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/events/events.js.src.html @@ -0,0 +1 @@ +events.js

        lib/goog/testing/events/events.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 Event Simulation.
        17 *
        18 * Utility functions for simulating events at the Closure level. All functions
        19 * in this package generate events by calling goog.events.fireListeners,
        20 * rather than interfacing with the browser directly. This is intended for
        21 * testing purposes, and should not be used in production code.
        22 *
        23 * The decision to use Closure events and dispatchers instead of the browser's
        24 * native events and dispatchers was conscious and deliberate. Native event
        25 * dispatchers have their own set of quirks and edge cases. Pure JS dispatchers
        26 * are more robust and transparent.
        27 *
        28 * If you think you need a testing mechanism that uses native Event objects,
        29 * please, please email closure-tech first to explain your use case before you
        30 * sink time into this.
        31 *
        32 * @author nicksantos@google.com (Nick Santos)
        33 */
        34
        35goog.provide('goog.testing.events');
        36goog.provide('goog.testing.events.Event');
        37
        38goog.require('goog.Disposable');
        39goog.require('goog.asserts');
        40goog.require('goog.dom.NodeType');
        41goog.require('goog.events');
        42goog.require('goog.events.BrowserEvent');
        43goog.require('goog.events.BrowserFeature');
        44goog.require('goog.events.EventTarget');
        45goog.require('goog.events.EventType');
        46goog.require('goog.events.KeyCodes');
        47goog.require('goog.object');
        48goog.require('goog.style');
        49goog.require('goog.userAgent');
        50
        51
        52
        53/**
        54 * goog.events.BrowserEvent expects an Event so we provide one for JSCompiler.
        55 *
        56 * This clones a lot of the functionality of goog.events.Event. This used to
        57 * use a mixin, but the mixin results in confusing the two types when compiled.
        58 *
        59 * @param {string} type Event Type.
        60 * @param {Object=} opt_target Reference to the object that is the target of
        61 * this event.
        62 * @constructor
        63 * @extends {Event}
        64 */
        65goog.testing.events.Event = function(type, opt_target) {
        66 this.type = type;
        67
        68 this.target = /** @type {EventTarget} */ (opt_target || null);
        69
        70 this.currentTarget = this.target;
        71};
        72
        73
        74/**
        75 * Whether to cancel the event in internal capture/bubble processing for IE.
        76 * @type {boolean}
        77 * @public
        78 * @suppress {underscore|visibility} Technically public, but referencing this
        79 * outside this package is strongly discouraged.
        80 */
        81goog.testing.events.Event.prototype.propagationStopped_ = false;
        82
        83
        84/** @override */
        85goog.testing.events.Event.prototype.defaultPrevented = false;
        86
        87
        88/**
        89 * Return value for in internal capture/bubble processing for IE.
        90 * @type {boolean}
        91 * @public
        92 * @suppress {underscore|visibility} Technically public, but referencing this
        93 * outside this package is strongly discouraged.
        94 */
        95goog.testing.events.Event.prototype.returnValue_ = true;
        96
        97
        98/** @override */
        99goog.testing.events.Event.prototype.stopPropagation = function() {
        100 this.propagationStopped_ = true;
        101};
        102
        103
        104/** @override */
        105goog.testing.events.Event.prototype.preventDefault = function() {
        106 this.defaultPrevented = true;
        107 this.returnValue_ = false;
        108};
        109
        110
        111/**
        112 * Asserts an event target exists. This will fail if target is not defined.
        113 *
        114 * TODO(nnaze): Gradually add this to the methods in this file, and eventually
        115 * update the method signatures to not take nullables. See http://b/8961907
        116 *
        117 * @param {EventTarget} target A target to assert.
        118 * @return {!EventTarget} The target, guaranteed to exist.
        119 * @private
        120 */
        121goog.testing.events.assertEventTarget_ = function(target) {
        122 return goog.asserts.assert(target, 'EventTarget should be defined.');
        123};
        124
        125
        126/**
        127 * A static helper function that sets the mouse position to the event.
        128 * @param {Event} event A simulated native event.
        129 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        130 * target's position (if available), otherwise (0, 0).
        131 * @private
        132 */
        133goog.testing.events.setEventClientXY_ = function(event, opt_coords) {
        134 if (!opt_coords && event.target &&
        135 event.target.nodeType == goog.dom.NodeType.ELEMENT) {
        136 try {
        137 opt_coords =
        138 goog.style.getClientPosition(/** @type {Element} **/ (event.target));
        139 } catch (ex) {
        140 // IE sometimes throws if it can't get the position.
        141 }
        142 }
        143 event.clientX = opt_coords ? opt_coords.x : 0;
        144 event.clientY = opt_coords ? opt_coords.y : 0;
        145
        146 // Pretend the browser window is at (0, 0).
        147 event.screenX = event.clientX;
        148 event.screenY = event.clientY;
        149};
        150
        151
        152/**
        153 * Simulates a mousedown, mouseup, and then click on the given event target,
        154 * with the left mouse button.
        155 * @param {EventTarget} target The target for the event.
        156 * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button;
        157 * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}.
        158 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        159 * target's position (if available), otherwise (0, 0).
        160 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        161 * BrowserEvent.
        162 * @return {boolean} The returnValue of the sequence: false if preventDefault()
        163 * was called on any of the events, true otherwise.
        164 */
        165goog.testing.events.fireClickSequence =
        166 function(target, opt_button, opt_coords, opt_eventProperties) {
        167 // Fire mousedown, mouseup, and click. Then return the bitwise AND of the 3.
        168 return !!(goog.testing.events.fireMouseDownEvent(
        169 target, opt_button, opt_coords, opt_eventProperties) &
        170 goog.testing.events.fireMouseUpEvent(
        171 target, opt_button, opt_coords, opt_eventProperties) &
        172 goog.testing.events.fireClickEvent(
        173 target, opt_button, opt_coords, opt_eventProperties));
        174};
        175
        176
        177/**
        178 * Simulates the sequence of events fired by the browser when the user double-
        179 * clicks the given target.
        180 * @param {EventTarget} target The target for the event.
        181 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        182 * target's position (if available), otherwise (0, 0).
        183 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        184 * BrowserEvent.
        185 * @return {boolean} The returnValue of the sequence: false if preventDefault()
        186 * was called on any of the events, true otherwise.
        187 */
        188goog.testing.events.fireDoubleClickSequence = function(
        189 target, opt_coords, opt_eventProperties) {
        190 // Fire mousedown, mouseup, click, mousedown, mouseup, click, dblclick.
        191 // Then return the bitwise AND of the 7.
        192 var btn = goog.events.BrowserEvent.MouseButton.LEFT;
        193 return !!(goog.testing.events.fireMouseDownEvent(
        194 target, btn, opt_coords, opt_eventProperties) &
        195 goog.testing.events.fireMouseUpEvent(
        196 target, btn, opt_coords, opt_eventProperties) &
        197 goog.testing.events.fireClickEvent(
        198 target, btn, opt_coords, opt_eventProperties) &
        199 // IE fires a selectstart instead of the second mousedown in a
        200 // dblclick, but we don't care about selectstart.
        201 (goog.userAgent.IE ||
        202 goog.testing.events.fireMouseDownEvent(
        203 target, btn, opt_coords, opt_eventProperties)) &
        204 goog.testing.events.fireMouseUpEvent(
        205 target, btn, opt_coords, opt_eventProperties) &
        206 // IE doesn't fire the second click in a dblclick.
        207 (goog.userAgent.IE ||
        208 goog.testing.events.fireClickEvent(
        209 target, btn, opt_coords, opt_eventProperties)) &
        210 goog.testing.events.fireDoubleClickEvent(
        211 target, opt_coords, opt_eventProperties));
        212};
        213
        214
        215/**
        216 * Simulates a complete keystroke (keydown, keypress, and keyup). Note that
        217 * if preventDefault is called on the keydown, the keypress will not fire.
        218 *
        219 * @param {EventTarget} target The target for the event.
        220 * @param {number} keyCode The keycode of the key pressed.
        221 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        222 * BrowserEvent.
        223 * @return {boolean} The returnValue of the sequence: false if preventDefault()
        224 * was called on any of the events, true otherwise.
        225 */
        226goog.testing.events.fireKeySequence = function(
        227 target, keyCode, opt_eventProperties) {
        228 return goog.testing.events.fireNonAsciiKeySequence(target, keyCode, keyCode,
        229 opt_eventProperties);
        230};
        231
        232
        233/**
        234 * Simulates a complete keystroke (keydown, keypress, and keyup) when typing
        235 * a non-ASCII character. Same as fireKeySequence, the keypress will not fire
        236 * if preventDefault is called on the keydown.
        237 *
        238 * @param {EventTarget} target The target for the event.
        239 * @param {number} keyCode The keycode of the keydown and keyup events.
        240 * @param {number} keyPressKeyCode The keycode of the keypress event.
        241 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        242 * BrowserEvent.
        243 * @return {boolean} The returnValue of the sequence: false if preventDefault()
        244 * was called on any of the events, true otherwise.
        245 */
        246goog.testing.events.fireNonAsciiKeySequence = function(
        247 target, keyCode, keyPressKeyCode, opt_eventProperties) {
        248 var keydown =
        249 new goog.testing.events.Event(goog.events.EventType.KEYDOWN, target);
        250 var keyup =
        251 new goog.testing.events.Event(goog.events.EventType.KEYUP, target);
        252 var keypress =
        253 new goog.testing.events.Event(goog.events.EventType.KEYPRESS, target);
        254 keydown.keyCode = keyup.keyCode = keyCode;
        255 keypress.keyCode = keyPressKeyCode;
        256
        257 if (opt_eventProperties) {
        258 goog.object.extend(keydown, opt_eventProperties);
        259 goog.object.extend(keyup, opt_eventProperties);
        260 goog.object.extend(keypress, opt_eventProperties);
        261 }
        262
        263 // Fire keydown, keypress, and keyup. Note that if the keydown is
        264 // prevent-defaulted, then the keypress will not fire.
        265 var result = true;
        266 if (!goog.testing.events.isBrokenGeckoMacActionKey_(keydown)) {
        267 result = goog.testing.events.fireBrowserEvent(keydown);
        268 }
        269 if (goog.events.KeyCodes.firesKeyPressEvent(
        270 keyCode, undefined, keydown.shiftKey, keydown.ctrlKey,
        271 keydown.altKey) && result) {
        272 result &= goog.testing.events.fireBrowserEvent(keypress);
        273 }
        274 return !!(result & goog.testing.events.fireBrowserEvent(keyup));
        275};
        276
        277
        278/**
        279 * @param {goog.testing.events.Event} e The event.
        280 * @return {boolean} Whether this is the Gecko/Mac's Meta-C/V/X, which
        281 * is broken and requires special handling.
        282 * @private
        283 */
        284goog.testing.events.isBrokenGeckoMacActionKey_ = function(e) {
        285 return goog.userAgent.MAC && goog.userAgent.GECKO &&
        286 (e.keyCode == goog.events.KeyCodes.C ||
        287 e.keyCode == goog.events.KeyCodes.X ||
        288 e.keyCode == goog.events.KeyCodes.V) && e.metaKey;
        289};
        290
        291
        292/**
        293 * Simulates a mouseover event on the given target.
        294 * @param {EventTarget} target The target for the event.
        295 * @param {EventTarget} relatedTarget The related target for the event (e.g.,
        296 * the node that the mouse is being moved out of).
        297 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        298 * target's position (if available), otherwise (0, 0).
        299 * @return {boolean} The returnValue of the event: false if preventDefault() was
        300 * called on it, true otherwise.
        301 */
        302goog.testing.events.fireMouseOverEvent = function(target, relatedTarget,
        303 opt_coords) {
        304 var mouseover =
        305 new goog.testing.events.Event(goog.events.EventType.MOUSEOVER, target);
        306 mouseover.relatedTarget = relatedTarget;
        307 goog.testing.events.setEventClientXY_(mouseover, opt_coords);
        308 return goog.testing.events.fireBrowserEvent(mouseover);
        309};
        310
        311
        312/**
        313 * Simulates a mousemove event on the given target.
        314 * @param {EventTarget} target The target for the event.
        315 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        316 * target's position (if available), otherwise (0, 0).
        317 * @return {boolean} The returnValue of the event: false if preventDefault() was
        318 * called on it, true otherwise.
        319 */
        320goog.testing.events.fireMouseMoveEvent = function(target, opt_coords) {
        321 var mousemove =
        322 new goog.testing.events.Event(goog.events.EventType.MOUSEMOVE, target);
        323
        324 goog.testing.events.setEventClientXY_(mousemove, opt_coords);
        325 return goog.testing.events.fireBrowserEvent(mousemove);
        326};
        327
        328
        329/**
        330 * Simulates a mouseout event on the given target.
        331 * @param {EventTarget} target The target for the event.
        332 * @param {EventTarget} relatedTarget The related target for the event (e.g.,
        333 * the node that the mouse is being moved into).
        334 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        335 * target's position (if available), otherwise (0, 0).
        336 * @return {boolean} The returnValue of the event: false if preventDefault() was
        337 * called on it, true otherwise.
        338 */
        339goog.testing.events.fireMouseOutEvent = function(target, relatedTarget,
        340 opt_coords) {
        341 var mouseout =
        342 new goog.testing.events.Event(goog.events.EventType.MOUSEOUT, target);
        343 mouseout.relatedTarget = relatedTarget;
        344 goog.testing.events.setEventClientXY_(mouseout, opt_coords);
        345 return goog.testing.events.fireBrowserEvent(mouseout);
        346};
        347
        348
        349/**
        350 * Simulates a mousedown event on the given target.
        351 * @param {EventTarget} target The target for the event.
        352 * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button;
        353 * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}.
        354 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        355 * target's position (if available), otherwise (0, 0).
        356 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        357 * BrowserEvent.
        358 * @return {boolean} The returnValue of the event: false if preventDefault() was
        359 * called on it, true otherwise.
        360 */
        361goog.testing.events.fireMouseDownEvent =
        362 function(target, opt_button, opt_coords, opt_eventProperties) {
        363
        364 var button = opt_button || goog.events.BrowserEvent.MouseButton.LEFT;
        365 button = !goog.events.BrowserFeature.HAS_W3C_BUTTON ?
        366 goog.events.BrowserEvent.IEButtonMap[button] : button;
        367 return goog.testing.events.fireMouseButtonEvent_(
        368 goog.events.EventType.MOUSEDOWN, target, button, opt_coords,
        369 opt_eventProperties);
        370};
        371
        372
        373/**
        374 * Simulates a mouseup event on the given target.
        375 * @param {EventTarget} target The target for the event.
        376 * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button;
        377 * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}.
        378 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        379 * target's position (if available), otherwise (0, 0).
        380 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        381 * BrowserEvent.
        382 * @return {boolean} The returnValue of the event: false if preventDefault() was
        383 * called on it, true otherwise.
        384 */
        385goog.testing.events.fireMouseUpEvent =
        386 function(target, opt_button, opt_coords, opt_eventProperties) {
        387 var button = opt_button || goog.events.BrowserEvent.MouseButton.LEFT;
        388 button = !goog.events.BrowserFeature.HAS_W3C_BUTTON ?
        389 goog.events.BrowserEvent.IEButtonMap[button] : button;
        390 return goog.testing.events.fireMouseButtonEvent_(
        391 goog.events.EventType.MOUSEUP, target, button, opt_coords,
        392 opt_eventProperties);
        393};
        394
        395
        396/**
        397 * Simulates a click event on the given target. IE only supports click with
        398 * the left mouse button.
        399 * @param {EventTarget} target The target for the event.
        400 * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button;
        401 * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}.
        402 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        403 * target's position (if available), otherwise (0, 0).
        404 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        405 * BrowserEvent.
        406 * @return {boolean} The returnValue of the event: false if preventDefault() was
        407 * called on it, true otherwise.
        408 */
        409goog.testing.events.fireClickEvent =
        410 function(target, opt_button, opt_coords, opt_eventProperties) {
        411 return goog.testing.events.fireMouseButtonEvent_(goog.events.EventType.CLICK,
        412 target, opt_button, opt_coords, opt_eventProperties);
        413};
        414
        415
        416/**
        417 * Simulates a double-click event on the given target. Always double-clicks
        418 * with the left mouse button since no browser supports double-clicking with
        419 * any other buttons.
        420 * @param {EventTarget} target The target for the event.
        421 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        422 * target's position (if available), otherwise (0, 0).
        423 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        424 * BrowserEvent.
        425 * @return {boolean} The returnValue of the event: false if preventDefault() was
        426 * called on it, true otherwise.
        427 */
        428goog.testing.events.fireDoubleClickEvent =
        429 function(target, opt_coords, opt_eventProperties) {
        430 return goog.testing.events.fireMouseButtonEvent_(
        431 goog.events.EventType.DBLCLICK, target,
        432 goog.events.BrowserEvent.MouseButton.LEFT, opt_coords,
        433 opt_eventProperties);
        434};
        435
        436
        437/**
        438 * Helper function to fire a mouse event.
        439 * with the left mouse button since no browser supports double-clicking with
        440 * any other buttons.
        441 * @param {string} type The event type.
        442 * @param {EventTarget} target The target for the event.
        443 * @param {number=} opt_button Mouse button; defaults to
        444 * {@code goog.events.BrowserEvent.MouseButton.LEFT}.
        445 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        446 * target's position (if available), otherwise (0, 0).
        447 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        448 * BrowserEvent.
        449 * @return {boolean} The returnValue of the event: false if preventDefault() was
        450 * called on it, true otherwise.
        451 * @private
        452 */
        453goog.testing.events.fireMouseButtonEvent_ =
        454 function(type, target, opt_button, opt_coords, opt_eventProperties) {
        455 var e =
        456 new goog.testing.events.Event(type, target);
        457 e.button = opt_button || goog.events.BrowserEvent.MouseButton.LEFT;
        458 goog.testing.events.setEventClientXY_(e, opt_coords);
        459 if (opt_eventProperties) {
        460 goog.object.extend(e, opt_eventProperties);
        461 }
        462 return goog.testing.events.fireBrowserEvent(e);
        463};
        464
        465
        466/**
        467 * Simulates a contextmenu event on the given target.
        468 * @param {EventTarget} target The target for the event.
        469 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        470 * target's position (if available), otherwise (0, 0).
        471 * @return {boolean} The returnValue of the event: false if preventDefault() was
        472 * called on it, true otherwise.
        473 */
        474goog.testing.events.fireContextMenuEvent = function(target, opt_coords) {
        475 var button = (goog.userAgent.MAC && goog.userAgent.WEBKIT) ?
        476 goog.events.BrowserEvent.MouseButton.LEFT :
        477 goog.events.BrowserEvent.MouseButton.RIGHT;
        478 var contextmenu =
        479 new goog.testing.events.Event(goog.events.EventType.CONTEXTMENU, target);
        480 contextmenu.button = !goog.events.BrowserFeature.HAS_W3C_BUTTON ?
        481 goog.events.BrowserEvent.IEButtonMap[button] : button;
        482 contextmenu.ctrlKey = goog.userAgent.MAC;
        483 goog.testing.events.setEventClientXY_(contextmenu, opt_coords);
        484 return goog.testing.events.fireBrowserEvent(contextmenu);
        485};
        486
        487
        488/**
        489 * Simulates a mousedown, contextmenu, and the mouseup on the given event
        490 * target, with the right mouse button.
        491 * @param {EventTarget} target The target for the event.
        492 * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's
        493 * target's position (if available), otherwise (0, 0).
        494 * @return {boolean} The returnValue of the sequence: false if preventDefault()
        495 * was called on any of the events, true otherwise.
        496 */
        497goog.testing.events.fireContextMenuSequence = function(target, opt_coords) {
        498 var props = goog.userAgent.MAC ? {ctrlKey: true} : {};
        499 var button = (goog.userAgent.MAC && goog.userAgent.WEBKIT) ?
        500 goog.events.BrowserEvent.MouseButton.LEFT :
        501 goog.events.BrowserEvent.MouseButton.RIGHT;
        502
        503 var result = goog.testing.events.fireMouseDownEvent(target,
        504 button, opt_coords, props);
        505 if (goog.userAgent.WINDOWS) {
        506 // All browsers are consistent on Windows.
        507 result &= goog.testing.events.fireMouseUpEvent(target,
        508 button, opt_coords) &
        509 goog.testing.events.fireContextMenuEvent(target, opt_coords);
        510 } else {
        511 result &= goog.testing.events.fireContextMenuEvent(target, opt_coords);
        512
        513 // GECKO on Mac and Linux always fires the mouseup after the contextmenu.
        514
        515 // WEBKIT is really weird.
        516 //
        517 // On Linux, it sometimes fires mouseup, but most of the time doesn't.
        518 // It's really hard to reproduce consistently. I think there's some
        519 // internal race condition. If contextmenu is preventDefaulted, then
        520 // mouseup always fires.
        521 //
        522 // On Mac, it always fires mouseup and then fires a click.
        523 result &= goog.testing.events.fireMouseUpEvent(target,
        524 button, opt_coords, props);
        525
        526 if (goog.userAgent.WEBKIT && goog.userAgent.MAC) {
        527 result &= goog.testing.events.fireClickEvent(
        528 target, button, opt_coords, props);
        529 }
        530 }
        531 return !!result;
        532};
        533
        534
        535/**
        536 * Simulates a popstate event on the given target.
        537 * @param {EventTarget} target The target for the event.
        538 * @param {Object} state History state object.
        539 * @return {boolean} The returnValue of the event: false if preventDefault() was
        540 * called on it, true otherwise.
        541 */
        542goog.testing.events.firePopStateEvent = function(target, state) {
        543 var e = new goog.testing.events.Event(goog.events.EventType.POPSTATE, target);
        544 e.state = state;
        545 return goog.testing.events.fireBrowserEvent(e);
        546};
        547
        548
        549/**
        550 * Simulate a blur event on the given target.
        551 * @param {EventTarget} target The target for the event.
        552 * @return {boolean} The value returned by firing the blur browser event,
        553 * which returns false iff 'preventDefault' was invoked.
        554 */
        555goog.testing.events.fireBlurEvent = function(target) {
        556 var e = new goog.testing.events.Event(
        557 goog.events.EventType.BLUR, target);
        558 return goog.testing.events.fireBrowserEvent(e);
        559};
        560
        561
        562/**
        563 * Simulate a focus event on the given target.
        564 * @param {EventTarget} target The target for the event.
        565 * @return {boolean} The value returned by firing the focus browser event,
        566 * which returns false iff 'preventDefault' was invoked.
        567 */
        568goog.testing.events.fireFocusEvent = function(target) {
        569 var e = new goog.testing.events.Event(
        570 goog.events.EventType.FOCUS, target);
        571 return goog.testing.events.fireBrowserEvent(e);
        572};
        573
        574
        575/**
        576 * Simulates an event's capturing and bubbling phases.
        577 * @param {Event} event A simulated native event. It will be wrapped in a
        578 * normalized BrowserEvent and dispatched to Closure listeners on all
        579 * ancestors of its target (inclusive).
        580 * @return {boolean} The returnValue of the event: false if preventDefault() was
        581 * called on it, true otherwise.
        582 */
        583goog.testing.events.fireBrowserEvent = function(event) {
        584 event.returnValue_ = true;
        585
        586 // generate a list of ancestors
        587 var ancestors = [];
        588 for (var current = event.target; current; current = current.parentNode) {
        589 ancestors.push(current);
        590 }
        591
        592 // dispatch capturing listeners
        593 for (var j = ancestors.length - 1;
        594 j >= 0 && !event.propagationStopped_;
        595 j--) {
        596 goog.events.fireListeners(ancestors[j], event.type, true,
        597 new goog.events.BrowserEvent(event, ancestors[j]));
        598 }
        599
        600 // dispatch bubbling listeners
        601 for (var j = 0;
        602 j < ancestors.length && !event.propagationStopped_;
        603 j++) {
        604 goog.events.fireListeners(ancestors[j], event.type, false,
        605 new goog.events.BrowserEvent(event, ancestors[j]));
        606 }
        607
        608 return event.returnValue_;
        609};
        610
        611
        612/**
        613 * Simulates a touchstart event on the given target.
        614 * @param {EventTarget} target The target for the event.
        615 * @param {goog.math.Coordinate=} opt_coords Touch position. Defaults to event's
        616 * target's position (if available), otherwise (0, 0).
        617 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        618 * BrowserEvent.
        619 * @return {boolean} The returnValue of the event: false if preventDefault() was
        620 * called on it, true otherwise.
        621 */
        622goog.testing.events.fireTouchStartEvent = function(
        623 target, opt_coords, opt_eventProperties) {
        624 // TODO: Support multi-touch events with array of coordinates.
        625 var touchstart =
        626 new goog.testing.events.Event(goog.events.EventType.TOUCHSTART, target);
        627 goog.testing.events.setEventClientXY_(touchstart, opt_coords);
        628 if (opt_eventProperties) {
        629 goog.object.extend(touchstart, opt_eventProperties);
        630 }
        631 return goog.testing.events.fireBrowserEvent(touchstart);
        632};
        633
        634
        635/**
        636 * Simulates a touchmove event on the given target.
        637 * @param {EventTarget} target The target for the event.
        638 * @param {goog.math.Coordinate=} opt_coords Touch position. Defaults to event's
        639 * target's position (if available), otherwise (0, 0).
        640 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        641 * BrowserEvent.
        642 * @return {boolean} The returnValue of the event: false if preventDefault() was
        643 * called on it, true otherwise.
        644 */
        645goog.testing.events.fireTouchMoveEvent = function(
        646 target, opt_coords, opt_eventProperties) {
        647 // TODO: Support multi-touch events with array of coordinates.
        648 var touchmove =
        649 new goog.testing.events.Event(goog.events.EventType.TOUCHMOVE, target);
        650 goog.testing.events.setEventClientXY_(touchmove, opt_coords);
        651 if (opt_eventProperties) {
        652 goog.object.extend(touchmove, opt_eventProperties);
        653 }
        654 return goog.testing.events.fireBrowserEvent(touchmove);
        655};
        656
        657
        658/**
        659 * Simulates a touchend event on the given target.
        660 * @param {EventTarget} target The target for the event.
        661 * @param {goog.math.Coordinate=} opt_coords Touch position. Defaults to event's
        662 * target's position (if available), otherwise (0, 0).
        663 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        664 * BrowserEvent.
        665 * @return {boolean} The returnValue of the event: false if preventDefault() was
        666 * called on it, true otherwise.
        667 */
        668goog.testing.events.fireTouchEndEvent = function(
        669 target, opt_coords, opt_eventProperties) {
        670 // TODO: Support multi-touch events with array of coordinates.
        671 var touchend =
        672 new goog.testing.events.Event(goog.events.EventType.TOUCHEND, target);
        673 goog.testing.events.setEventClientXY_(touchend, opt_coords);
        674 if (opt_eventProperties) {
        675 goog.object.extend(touchend, opt_eventProperties);
        676 }
        677 return goog.testing.events.fireBrowserEvent(touchend);
        678};
        679
        680
        681/**
        682 * Simulates a simple touch sequence on the given target.
        683 * @param {EventTarget} target The target for the event.
        684 * @param {goog.math.Coordinate=} opt_coords Touch position. Defaults to event
        685 * target's position (if available), otherwise (0, 0).
        686 * @param {Object=} opt_eventProperties Event properties to be mixed into the
        687 * BrowserEvent.
        688 * @return {boolean} The returnValue of the sequence: false if preventDefault()
        689 * was called on any of the events, true otherwise.
        690 */
        691goog.testing.events.fireTouchSequence = function(
        692 target, opt_coords, opt_eventProperties) {
        693 // TODO: Support multi-touch events with array of coordinates.
        694 // Fire touchstart, touchmove, touchend then return the bitwise AND of the 3.
        695 return !!(goog.testing.events.fireTouchStartEvent(
        696 target, opt_coords, opt_eventProperties) &
        697 goog.testing.events.fireTouchEndEvent(
        698 target, opt_coords, opt_eventProperties));
        699};
        700
        701
        702/**
        703 * Mixins a listenable into the given object. This turns the object
        704 * into a goog.events.Listenable. This is useful, for example, when
        705 * you need to mock a implementation of listenable and still want it
        706 * to work with goog.events.
        707 * @param {!Object} obj The object to mixin into.
        708 */
        709goog.testing.events.mixinListenable = function(obj) {
        710 var listenable = new goog.events.EventTarget();
        711
        712 listenable.setTargetForTesting(obj);
        713
        714 var listenablePrototype = goog.events.EventTarget.prototype;
        715 var disposablePrototype = goog.Disposable.prototype;
        716 for (var key in listenablePrototype) {
        717 if (listenablePrototype.hasOwnProperty(key) ||
        718 disposablePrototype.hasOwnProperty(key)) {
        719 var member = listenablePrototype[key];
        720 if (goog.isFunction(member)) {
        721 obj[key] = goog.bind(member, listenable);
        722 } else {
        723 obj[key] = member;
        724 }
        725 }
        726 }
        727};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/functionmock.js.src.html b/docs/api/javascript/source/lib/goog/testing/functionmock.js.src.html new file mode 100644 index 0000000000000..820a40f393624 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/functionmock.js.src.html @@ -0,0 +1 @@ +functionmock.js

        lib/goog/testing/functionmock.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 Enable mocking of functions not attached to objects
        17 * whether they be global / top-level or anonymous methods / closures.
        18 *
        19 * See the unit tests for usage.
        20 *
        21 */
        22
        23goog.provide('goog.testing');
        24goog.provide('goog.testing.FunctionMock');
        25goog.provide('goog.testing.GlobalFunctionMock');
        26goog.provide('goog.testing.MethodMock');
        27
        28goog.require('goog.object');
        29goog.require('goog.testing.LooseMock');
        30goog.require('goog.testing.Mock');
        31goog.require('goog.testing.MockInterface');
        32goog.require('goog.testing.PropertyReplacer');
        33goog.require('goog.testing.StrictMock');
        34
        35
        36/**
        37 * Class used to mock a function. Useful for mocking closures and anonymous
        38 * callbacks etc. Creates a function object that extends goog.testing.Mock.
        39 * @param {string=} opt_functionName The optional name of the function to mock.
        40 * Set to '[anonymous mocked function]' if not passed in.
        41 * @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or
        42 * goog.testing.Mock.STRICT. The default is STRICT.
        43 * @return {goog.testing.MockInterface} The mocked function.
        44 * @suppress {missingProperties} Mocks do not fit in the type system well.
        45 */
        46goog.testing.FunctionMock = function(opt_functionName, opt_strictness) {
        47 var fn = function() {
        48 var args = Array.prototype.slice.call(arguments);
        49 args.splice(0, 0, opt_functionName || '[anonymous mocked function]');
        50 return fn.$mockMethod.apply(fn, args);
        51 };
        52 var base = opt_strictness === goog.testing.Mock.LOOSE ?
        53 goog.testing.LooseMock : goog.testing.StrictMock;
        54 goog.object.extend(fn, new base({}));
        55
        56 return /** @type {goog.testing.MockInterface} */ (fn);
        57};
        58
        59
        60/**
        61 * Mocks an existing function. Creates a goog.testing.FunctionMock
        62 * and registers it in the given scope with the name specified by functionName.
        63 * @param {Object} scope The scope of the method to be mocked out.
        64 * @param {string} functionName The name of the function we're going to mock.
        65 * @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or
        66 * goog.testing.Mock.STRICT. The default is STRICT.
        67 * @return {!goog.testing.MockInterface} The mocked method.
        68 */
        69goog.testing.MethodMock = function(scope, functionName, opt_strictness) {
        70 if (!(functionName in scope)) {
        71 throw Error(functionName + ' is not a property of the given scope.');
        72 }
        73
        74 var fn = goog.testing.FunctionMock(functionName, opt_strictness);
        75
        76 fn.$propertyReplacer_ = new goog.testing.PropertyReplacer();
        77 fn.$propertyReplacer_.set(scope, functionName, fn);
        78 fn.$tearDown = goog.testing.MethodMock.$tearDown;
        79
        80 return fn;
        81};
        82
        83
        84/**
        85 * Resets the global function that we mocked back to its original state.
        86 * @this {goog.testing.MockInterface}
        87 */
        88goog.testing.MethodMock.$tearDown = function() {
        89 this.$propertyReplacer_.reset();
        90};
        91
        92
        93/**
        94 * Mocks a global / top-level function. Creates a goog.testing.MethodMock
        95 * in the global scope with the name specified by functionName.
        96 * @param {string} functionName The name of the function we're going to mock.
        97 * @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or
        98 * goog.testing.Mock.STRICT. The default is STRICT.
        99 * @return {!goog.testing.MockInterface} The mocked global function.
        100 */
        101goog.testing.GlobalFunctionMock = function(functionName, opt_strictness) {
        102 return goog.testing.MethodMock(goog.global, functionName, opt_strictness);
        103};
        104
        105
        106/**
        107 * Convenience method for creating a mock for a function.
        108 * @param {string=} opt_functionName The optional name of the function to mock
        109 * set to '[anonymous mocked function]' if not passed in.
        110 * @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or
        111 * goog.testing.Mock.STRICT. The default is STRICT.
        112 * @return {goog.testing.MockInterface} The mocked function.
        113 */
        114goog.testing.createFunctionMock = function(opt_functionName, opt_strictness) {
        115 return goog.testing.FunctionMock(opt_functionName, opt_strictness);
        116};
        117
        118
        119/**
        120 * Convenience method for creating a mock for a method.
        121 * @param {Object} scope The scope of the method to be mocked out.
        122 * @param {string} functionName The name of the function we're going to mock.
        123 * @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or
        124 * goog.testing.Mock.STRICT. The default is STRICT.
        125 * @return {!goog.testing.MockInterface} The mocked global function.
        126 */
        127goog.testing.createMethodMock = function(scope, functionName, opt_strictness) {
        128 return goog.testing.MethodMock(scope, functionName, opt_strictness);
        129};
        130
        131
        132/**
        133 * Convenience method for creating a mock for a constructor. Copies class
        134 * members to the mock.
        135 *
        136 * <p>When mocking a constructor to return a mocked instance, remember to create
        137 * the instance mock before mocking the constructor. If you mock the constructor
        138 * first, then the mock framework will be unable to examine the prototype chain
        139 * when creating the mock instance.
        140 * @param {Object} scope The scope of the constructor to be mocked out.
        141 * @param {string} constructorName The name of the constructor we're going to
        142 * mock.
        143 * @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or
        144 * goog.testing.Mock.STRICT. The default is STRICT.
        145 * @return {!goog.testing.MockInterface} The mocked constructor.
        146 */
        147goog.testing.createConstructorMock = function(scope, constructorName,
        148 opt_strictness) {
        149 var realConstructor = scope[constructorName];
        150 var constructorMock = goog.testing.MethodMock(scope, constructorName,
        151 opt_strictness);
        152
        153 // Copy class members from the real constructor to the mock. Do not copy
        154 // the closure superClass_ property (see goog.inherits), the built-in
        155 // prototype property, or properties added to Function.prototype
        156 // (see goog.MODIFY_FUNCTION_PROTOTYPES in closure/base.js).
        157 for (var property in realConstructor) {
        158 if (property != 'superClass_' &&
        159 property != 'prototype' &&
        160 realConstructor.hasOwnProperty(property)) {
        161 constructorMock[property] = realConstructor[property];
        162 }
        163 }
        164 return constructorMock;
        165};
        166
        167
        168/**
        169 * Convenience method for creating a mocks for a global / top-level function.
        170 * @param {string} functionName The name of the function we're going to mock.
        171 * @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or
        172 * goog.testing.Mock.STRICT. The default is STRICT.
        173 * @return {goog.testing.MockInterface} The mocked global function.
        174 */
        175goog.testing.createGlobalFunctionMock = function(functionName, opt_strictness) {
        176 return goog.testing.GlobalFunctionMock(functionName, opt_strictness);
        177};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/jsunit.js.src.html b/docs/api/javascript/source/lib/goog/testing/jsunit.js.src.html new file mode 100644 index 0000000000000..a3424ace01687 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/jsunit.js.src.html @@ -0,0 +1 @@ +jsunit.js

        lib/goog/testing/jsunit.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 Utilities for working with JsUnit. Writes out the JsUnit file
        17 * that needs to be included in every unit test.
        18 *
        19 * Testing code should not have dependencies outside of goog.testing so as to
        20 * reduce the chance of masking missing dependencies.
        21 *
        22 */
        23
        24goog.provide('goog.testing.jsunit');
        25
        26goog.require('goog.testing.TestCase');
        27goog.require('goog.testing.TestRunner');
        28
        29
        30/**
        31 * Base path for JsUnit app files, relative to Closure's base path.
        32 * @type {string}
        33 */
        34goog.testing.jsunit.BASE_PATH =
        35 '../../third_party/java/jsunit/core/app/';
        36
        37
        38/**
        39 * Filename for the core JS Unit script.
        40 * @type {string}
        41 */
        42goog.testing.jsunit.CORE_SCRIPT =
        43 goog.testing.jsunit.BASE_PATH + 'jsUnitCore.js';
        44
        45
        46/**
        47 * @define {boolean} If this code is being parsed by JsTestC, we let it disable
        48 * the onload handler to avoid running the test in JsTestC.
        49 */
        50goog.define('goog.testing.jsunit.AUTO_RUN_ONLOAD', true);
        51
        52
        53/**
        54 * @define {number} Sets a delay in milliseconds after the window onload event
        55 * and running the tests. Used to prevent interference with Selenium and give
        56 * tests with asynchronous operations time to finish loading.
        57 */
        58goog.define('goog.testing.jsunit.AUTO_RUN_DELAY_IN_MS', 500);
        59
        60
        61(function() {
        62 // Increases the maximum number of stack frames in Google Chrome from the
        63 // default 10 to 50 to get more useful stack traces.
        64 Error.stackTraceLimit = 50;
        65
        66 // Store a reference to the window's timeout so that it can't be overridden
        67 // by tests.
        68 /** @type {!Function} */
        69 var realTimeout = window.setTimeout;
        70
        71 // Check for JsUnit's test runner (need to check for >2.2 and <=2.2)
        72 if (top['JsUnitTestManager'] || top['jsUnitTestManager']) {
        73 // Running inside JsUnit so add support code.
        74 var path = goog.basePath + goog.testing.jsunit.CORE_SCRIPT;
        75 document.write('<script type="text/javascript" src="' +
        76 path + '"></' + 'script>');
        77
        78 } else {
        79
        80 // Create a test runner.
        81 var tr = new goog.testing.TestRunner();
        82
        83 // Export it so that it can be queried by Selenium and tests that use a
        84 // compiled test runner.
        85 goog.exportSymbol('G_testRunner', tr);
        86 goog.exportSymbol('G_testRunner.initialize', tr.initialize);
        87 goog.exportSymbol('G_testRunner.isInitialized', tr.isInitialized);
        88 goog.exportSymbol('G_testRunner.isFinished', tr.isFinished);
        89 goog.exportSymbol('G_testRunner.isSuccess', tr.isSuccess);
        90 goog.exportSymbol('G_testRunner.getReport', tr.getReport);
        91 goog.exportSymbol('G_testRunner.getRunTime', tr.getRunTime);
        92 goog.exportSymbol('G_testRunner.getNumFilesLoaded', tr.getNumFilesLoaded);
        93 goog.exportSymbol('G_testRunner.setStrict', tr.setStrict);
        94 goog.exportSymbol('G_testRunner.logTestFailure', tr.logTestFailure);
        95 goog.exportSymbol('G_testRunner.getTestResults', tr.getTestResults);
        96
        97 // Export debug as a global function for JSUnit compatibility. This just
        98 // calls log on the current test case.
        99 if (!goog.global['debug']) {
        100 goog.exportSymbol('debug', goog.bind(tr.log, tr));
        101 }
        102
        103 // If the application has defined a global error filter, set it now. This
        104 // allows users who use a base test include to set the error filter before
        105 // the testing code is loaded.
        106 if (goog.global['G_errorFilter']) {
        107 tr.setErrorFilter(goog.global['G_errorFilter']);
        108 }
        109
        110 // Add an error handler to report errors that may occur during
        111 // initialization of the page.
        112 var onerror = window.onerror;
        113 window.onerror = function(error, url, line) {
        114 // Call any existing onerror handlers.
        115 if (onerror) {
        116 onerror(error, url, line);
        117 }
        118 if (typeof error == 'object') {
        119 // Webkit started passing an event object as the only argument to
        120 // window.onerror. It doesn't contain an error message, url or line
        121 // number. We therefore log as much info as we can.
        122 if (error.target && error.target.tagName == 'SCRIPT') {
        123 tr.logError('UNKNOWN ERROR: Script ' + error.target.src);
        124 } else {
        125 tr.logError('UNKNOWN ERROR: No error information available.');
        126 }
        127 } else {
        128 tr.logError('JS ERROR: ' + error + '\nURL: ' + url + '\nLine: ' + line);
        129 }
        130 };
        131
        132 // Create an onload handler, if the test runner hasn't been initialized then
        133 // no test has been registered with the test runner by the test file. We
        134 // then create a new test case and auto discover any tests in the global
        135 // scope. If this code is being parsed by JsTestC, we let it disable the
        136 // onload handler to avoid running the test in JsTestC.
        137 if (goog.testing.jsunit.AUTO_RUN_ONLOAD) {
        138 var onload = window.onload;
        139 window.onload = function(e) {
        140 // Call any existing onload handlers.
        141 if (onload) {
        142 onload(e);
        143 }
        144 // Wait so that we don't interfere with WebDriver.
        145 realTimeout(function() {
        146 if (!tr.initialized) {
        147 var test = new goog.testing.TestCase(document.title);
        148 test.autoDiscoverTests();
        149 tr.initialize(test);
        150 }
        151 tr.execute();
        152 }, goog.testing.jsunit.AUTO_RUN_DELAY_IN_MS);
        153 window.onload = null;
        154 };
        155 }
        156 }
        157})();
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/loosemock.js.src.html b/docs/api/javascript/source/lib/goog/testing/loosemock.js.src.html new file mode 100644 index 0000000000000..9aab9bc7206bc --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/loosemock.js.src.html @@ -0,0 +1 @@ +loosemock.js

        lib/goog/testing/loosemock.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 This file defines a loose mock implementation.
        17 */
        18
        19goog.provide('goog.testing.LooseExpectationCollection');
        20goog.provide('goog.testing.LooseMock');
        21
        22goog.require('goog.array');
        23goog.require('goog.structs.Map');
        24goog.require('goog.testing.Mock');
        25
        26
        27
        28/**
        29 * This class is an ordered collection of expectations for one method. Since
        30 * the loose mock does most of its verification at the time of $verify, this
        31 * class is necessary to manage the return/throw behavior when the mock is
        32 * being called.
        33 * @constructor
        34 * @final
        35 */
        36goog.testing.LooseExpectationCollection = function() {
        37 /**
        38 * The list of expectations. All of these should have the same name.
        39 * @type {Array.<goog.testing.MockExpectation>}
        40 * @private
        41 */
        42 this.expectations_ = [];
        43};
        44
        45
        46/**
        47 * Adds an expectation to this collection.
        48 * @param {goog.testing.MockExpectation} expectation The expectation to add.
        49 */
        50goog.testing.LooseExpectationCollection.prototype.addExpectation =
        51 function(expectation) {
        52 this.expectations_.push(expectation);
        53};
        54
        55
        56/**
        57 * Gets the list of expectations in this collection.
        58 * @return {Array.<goog.testing.MockExpectation>} The array of expectations.
        59 */
        60goog.testing.LooseExpectationCollection.prototype.getExpectations = function() {
        61 return this.expectations_;
        62};
        63
        64
        65
        66/**
        67 * This is a mock that does not care about the order of method calls. As a
        68 * result, it won't throw exceptions until verify() is called. The only
        69 * exception is that if a method is called that has no expectations, then an
        70 * exception will be thrown.
        71 * @param {Object|Function} objectToMock The object that should be mocked, or
        72 * the constructor of an object to mock.
        73 * @param {boolean=} opt_ignoreUnexpectedCalls Whether to ignore unexpected
        74 * calls.
        75 * @param {boolean=} opt_mockStaticMethods An optional argument denoting that
        76 * a mock should be constructed from the static functions of a class.
        77 * @param {boolean=} opt_createProxy An optional argument denoting that
        78 * a proxy for the target mock should be created.
        79 * @constructor
        80 * @extends {goog.testing.Mock}
        81 */
        82goog.testing.LooseMock = function(objectToMock, opt_ignoreUnexpectedCalls,
        83 opt_mockStaticMethods, opt_createProxy) {
        84 goog.testing.Mock.call(this, objectToMock, opt_mockStaticMethods,
        85 opt_createProxy);
        86
        87 /**
        88 * A map of method names to a LooseExpectationCollection for that method.
        89 * @type {goog.structs.Map}
        90 * @private
        91 */
        92 this.$expectations_ = new goog.structs.Map();
        93
        94 /**
        95 * The calls that have been made; we cache them to verify at the end. Each
        96 * element is an array where the first element is the name, and the second
        97 * element is the arguments.
        98 * @type {Array.<Array.<*>>}
        99 * @private
        100 */
        101 this.$calls_ = [];
        102
        103 /**
        104 * Whether to ignore unexpected calls.
        105 * @type {boolean}
        106 * @private
        107 */
        108 this.$ignoreUnexpectedCalls_ = !!opt_ignoreUnexpectedCalls;
        109};
        110goog.inherits(goog.testing.LooseMock, goog.testing.Mock);
        111
        112
        113/**
        114 * A setter for the ignoreUnexpectedCalls field.
        115 * @param {boolean} ignoreUnexpectedCalls Whether to ignore unexpected calls.
        116 * @return {!goog.testing.LooseMock} This mock object.
        117 */
        118goog.testing.LooseMock.prototype.$setIgnoreUnexpectedCalls = function(
        119 ignoreUnexpectedCalls) {
        120 this.$ignoreUnexpectedCalls_ = ignoreUnexpectedCalls;
        121 return this;
        122};
        123
        124
        125/** @override */
        126goog.testing.LooseMock.prototype.$recordExpectation = function() {
        127 if (!this.$expectations_.containsKey(this.$pendingExpectation.name)) {
        128 this.$expectations_.set(this.$pendingExpectation.name,
        129 new goog.testing.LooseExpectationCollection());
        130 }
        131
        132 var collection = this.$expectations_.get(this.$pendingExpectation.name);
        133 collection.addExpectation(this.$pendingExpectation);
        134};
        135
        136
        137/** @override */
        138goog.testing.LooseMock.prototype.$recordCall = function(name, args) {
        139 if (!this.$expectations_.containsKey(name)) {
        140 if (this.$ignoreUnexpectedCalls_) {
        141 return;
        142 }
        143 this.$throwCallException(name, args);
        144 }
        145
        146 // Start from the beginning of the expectations for this name,
        147 // and iterate over them until we find an expectation that matches
        148 // and also has calls remaining.
        149 var collection = this.$expectations_.get(name);
        150 var matchingExpectation = null;
        151 var expectations = collection.getExpectations();
        152 for (var i = 0; i < expectations.length; i++) {
        153 var expectation = expectations[i];
        154 if (this.$verifyCall(expectation, name, args)) {
        155 matchingExpectation = expectation;
        156 if (expectation.actualCalls < expectation.maxCalls) {
        157 break;
        158 } // else continue and see if we can find something that does match
        159 }
        160 }
        161 if (matchingExpectation == null) {
        162 this.$throwCallException(name, args, expectation);
        163 }
        164
        165 matchingExpectation.actualCalls++;
        166 if (matchingExpectation.actualCalls > matchingExpectation.maxCalls) {
        167 this.$throwException('Too many calls to ' + matchingExpectation.name +
        168 '\nExpected: ' + matchingExpectation.maxCalls + ' but was: ' +
        169 matchingExpectation.actualCalls);
        170 }
        171
        172 this.$calls_.push([name, args]);
        173 return this.$do(matchingExpectation, args);
        174};
        175
        176
        177/** @override */
        178goog.testing.LooseMock.prototype.$reset = function() {
        179 goog.testing.LooseMock.superClass_.$reset.call(this);
        180
        181 this.$expectations_ = new goog.structs.Map();
        182 this.$calls_ = [];
        183};
        184
        185
        186/** @override */
        187goog.testing.LooseMock.prototype.$replay = function() {
        188 goog.testing.LooseMock.superClass_.$replay.call(this);
        189
        190 // Verify that there are no expectations that can never be reached.
        191 // This can't catch every situation, but it is a decent sanity check
        192 // and it's similar to the behavior of EasyMock in java.
        193 var collections = this.$expectations_.getValues();
        194 for (var i = 0; i < collections.length; i++) {
        195 var expectations = collections[i].getExpectations();
        196 for (var j = 0; j < expectations.length; j++) {
        197 var expectation = expectations[j];
        198 // If this expectation can be called infinite times, then
        199 // check if any subsequent expectation has the exact same
        200 // argument list.
        201 if (!isFinite(expectation.maxCalls)) {
        202 for (var k = j + 1; k < expectations.length; k++) {
        203 var laterExpectation = expectations[k];
        204 if (laterExpectation.minCalls > 0 &&
        205 goog.array.equals(expectation.argumentList,
        206 laterExpectation.argumentList)) {
        207 var name = expectation.name;
        208 var argsString = this.$argumentsAsString(expectation.argumentList);
        209 this.$throwException([
        210 'Expected call to ', name, ' with arguments ', argsString,
        211 ' has an infinite max number of calls; can\'t expect an',
        212 ' identical call later with a positive min number of calls'
        213 ].join(''));
        214 }
        215 }
        216 }
        217 }
        218 }
        219};
        220
        221
        222/** @override */
        223goog.testing.LooseMock.prototype.$verify = function() {
        224 goog.testing.LooseMock.superClass_.$verify.call(this);
        225 var collections = this.$expectations_.getValues();
        226
        227 for (var i = 0; i < collections.length; i++) {
        228 var expectations = collections[i].getExpectations();
        229 for (var j = 0; j < expectations.length; j++) {
        230 var expectation = expectations[j];
        231 if (expectation.actualCalls > expectation.maxCalls) {
        232 this.$throwException('Too many calls to ' + expectation.name +
        233 '\nExpected: ' + expectation.maxCalls + ' but was: ' +
        234 expectation.actualCalls);
        235 } else if (expectation.actualCalls < expectation.minCalls) {
        236 this.$throwException('Not enough calls to ' + expectation.name +
        237 '\nExpected: ' + expectation.minCalls + ' but was: ' +
        238 expectation.actualCalls);
        239 }
        240 }
        241 }
        242};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/mock.js.src.html b/docs/api/javascript/source/lib/goog/testing/mock.js.src.html new file mode 100644 index 0000000000000..db8ae1ef0841e --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/mock.js.src.html @@ -0,0 +1 @@ +mock.js

        lib/goog/testing/mock.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 This file defines base classes used for creating mocks in
        17 * JavaScript. The API was inspired by EasyMock.
        18 *
        19 * The basic API is:
        20 * <ul>
        21 * <li>Create an object to be mocked
        22 * <li>Create a mock object, passing in the above object to the constructor
        23 * <li>Set expectations by calling methods on the mock object
        24 * <li>Call $replay() on the mock object
        25 * <li>Pass the mock to code that will make real calls on it
        26 * <li>Call $verify() to make sure that expectations were met
        27 * </ul>
        28 *
        29 * For examples, please see the unit tests for LooseMock and StrictMock.
        30 *
        31 * Still TODO
        32 * implement better (and pluggable) argument matching
        33 * Have the exceptions for LooseMock show the number of expected/actual calls
        34 * loose and strict mocks share a lot of code - move it to the base class
        35 *
        36 */
        37
        38goog.provide('goog.testing.Mock');
        39goog.provide('goog.testing.MockExpectation');
        40
        41goog.require('goog.array');
        42goog.require('goog.object');
        43goog.require('goog.testing.JsUnitException');
        44goog.require('goog.testing.MockInterface');
        45goog.require('goog.testing.mockmatchers');
        46
        47
        48
        49/**
        50 * This is a class that represents an expectation.
        51 * @param {string} name The name of the method for this expectation.
        52 * @constructor
        53 * @final
        54 */
        55goog.testing.MockExpectation = function(name) {
        56 /**
        57 * The name of the method that is expected to be called.
        58 * @type {string}
        59 */
        60 this.name = name;
        61
        62 /**
        63 * An array of error messages for expectations not met.
        64 * @type {Array}
        65 */
        66 this.errorMessages = [];
        67};
        68
        69
        70/**
        71 * The minimum number of times this method should be called.
        72 * @type {number}
        73 */
        74goog.testing.MockExpectation.prototype.minCalls = 1;
        75
        76
        77/**
        78 * The maximum number of times this method should be called.
        79 * @type {number}
        80 */
        81goog.testing.MockExpectation.prototype.maxCalls = 1;
        82
        83
        84/**
        85 * The value that this method should return.
        86 * @type {*}
        87 */
        88goog.testing.MockExpectation.prototype.returnValue;
        89
        90
        91/**
        92 * The value that will be thrown when the method is called
        93 * @type {*}
        94 */
        95goog.testing.MockExpectation.prototype.exceptionToThrow;
        96
        97
        98/**
        99 * The arguments that are expected to be passed to this function
        100 * @type {Array.<*>}
        101 */
        102goog.testing.MockExpectation.prototype.argumentList;
        103
        104
        105/**
        106 * The number of times this method is called by real code.
        107 * @type {number}
        108 */
        109goog.testing.MockExpectation.prototype.actualCalls = 0;
        110
        111
        112/**
        113 * The number of times this method is called during the verification phase.
        114 * @type {number}
        115 */
        116goog.testing.MockExpectation.prototype.verificationCalls = 0;
        117
        118
        119/**
        120 * The function which will be executed when this method is called.
        121 * Method arguments will be passed to this function, and return value
        122 * of this function will be returned by the method.
        123 * @type {Function}
        124 */
        125goog.testing.MockExpectation.prototype.toDo;
        126
        127
        128/**
        129 * Allow expectation failures to include messages.
        130 * @param {string} message The failure message.
        131 */
        132goog.testing.MockExpectation.prototype.addErrorMessage = function(message) {
        133 this.errorMessages.push(message);
        134};
        135
        136
        137/**
        138 * Get the error messages seen so far.
        139 * @return {string} Error messages separated by \n.
        140 */
        141goog.testing.MockExpectation.prototype.getErrorMessage = function() {
        142 return this.errorMessages.join('\n');
        143};
        144
        145
        146/**
        147 * Get how many error messages have been seen so far.
        148 * @return {number} Count of error messages.
        149 */
        150goog.testing.MockExpectation.prototype.getErrorMessageCount = function() {
        151 return this.errorMessages.length;
        152};
        153
        154
        155
        156/**
        157 * The base class for a mock object.
        158 * @param {Object|Function} objectToMock The object that should be mocked, or
        159 * the constructor of an object to mock.
        160 * @param {boolean=} opt_mockStaticMethods An optional argument denoting that
        161 * a mock should be constructed from the static functions of a class.
        162 * @param {boolean=} opt_createProxy An optional argument denoting that
        163 * a proxy for the target mock should be created.
        164 * @constructor
        165 * @implements {goog.testing.MockInterface}
        166 */
        167goog.testing.Mock = function(objectToMock, opt_mockStaticMethods,
        168 opt_createProxy) {
        169 if (!goog.isObject(objectToMock) && !goog.isFunction(objectToMock)) {
        170 throw new Error('objectToMock must be an object or constructor.');
        171 }
        172 if (opt_createProxy && !opt_mockStaticMethods &&
        173 goog.isFunction(objectToMock)) {
        174 /**
        175 * @constructor
        176 * @final
        177 */
        178 var tempCtor = function() {};
        179 goog.inherits(tempCtor, objectToMock);
        180 this.$proxy = new tempCtor();
        181 } else if (opt_createProxy && opt_mockStaticMethods &&
        182 goog.isFunction(objectToMock)) {
        183 throw Error('Cannot create a proxy when opt_mockStaticMethods is true');
        184 } else if (opt_createProxy && !goog.isFunction(objectToMock)) {
        185 throw Error('Must have a constructor to create a proxy');
        186 }
        187
        188 if (goog.isFunction(objectToMock) && !opt_mockStaticMethods) {
        189 this.$initializeFunctions_(objectToMock.prototype);
        190 } else {
        191 this.$initializeFunctions_(objectToMock);
        192 }
        193 this.$argumentListVerifiers_ = {};
        194};
        195
        196
        197/**
        198 * Option that may be passed when constructing function, method, and
        199 * constructor mocks. Indicates that the expected calls should be accepted in
        200 * any order.
        201 * @const
        202 * @type {number}
        203 */
        204goog.testing.Mock.LOOSE = 1;
        205
        206
        207/**
        208 * Option that may be passed when constructing function, method, and
        209 * constructor mocks. Indicates that the expected calls should be accepted in
        210 * the recorded order only.
        211 * @const
        212 * @type {number}
        213 */
        214goog.testing.Mock.STRICT = 0;
        215
        216
        217/**
        218 * This array contains the name of the functions that are part of the base
        219 * Object prototype.
        220 * Basically a copy of goog.object.PROTOTYPE_FIELDS_.
        221 * @const
        222 * @type {!Array.<string>}
        223 * @private
        224 */
        225goog.testing.Mock.PROTOTYPE_FIELDS_ = [
        226 'constructor',
        227 'hasOwnProperty',
        228 'isPrototypeOf',
        229 'propertyIsEnumerable',
        230 'toLocaleString',
        231 'toString',
        232 'valueOf'
        233];
        234
        235
        236/**
        237 * A proxy for the mock. This can be used for dependency injection in lieu of
        238 * the mock if the test requires a strict instanceof check.
        239 * @type {Object}
        240 */
        241goog.testing.Mock.prototype.$proxy = null;
        242
        243
        244/**
        245 * Map of argument name to optional argument list verifier function.
        246 * @type {Object}
        247 */
        248goog.testing.Mock.prototype.$argumentListVerifiers_;
        249
        250
        251/**
        252 * Whether or not we are in recording mode.
        253 * @type {boolean}
        254 * @private
        255 */
        256goog.testing.Mock.prototype.$recording_ = true;
        257
        258
        259/**
        260 * The expectation currently being created. All methods that modify the
        261 * current expectation return the Mock object for easy chaining, so this is
        262 * where we keep track of the expectation that's currently being modified.
        263 * @type {goog.testing.MockExpectation}
        264 * @protected
        265 */
        266goog.testing.Mock.prototype.$pendingExpectation;
        267
        268
        269/**
        270 * First exception thrown by this mock; used in $verify.
        271 * @type {Object}
        272 * @private
        273 */
        274goog.testing.Mock.prototype.$threwException_ = null;
        275
        276
        277/**
        278 * Initializes the functions on the mock object.
        279 * @param {Object} objectToMock The object being mocked.
        280 * @private
        281 */
        282goog.testing.Mock.prototype.$initializeFunctions_ = function(objectToMock) {
        283 // Gets the object properties.
        284 var enumerableProperties = goog.object.getKeys(objectToMock);
        285
        286 // The non enumerable properties are added if they override the ones in the
        287 // Object prototype. This is due to the fact that IE8 does not enumerate any
        288 // of the prototype Object functions even when overriden and mocking these is
        289 // sometimes needed.
        290 for (var i = 0; i < goog.testing.Mock.PROTOTYPE_FIELDS_.length; i++) {
        291 var prop = goog.testing.Mock.PROTOTYPE_FIELDS_[i];
        292 // Look at b/6758711 if you're considering adding ALL properties to ALL
        293 // mocks.
        294 if (objectToMock[prop] !== Object.prototype[prop]) {
        295 enumerableProperties.push(prop);
        296 }
        297 }
        298
        299 // Adds the properties to the mock.
        300 for (var i = 0; i < enumerableProperties.length; i++) {
        301 var prop = enumerableProperties[i];
        302 if (typeof objectToMock[prop] == 'function') {
        303 this[prop] = goog.bind(this.$mockMethod, this, prop);
        304 if (this.$proxy) {
        305 this.$proxy[prop] = goog.bind(this.$mockMethod, this, prop);
        306 }
        307 }
        308 }
        309};
        310
        311
        312/**
        313 * Registers a verfifier function to use when verifying method argument lists.
        314 * @param {string} methodName The name of the method for which the verifierFn
        315 * should be used.
        316 * @param {Function} fn Argument list verifier function. Should take 2 argument
        317 * arrays as arguments, and return true if they are considered equivalent.
        318 * @return {!goog.testing.Mock} This mock object.
        319 */
        320goog.testing.Mock.prototype.$registerArgumentListVerifier = function(methodName,
        321 fn) {
        322 this.$argumentListVerifiers_[methodName] = fn;
        323 return this;
        324};
        325
        326
        327/**
        328 * The function that replaces all methods on the mock object.
        329 * @param {string} name The name of the method being mocked.
        330 * @return {*} In record mode, returns the mock object. In replay mode, returns
        331 * whatever the creator of the mock set as the return value.
        332 */
        333goog.testing.Mock.prototype.$mockMethod = function(name) {
        334 try {
        335 // Shift off the name argument so that args contains the arguments to
        336 // the mocked method.
        337 var args = goog.array.slice(arguments, 1);
        338 if (this.$recording_) {
        339 this.$pendingExpectation = new goog.testing.MockExpectation(name);
        340 this.$pendingExpectation.argumentList = args;
        341 this.$recordExpectation();
        342 return this;
        343 } else {
        344 return this.$recordCall(name, args);
        345 }
        346 } catch (ex) {
        347 this.$recordAndThrow(ex);
        348 }
        349};
        350
        351
        352/**
        353 * Records the currently pending expectation, intended to be overridden by a
        354 * subclass.
        355 * @protected
        356 */
        357goog.testing.Mock.prototype.$recordExpectation = function() {};
        358
        359
        360/**
        361 * Records an actual method call, intended to be overridden by a
        362 * subclass. The subclass must find the pending expectation and return the
        363 * correct value.
        364 * @param {string} name The name of the method being called.
        365 * @param {Array} args The arguments to the method.
        366 * @return {*} The return expected by the mock.
        367 * @protected
        368 */
        369goog.testing.Mock.prototype.$recordCall = function(name, args) {
        370 return undefined;
        371};
        372
        373
        374/**
        375 * If the expectation expects to throw, this method will throw.
        376 * @param {goog.testing.MockExpectation} expectation The expectation.
        377 */
        378goog.testing.Mock.prototype.$maybeThrow = function(expectation) {
        379 if (typeof expectation.exceptionToThrow != 'undefined') {
        380 throw expectation.exceptionToThrow;
        381 }
        382};
        383
        384
        385/**
        386 * If this expectation defines a function to be called,
        387 * it will be called and its result will be returned.
        388 * Otherwise, if the expectation expects to throw, it will throw.
        389 * Otherwise, this method will return defined value.
        390 * @param {goog.testing.MockExpectation} expectation The expectation.
        391 * @param {Array} args The arguments to the method.
        392 * @return {*} The return value expected by the mock.
        393 */
        394goog.testing.Mock.prototype.$do = function(expectation, args) {
        395 if (typeof expectation.toDo == 'undefined') {
        396 this.$maybeThrow(expectation);
        397 return expectation.returnValue;
        398 } else {
        399 return expectation.toDo.apply(this, args);
        400 }
        401};
        402
        403
        404/**
        405 * Specifies a return value for the currently pending expectation.
        406 * @param {*} val The return value.
        407 * @return {!goog.testing.Mock} This mock object.
        408 */
        409goog.testing.Mock.prototype.$returns = function(val) {
        410 this.$pendingExpectation.returnValue = val;
        411 return this;
        412};
        413
        414
        415/**
        416 * Specifies a value for the currently pending expectation to throw.
        417 * @param {*} val The value to throw.
        418 * @return {!goog.testing.Mock} This mock object.
        419 */
        420goog.testing.Mock.prototype.$throws = function(val) {
        421 this.$pendingExpectation.exceptionToThrow = val;
        422 return this;
        423};
        424
        425
        426/**
        427 * Specifies a function to call for currently pending expectation.
        428 * Note, that using this method overrides declarations made
        429 * using $returns() and $throws() methods.
        430 * @param {Function} func The function to call.
        431 * @return {!goog.testing.Mock} This mock object.
        432 */
        433goog.testing.Mock.prototype.$does = function(func) {
        434 this.$pendingExpectation.toDo = func;
        435 return this;
        436};
        437
        438
        439/**
        440 * Allows the expectation to be called 0 or 1 times.
        441 * @return {!goog.testing.Mock} This mock object.
        442 */
        443goog.testing.Mock.prototype.$atMostOnce = function() {
        444 this.$pendingExpectation.minCalls = 0;
        445 this.$pendingExpectation.maxCalls = 1;
        446 return this;
        447};
        448
        449
        450/**
        451 * Allows the expectation to be called any number of times, as long as it's
        452 * called once.
        453 * @return {!goog.testing.Mock} This mock object.
        454 */
        455goog.testing.Mock.prototype.$atLeastOnce = function() {
        456 this.$pendingExpectation.maxCalls = Infinity;
        457 return this;
        458};
        459
        460
        461/**
        462 * Allows the expectation to be called exactly once.
        463 * @return {!goog.testing.Mock} This mock object.
        464 */
        465goog.testing.Mock.prototype.$once = function() {
        466 this.$pendingExpectation.minCalls = 1;
        467 this.$pendingExpectation.maxCalls = 1;
        468 return this;
        469};
        470
        471
        472/**
        473 * Disallows the expectation from being called.
        474 * @return {!goog.testing.Mock} This mock object.
        475 */
        476goog.testing.Mock.prototype.$never = function() {
        477 this.$pendingExpectation.minCalls = 0;
        478 this.$pendingExpectation.maxCalls = 0;
        479 return this;
        480};
        481
        482
        483/**
        484 * Allows the expectation to be called any number of times.
        485 * @return {!goog.testing.Mock} This mock object.
        486 */
        487goog.testing.Mock.prototype.$anyTimes = function() {
        488 this.$pendingExpectation.minCalls = 0;
        489 this.$pendingExpectation.maxCalls = Infinity;
        490 return this;
        491};
        492
        493
        494/**
        495 * Specifies the number of times the expectation should be called.
        496 * @param {number} times The number of times this method will be called.
        497 * @return {!goog.testing.Mock} This mock object.
        498 */
        499goog.testing.Mock.prototype.$times = function(times) {
        500 this.$pendingExpectation.minCalls = times;
        501 this.$pendingExpectation.maxCalls = times;
        502 return this;
        503};
        504
        505
        506/**
        507 * Switches from recording to replay mode.
        508 * @override
        509 */
        510goog.testing.Mock.prototype.$replay = function() {
        511 this.$recording_ = false;
        512};
        513
        514
        515/**
        516 * Resets the state of this mock object. This clears all pending expectations
        517 * without verifying, and puts the mock in recording mode.
        518 * @override
        519 */
        520goog.testing.Mock.prototype.$reset = function() {
        521 this.$recording_ = true;
        522 this.$threwException_ = null;
        523 delete this.$pendingExpectation;
        524};
        525
        526
        527/**
        528 * Throws an exception and records that an exception was thrown.
        529 * @param {string} comment A short comment about the exception.
        530 * @param {?string=} opt_message A longer message about the exception.
        531 * @throws {Object} JsUnitException object.
        532 * @protected
        533 */
        534goog.testing.Mock.prototype.$throwException = function(comment, opt_message) {
        535 this.$recordAndThrow(new goog.testing.JsUnitException(comment, opt_message));
        536};
        537
        538
        539/**
        540 * Throws an exception and records that an exception was thrown.
        541 * @param {Object} ex Exception.
        542 * @throws {Object} #ex.
        543 * @protected
        544 */
        545goog.testing.Mock.prototype.$recordAndThrow = function(ex) {
        546 // If it's an assert exception, record it.
        547 if (ex['isJsUnitException']) {
        548 var testRunner = goog.global['G_testRunner'];
        549 if (testRunner) {
        550 var logTestFailureFunction = testRunner['logTestFailure'];
        551 if (logTestFailureFunction) {
        552 logTestFailureFunction.call(testRunner, ex);
        553 }
        554 }
        555
        556 if (!this.$threwException_) {
        557 // Only remember first exception thrown.
        558 this.$threwException_ = ex;
        559 }
        560 }
        561 throw ex;
        562};
        563
        564
        565/**
        566 * Verify that all of the expectations were met. Should be overridden by
        567 * subclasses.
        568 * @override
        569 */
        570goog.testing.Mock.prototype.$verify = function() {
        571 if (this.$threwException_) {
        572 throw this.$threwException_;
        573 }
        574};
        575
        576
        577/**
        578 * Verifies that a method call matches an expectation.
        579 * @param {goog.testing.MockExpectation} expectation The expectation to check.
        580 * @param {string} name The name of the called method.
        581 * @param {Array.<*>?} args The arguments passed to the mock.
        582 * @return {boolean} Whether the call matches the expectation.
        583 */
        584goog.testing.Mock.prototype.$verifyCall = function(expectation, name, args) {
        585 if (expectation.name != name) {
        586 return false;
        587 }
        588 var verifierFn =
        589 this.$argumentListVerifiers_.hasOwnProperty(expectation.name) ?
        590 this.$argumentListVerifiers_[expectation.name] :
        591 goog.testing.mockmatchers.flexibleArrayMatcher;
        592
        593 return verifierFn(expectation.argumentList, args, expectation);
        594};
        595
        596
        597/**
        598 * Render the provided argument array to a string to help
        599 * clients with debugging tests.
        600 * @param {Array.<*>?} args The arguments passed to the mock.
        601 * @return {string} Human-readable string.
        602 */
        603goog.testing.Mock.prototype.$argumentsAsString = function(args) {
        604 var retVal = [];
        605 for (var i = 0; i < args.length; i++) {
        606 try {
        607 retVal.push(goog.typeOf(args[i]));
        608 } catch (e) {
        609 retVal.push('[unknown]');
        610 }
        611 }
        612 return '(' + retVal.join(', ') + ')';
        613};
        614
        615
        616/**
        617 * Throw an exception based on an incorrect method call.
        618 * @param {string} name Name of method called.
        619 * @param {Array.<*>?} args Arguments passed to the mock.
        620 * @param {goog.testing.MockExpectation=} opt_expectation Expected next call,
        621 * if any.
        622 */
        623goog.testing.Mock.prototype.$throwCallException = function(name, args,
        624 opt_expectation) {
        625 var errorStringBuffer = [];
        626 var actualArgsString = this.$argumentsAsString(args);
        627 var expectedArgsString = opt_expectation ?
        628 this.$argumentsAsString(opt_expectation.argumentList) : '';
        629
        630 if (opt_expectation && opt_expectation.name == name) {
        631 errorStringBuffer.push('Bad arguments to ', name, '().\n',
        632 'Actual: ', actualArgsString, '\n',
        633 'Expected: ', expectedArgsString, '\n',
        634 opt_expectation.getErrorMessage());
        635 } else {
        636 errorStringBuffer.push('Unexpected call to ', name,
        637 actualArgsString, '.');
        638 if (opt_expectation) {
        639 errorStringBuffer.push('\nNext expected call was to ',
        640 opt_expectation.name,
        641 expectedArgsString);
        642 }
        643 }
        644 this.$throwException(errorStringBuffer.join(''));
        645};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/mockclock.js.src.html b/docs/api/javascript/source/lib/goog/testing/mockclock.js.src.html new file mode 100644 index 0000000000000..e81c49b9744bb --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/mockclock.js.src.html @@ -0,0 +1 @@ +mockclock.js

        lib/goog/testing/mockclock.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 Mock Clock implementation for working with setTimeout,
        17 * setInterval, clearTimeout and clearInterval within unit tests.
        18 *
        19 * Derived from jsUnitMockTimeout.js, contributed to JsUnit by
        20 * Pivotal Computer Systems, www.pivotalsf.com
        21 *
        22 */
        23
        24goog.provide('goog.testing.MockClock');
        25
        26goog.require('goog.Disposable');
        27goog.require('goog.async.run');
        28goog.require('goog.testing.PropertyReplacer');
        29goog.require('goog.testing.events');
        30goog.require('goog.testing.events.Event');
        31goog.require('goog.testing.watchers');
        32
        33
        34
        35/**
        36 * Class for unit testing code that uses setTimeout and clearTimeout.
        37 *
        38 * NOTE: If you are using MockClock to test code that makes use of
        39 * goog.fx.Animation, then you must either:
        40 *
        41 * 1. Install and dispose of the MockClock in setUpPage() and tearDownPage()
        42 * respectively (rather than setUp()/tearDown()).
        43 *
        44 * or
        45 *
        46 * 2. Ensure that every test clears the animation queue by calling
        47 * mockClock.tick(x) at the end of each test function (where `x` is large
        48 * enough to complete all animations).
        49 *
        50 * Otherwise, if any animation is left pending at the time that
        51 * MockClock.dispose() is called, that will permanently prevent any future
        52 * animations from playing on the page.
        53 *
        54 * @param {boolean=} opt_autoInstall Install the MockClock at construction time.
        55 * @constructor
        56 * @extends {goog.Disposable}
        57 * @final
        58 */
        59goog.testing.MockClock = function(opt_autoInstall) {
        60 goog.Disposable.call(this);
        61
        62 /**
        63 * Reverse-order queue of timers to fire.
        64 *
        65 * The last item of the queue is popped off. Insertion happens from the
        66 * right. For example, the expiration times for each element of the queue
        67 * might be in the order 300, 200, 200.
        68 *
        69 * @type {Array.<Object>}
        70 * @private
        71 */
        72 this.queue_ = [];
        73
        74 /**
        75 * Set of timeouts that should be treated as cancelled.
        76 *
        77 * Rather than removing cancelled timers directly from the queue, this set
        78 * simply marks them as deleted so that they can be ignored when their
        79 * turn comes up. The keys are the timeout keys that are cancelled, each
        80 * mapping to true.
        81 *
        82 * @type {Object}
        83 * @private
        84 */
        85 this.deletedKeys_ = {};
        86
        87 if (opt_autoInstall) {
        88 this.install();
        89 }
        90};
        91goog.inherits(goog.testing.MockClock, goog.Disposable);
        92
        93
        94/**
        95 * Default wait timeout for mocking requestAnimationFrame (in milliseconds).
        96 *
        97 * @type {number}
        98 * @const
        99 */
        100goog.testing.MockClock.REQUEST_ANIMATION_FRAME_TIMEOUT = 20;
        101
        102
        103/**
        104 * Count of the number of timeouts made.
        105 * @type {number}
        106 * @private
        107 */
        108goog.testing.MockClock.prototype.timeoutsMade_ = 0;
        109
        110
        111/**
        112 * PropertyReplacer instance which overwrites and resets setTimeout,
        113 * setInterval, etc. or null if the MockClock is not installed.
        114 * @type {goog.testing.PropertyReplacer}
        115 * @private
        116 */
        117goog.testing.MockClock.prototype.replacer_ = null;
        118
        119
        120/**
        121 * Map of deleted keys. These keys represents keys that were deleted in a
        122 * clearInterval, timeoutid -> object.
        123 * @type {Object}
        124 * @private
        125 */
        126goog.testing.MockClock.prototype.deletedKeys_ = null;
        127
        128
        129/**
        130 * The current simulated time in milliseconds.
        131 * @type {number}
        132 * @private
        133 */
        134goog.testing.MockClock.prototype.nowMillis_ = 0;
        135
        136
        137/**
        138 * Additional delay between the time a timeout was set to fire, and the time
        139 * it actually fires. Useful for testing workarounds for this Firefox 2 bug:
        140 * https://bugzilla.mozilla.org/show_bug.cgi?id=291386
        141 * May be negative.
        142 * @type {number}
        143 * @private
        144 */
        145goog.testing.MockClock.prototype.timeoutDelay_ = 0;
        146
        147
        148/**
        149 * Installs the MockClock by overriding the global object's implementation of
        150 * setTimeout, setInterval, clearTimeout and clearInterval.
        151 */
        152goog.testing.MockClock.prototype.install = function() {
        153 if (!this.replacer_) {
        154 var r = this.replacer_ = new goog.testing.PropertyReplacer();
        155 r.set(goog.global, 'setTimeout', goog.bind(this.setTimeout_, this));
        156 r.set(goog.global, 'setInterval', goog.bind(this.setInterval_, this));
        157 r.set(goog.global, 'setImmediate', goog.bind(this.setImmediate_, this));
        158 r.set(goog.global, 'clearTimeout', goog.bind(this.clearTimeout_, this));
        159 r.set(goog.global, 'clearInterval', goog.bind(this.clearInterval_, this));
        160 // goog.Promise uses goog.async.run. In order to be able to test
        161 // Promise-based code, we need to make sure that goog.async.run uses
        162 // nextTick instead of native browser Promises. This means that it will
        163 // default to setImmediate, which is replaced above. Note that we test for
        164 // the presence of goog.async.run.forceNextTick to be resilient to the case
        165 // where tests replace goog.async.run directly.
        166 goog.async.run.forceNextTick && goog.async.run.forceNextTick();
        167
        168 // Replace the requestAnimationFrame functions.
        169 this.replaceRequestAnimationFrame_();
        170
        171 // PropertyReplacer#set can't be called with renameable functions.
        172 this.oldGoogNow_ = goog.now;
        173 goog.now = goog.bind(this.getCurrentTime, this);
        174 }
        175};
        176
        177
        178/**
        179 * Installs the mocks for requestAnimationFrame and cancelRequestAnimationFrame.
        180 * @private
        181 */
        182goog.testing.MockClock.prototype.replaceRequestAnimationFrame_ = function() {
        183 var r = this.replacer_;
        184 var requestFuncs = ['requestAnimationFrame',
        185 'webkitRequestAnimationFrame',
        186 'mozRequestAnimationFrame',
        187 'oRequestAnimationFrame',
        188 'msRequestAnimationFrame'];
        189
        190 var cancelFuncs = ['cancelRequestAnimationFrame',
        191 'webkitCancelRequestAnimationFrame',
        192 'mozCancelRequestAnimationFrame',
        193 'oCancelRequestAnimationFrame',
        194 'msCancelRequestAnimationFrame'];
        195
        196 for (var i = 0; i < requestFuncs.length; ++i) {
        197 if (goog.global && goog.global[requestFuncs[i]]) {
        198 r.set(goog.global, requestFuncs[i],
        199 goog.bind(this.requestAnimationFrame_, this));
        200 }
        201 }
        202
        203 for (var i = 0; i < cancelFuncs.length; ++i) {
        204 if (goog.global && goog.global[cancelFuncs[i]]) {
        205 r.set(goog.global, cancelFuncs[i],
        206 goog.bind(this.cancelRequestAnimationFrame_, this));
        207 }
        208 }
        209};
        210
        211
        212/**
        213 * Removes the MockClock's hooks into the global object's functions and revert
        214 * to their original values.
        215 */
        216goog.testing.MockClock.prototype.uninstall = function() {
        217 if (this.replacer_) {
        218 this.replacer_.reset();
        219 this.replacer_ = null;
        220 goog.now = this.oldGoogNow_;
        221 }
        222
        223 this.fireResetEvent();
        224};
        225
        226
        227/** @override */
        228goog.testing.MockClock.prototype.disposeInternal = function() {
        229 this.uninstall();
        230 this.queue_ = null;
        231 this.deletedKeys_ = null;
        232 goog.testing.MockClock.superClass_.disposeInternal.call(this);
        233};
        234
        235
        236/**
        237 * Resets the MockClock, removing all timeouts that are scheduled and resets
        238 * the fake timer count.
        239 */
        240goog.testing.MockClock.prototype.reset = function() {
        241 this.queue_ = [];
        242 this.deletedKeys_ = {};
        243 this.nowMillis_ = 0;
        244 this.timeoutsMade_ = 0;
        245 this.timeoutDelay_ = 0;
        246
        247 this.fireResetEvent();
        248};
        249
        250
        251/**
        252 * Signals that the mock clock has been reset, allowing objects that
        253 * maintain their own internal state to reset.
        254 */
        255goog.testing.MockClock.prototype.fireResetEvent = function() {
        256 goog.testing.watchers.signalClockReset();
        257};
        258
        259
        260/**
        261 * Sets the amount of time between when a timeout is scheduled to fire and when
        262 * it actually fires.
        263 * @param {number} delay The delay in milliseconds. May be negative.
        264 */
        265goog.testing.MockClock.prototype.setTimeoutDelay = function(delay) {
        266 this.timeoutDelay_ = delay;
        267};
        268
        269
        270/**
        271 * @return {number} delay The amount of time between when a timeout is
        272 * scheduled to fire and when it actually fires, in milliseconds. May
        273 * be negative.
        274 */
        275goog.testing.MockClock.prototype.getTimeoutDelay = function() {
        276 return this.timeoutDelay_;
        277};
        278
        279
        280/**
        281 * Increments the MockClock's time by a given number of milliseconds, running
        282 * any functions that are now overdue.
        283 * @param {number=} opt_millis Number of milliseconds to increment the counter.
        284 * If not specified, clock ticks 1 millisecond.
        285 * @return {number} Current mock time in milliseconds.
        286 */
        287goog.testing.MockClock.prototype.tick = function(opt_millis) {
        288 if (typeof opt_millis != 'number') {
        289 opt_millis = 1;
        290 }
        291 var endTime = this.nowMillis_ + opt_millis;
        292 this.runFunctionsWithinRange_(endTime);
        293 this.nowMillis_ = endTime;
        294 return endTime;
        295};
        296
        297
        298/**
        299 * @return {number} The number of timeouts that have been scheduled.
        300 */
        301goog.testing.MockClock.prototype.getTimeoutsMade = function() {
        302 return this.timeoutsMade_;
        303};
        304
        305
        306/**
        307 * @return {number} The MockClock's current time in milliseconds.
        308 */
        309goog.testing.MockClock.prototype.getCurrentTime = function() {
        310 return this.nowMillis_;
        311};
        312
        313
        314/**
        315 * @param {number} timeoutKey The timeout key.
        316 * @return {boolean} Whether the timer has been set and not cleared,
        317 * independent of the timeout's expiration. In other words, the timeout
        318 * could have passed or could be scheduled for the future. Either way,
        319 * this function returns true or false depending only on whether the
        320 * provided timeoutKey represents a timeout that has been set and not
        321 * cleared.
        322 */
        323goog.testing.MockClock.prototype.isTimeoutSet = function(timeoutKey) {
        324 return timeoutKey <= this.timeoutsMade_ && !this.deletedKeys_[timeoutKey];
        325};
        326
        327
        328/**
        329 * Runs any function that is scheduled before a certain time. Timeouts can
        330 * be made to fire early or late if timeoutDelay_ is non-0.
        331 * @param {number} endTime The latest time in the range, in milliseconds.
        332 * @private
        333 */
        334goog.testing.MockClock.prototype.runFunctionsWithinRange_ = function(
        335 endTime) {
        336 var adjustedEndTime = endTime - this.timeoutDelay_;
        337
        338 // Repeatedly pop off the last item since the queue is always sorted.
        339 while (this.queue_ && this.queue_.length &&
        340 this.queue_[this.queue_.length - 1].runAtMillis <= adjustedEndTime) {
        341 var timeout = this.queue_.pop();
        342
        343 if (!(timeout.timeoutKey in this.deletedKeys_)) {
        344 // Only move time forwards.
        345 this.nowMillis_ = Math.max(this.nowMillis_,
        346 timeout.runAtMillis + this.timeoutDelay_);
        347 // Call timeout in global scope and pass the timeout key as the argument.
        348 timeout.funcToCall.call(goog.global, timeout.timeoutKey);
        349 // In case the interval was cleared in the funcToCall
        350 if (timeout.recurring) {
        351 this.scheduleFunction_(
        352 timeout.timeoutKey, timeout.funcToCall, timeout.millis, true);
        353 }
        354 }
        355 }
        356};
        357
        358
        359/**
        360 * Schedules a function to be run at a certain time.
        361 * @param {number} timeoutKey The timeout key.
        362 * @param {Function} funcToCall The function to call.
        363 * @param {number} millis The number of milliseconds to call it in.
        364 * @param {boolean} recurring Whether to function call should recur.
        365 * @private
        366 */
        367goog.testing.MockClock.prototype.scheduleFunction_ = function(
        368 timeoutKey, funcToCall, millis, recurring) {
        369 if (!goog.isFunction(funcToCall)) {
        370 // Early error for debuggability rather than dying in the next .tick()
        371 throw new TypeError('The provided callback must be a function, not a ' +
        372 typeof funcToCall);
        373 }
        374
        375 var timeout = {
        376 runAtMillis: this.nowMillis_ + millis,
        377 funcToCall: funcToCall,
        378 recurring: recurring,
        379 timeoutKey: timeoutKey,
        380 millis: millis
        381 };
        382
        383 goog.testing.MockClock.insert_(timeout, this.queue_);
        384};
        385
        386
        387/**
        388 * Inserts a timer descriptor into a descending-order queue.
        389 *
        390 * Later-inserted duplicates appear at lower indices. For example, the
        391 * asterisk in (5,4,*,3,2,1) would be the insertion point for 3.
        392 *
        393 * @param {Object} timeout The timeout to insert, with numerical runAtMillis
        394 * property.
        395 * @param {Array.<Object>} queue The queue to insert into, with each element
        396 * having a numerical runAtMillis property.
        397 * @private
        398 */
        399goog.testing.MockClock.insert_ = function(timeout, queue) {
        400 // Although insertion of N items is quadratic, requiring goog.structs.Heap
        401 // from a unit test will make tests more prone to breakage. Since unit
        402 // tests are normally small, scalability is not a primary issue.
        403
        404 // Find an insertion point. Since the queue is in reverse order (so we
        405 // can pop rather than unshift), and later timers with the same time stamp
        406 // should be executed later, we look for the element strictly greater than
        407 // the one we are inserting.
        408
        409 for (var i = queue.length; i != 0; i--) {
        410 if (queue[i - 1].runAtMillis > timeout.runAtMillis) {
        411 break;
        412 }
        413 queue[i] = queue[i - 1];
        414 }
        415
        416 queue[i] = timeout;
        417};
        418
        419
        420/**
        421 * Maximum 32-bit signed integer.
        422 *
        423 * Timeouts over this time return immediately in many browsers, due to integer
        424 * overflow. Such known browsers include Firefox, Chrome, and Safari, but not
        425 * IE.
        426 *
        427 * @type {number}
        428 * @private
        429 */
        430goog.testing.MockClock.MAX_INT_ = 2147483647;
        431
        432
        433/**
        434 * Schedules a function to be called after {@code millis} milliseconds.
        435 * Mock implementation for setTimeout.
        436 * @param {Function} funcToCall The function to call.
        437 * @param {number} millis The number of milliseconds to call it after.
        438 * @return {number} The number of timeouts created.
        439 * @private
        440 */
        441goog.testing.MockClock.prototype.setTimeout_ = function(funcToCall, millis) {
        442 if (millis > goog.testing.MockClock.MAX_INT_) {
        443 throw Error(
        444 'Bad timeout value: ' + millis + '. Timeouts over MAX_INT ' +
        445 '(24.8 days) cause timeouts to be fired ' +
        446 'immediately in most browsers, except for IE.');
        447 }
        448 this.timeoutsMade_ = this.timeoutsMade_ + 1;
        449 this.scheduleFunction_(this.timeoutsMade_, funcToCall, millis, false);
        450 return this.timeoutsMade_;
        451};
        452
        453
        454/**
        455 * Schedules a function to be called every {@code millis} milliseconds.
        456 * Mock implementation for setInterval.
        457 * @param {Function} funcToCall The function to call.
        458 * @param {number} millis The number of milliseconds between calls.
        459 * @return {number} The number of timeouts created.
        460 * @private
        461 */
        462goog.testing.MockClock.prototype.setInterval_ = function(funcToCall, millis) {
        463 this.timeoutsMade_ = this.timeoutsMade_ + 1;
        464 this.scheduleFunction_(this.timeoutsMade_, funcToCall, millis, true);
        465 return this.timeoutsMade_;
        466};
        467
        468
        469/**
        470 * Schedules a function to be called when an animation frame is triggered.
        471 * Mock implementation for requestAnimationFrame.
        472 * @param {Function} funcToCall The function to call.
        473 * @return {number} The number of timeouts created.
        474 * @private
        475 */
        476goog.testing.MockClock.prototype.requestAnimationFrame_ = function(funcToCall) {
        477 return this.setTimeout_(goog.bind(function() {
        478 if (funcToCall) {
        479 funcToCall(this.getCurrentTime());
        480 } else if (goog.global.mozRequestAnimationFrame) {
        481 var event = new goog.testing.events.Event('MozBeforePaint', goog.global);
        482 event['timeStamp'] = this.getCurrentTime();
        483 goog.testing.events.fireBrowserEvent(event);
        484 }
        485 }, this), goog.testing.MockClock.REQUEST_ANIMATION_FRAME_TIMEOUT);
        486};
        487
        488
        489/**
        490 * Schedules a function to be called immediately after the current JS
        491 * execution.
        492 * Mock implementation for setImmediate.
        493 * @param {Function} funcToCall The function to call.
        494 * @return {number} The number of timeouts created.
        495 * @private
        496 */
        497goog.testing.MockClock.prototype.setImmediate_ = function(funcToCall) {
        498 return this.setTimeout_(funcToCall, 0);
        499};
        500
        501
        502/**
        503 * Clears a timeout.
        504 * Mock implementation for clearTimeout.
        505 * @param {number} timeoutKey The timeout key to clear.
        506 * @private
        507 */
        508goog.testing.MockClock.prototype.clearTimeout_ = function(timeoutKey) {
        509 // Some common libraries register static state with timers.
        510 // This is bad. It leads to all sorts of crazy test problems where
        511 // 1) Test A sets up a new mock clock and a static timer.
        512 // 2) Test B sets up a new mock clock, but re-uses the static timer
        513 // from Test A.
        514 // 3) A timeout key from test A gets cleared, breaking a timeout in
        515 // Test B.
        516 //
        517 // For now, we just hackily fail silently if someone tries to clear a timeout
        518 // key before we've allocated it.
        519 // Ideally, we should throw an exception if we see this happening.
        520 //
        521 // TODO(user): We might also try allocating timeout ids from a global
        522 // pool rather than a local pool.
        523 if (this.isTimeoutSet(timeoutKey)) {
        524 this.deletedKeys_[timeoutKey] = true;
        525 }
        526};
        527
        528
        529/**
        530 * Clears an interval.
        531 * Mock implementation for clearInterval.
        532 * @param {number} timeoutKey The interval key to clear.
        533 * @private
        534 */
        535goog.testing.MockClock.prototype.clearInterval_ = function(timeoutKey) {
        536 this.clearTimeout_(timeoutKey);
        537};
        538
        539
        540/**
        541 * Clears a requestAnimationFrame.
        542 * Mock implementation for cancelRequestAnimationFrame.
        543 * @param {number} timeoutKey The requestAnimationFrame key to clear.
        544 * @private
        545 */
        546goog.testing.MockClock.prototype.cancelRequestAnimationFrame_ =
        547 function(timeoutKey) {
        548 this.clearTimeout_(timeoutKey);
        549};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/mockcontrol.js.src.html b/docs/api/javascript/source/lib/goog/testing/mockcontrol.js.src.html new file mode 100644 index 0000000000000..966951f980381 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/mockcontrol.js.src.html @@ -0,0 +1 @@ +mockcontrol.js

        lib/goog/testing/mockcontrol.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 A MockControl holds a set of mocks for a particular test.
        17 * It consolidates calls to $replay, $verify, and $tearDown, which simplifies
        18 * the test and helps avoid omissions.
        19 *
        20 * You can create and control a mock:
        21 * var mockFoo = mockControl.addMock(new MyMock(Foo));
        22 *
        23 * MockControl also exposes some convenience functions that create
        24 * controlled mocks for common mocks: StrictMock, LooseMock,
        25 * FunctionMock, MethodMock, and GlobalFunctionMock.
        26 *
        27 */
        28
        29
        30goog.provide('goog.testing.MockControl');
        31
        32goog.require('goog.array');
        33goog.require('goog.testing');
        34goog.require('goog.testing.LooseMock');
        35goog.require('goog.testing.StrictMock');
        36
        37
        38
        39/**
        40 * Controls a set of mocks. Controlled mocks are replayed, verified, and
        41 * cleaned-up at the same time.
        42 * @constructor
        43 */
        44goog.testing.MockControl = function() {
        45 /**
        46 * The list of mocks being controlled.
        47 * @type {Array.<goog.testing.MockInterface>}
        48 * @private
        49 */
        50 this.mocks_ = [];
        51};
        52
        53
        54/**
        55 * Takes control of this mock.
        56 * @param {goog.testing.MockInterface} mock Mock to be controlled.
        57 * @return {goog.testing.MockInterface} The same mock passed in,
        58 * for convenience.
        59 */
        60goog.testing.MockControl.prototype.addMock = function(mock) {
        61 this.mocks_.push(mock);
        62 return mock;
        63};
        64
        65
        66/**
        67 * Calls replay on each controlled mock.
        68 */
        69goog.testing.MockControl.prototype.$replayAll = function() {
        70 goog.array.forEach(this.mocks_, function(m) {
        71 m.$replay();
        72 });
        73};
        74
        75
        76/**
        77 * Calls reset on each controlled mock.
        78 */
        79goog.testing.MockControl.prototype.$resetAll = function() {
        80 goog.array.forEach(this.mocks_, function(m) {
        81 m.$reset();
        82 });
        83};
        84
        85
        86/**
        87 * Calls verify on each controlled mock.
        88 */
        89goog.testing.MockControl.prototype.$verifyAll = function() {
        90 goog.array.forEach(this.mocks_, function(m) {
        91 m.$verify();
        92 });
        93};
        94
        95
        96/**
        97 * Calls tearDown on each controlled mock, if necesssary.
        98 */
        99goog.testing.MockControl.prototype.$tearDown = function() {
        100 goog.array.forEach(this.mocks_, function(m) {
        101 // $tearDown if defined.
        102 if (m.$tearDown) {
        103 m.$tearDown();
        104 }
        105 // TODO(user): Somehow determine if verifyAll should have been called
        106 // but was not.
        107 });
        108};
        109
        110
        111/**
        112 * Creates a controlled StrictMock. Passes its arguments through to the
        113 * StrictMock constructor.
        114 * @param {Object|Function} objectToMock The object that should be mocked, or
        115 * the constructor of an object to mock.
        116 * @param {boolean=} opt_mockStaticMethods An optional argument denoting that
        117 * a mock should be constructed from the static functions of a class.
        118 * @param {boolean=} opt_createProxy An optional argument denoting that
        119 * a proxy for the target mock should be created.
        120 * @return {!goog.testing.StrictMock} The mock object.
        121 */
        122goog.testing.MockControl.prototype.createStrictMock = function(
        123 objectToMock, opt_mockStaticMethods, opt_createProxy) {
        124 var m = new goog.testing.StrictMock(objectToMock, opt_mockStaticMethods,
        125 opt_createProxy);
        126 this.addMock(m);
        127 return m;
        128};
        129
        130
        131/**
        132 * Creates a controlled LooseMock. Passes its arguments through to the
        133 * LooseMock constructor.
        134 * @param {Object|Function} objectToMock The object that should be mocked, or
        135 * the constructor of an object to mock.
        136 * @param {boolean=} opt_ignoreUnexpectedCalls Whether to ignore unexpected
        137 * calls.
        138 * @param {boolean=} opt_mockStaticMethods An optional argument denoting that
        139 * a mock should be constructed from the static functions of a class.
        140 * @param {boolean=} opt_createProxy An optional argument denoting that
        141 * a proxy for the target mock should be created.
        142 * @return {!goog.testing.LooseMock} The mock object.
        143 */
        144goog.testing.MockControl.prototype.createLooseMock = function(
        145 objectToMock, opt_ignoreUnexpectedCalls,
        146 opt_mockStaticMethods, opt_createProxy) {
        147 var m = new goog.testing.LooseMock(objectToMock, opt_ignoreUnexpectedCalls,
        148 opt_mockStaticMethods, opt_createProxy);
        149 this.addMock(m);
        150 return m;
        151};
        152
        153
        154/**
        155 * Creates a controlled FunctionMock. Passes its arguments through to the
        156 * FunctionMock constructor.
        157 * @param {string=} opt_functionName The optional name of the function to mock
        158 * set to '[anonymous mocked function]' if not passed in.
        159 * @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or
        160 * goog.testing.Mock.STRICT. The default is STRICT.
        161 * @return {goog.testing.MockInterface} The mocked function.
        162 */
        163goog.testing.MockControl.prototype.createFunctionMock = function(
        164 opt_functionName, opt_strictness) {
        165 var m = goog.testing.createFunctionMock(opt_functionName, opt_strictness);
        166 this.addMock(m);
        167 return m;
        168};
        169
        170
        171/**
        172 * Creates a controlled MethodMock. Passes its arguments through to the
        173 * MethodMock constructor.
        174 * @param {Object} scope The scope of the method to be mocked out.
        175 * @param {string} functionName The name of the function we're going to mock.
        176 * @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or
        177 * goog.testing.Mock.STRICT. The default is STRICT.
        178 * @return {!goog.testing.MockInterface} The mocked method.
        179 */
        180goog.testing.MockControl.prototype.createMethodMock = function(
        181 scope, functionName, opt_strictness) {
        182 var m = goog.testing.createMethodMock(scope, functionName, opt_strictness);
        183 this.addMock(m);
        184 return m;
        185};
        186
        187
        188/**
        189 * Creates a controlled MethodMock for a constructor. Passes its arguments
        190 * through to the MethodMock constructor. See
        191 * {@link goog.testing.createConstructorMock} for details.
        192 * @param {Object} scope The scope of the constructor to be mocked out.
        193 * @param {string} constructorName The name of the function we're going to mock.
        194 * @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or
        195 * goog.testing.Mock.STRICT. The default is STRICT.
        196 * @return {!goog.testing.MockInterface} The mocked method.
        197 */
        198goog.testing.MockControl.prototype.createConstructorMock = function(
        199 scope, constructorName, opt_strictness) {
        200 var m = goog.testing.createConstructorMock(scope, constructorName,
        201 opt_strictness);
        202 this.addMock(m);
        203 return m;
        204};
        205
        206
        207/**
        208 * Creates a controlled GlobalFunctionMock. Passes its arguments through to the
        209 * GlobalFunctionMock constructor.
        210 * @param {string} functionName The name of the function we're going to mock.
        211 * @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or
        212 * goog.testing.Mock.STRICT. The default is STRICT.
        213 * @return {goog.testing.MockInterface} The mocked function.
        214 */
        215goog.testing.MockControl.prototype.createGlobalFunctionMock = function(
        216 functionName, opt_strictness) {
        217 var m = goog.testing.createGlobalFunctionMock(functionName, opt_strictness);
        218 this.addMock(m);
        219 return m;
        220};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/mockinterface.js.src.html b/docs/api/javascript/source/lib/goog/testing/mockinterface.js.src.html new file mode 100644 index 0000000000000..e536030ab30dd --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/mockinterface.js.src.html @@ -0,0 +1 @@ +mockinterface.js

        lib/goog/testing/mockinterface.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 An interface that all mocks should share.
        17 * @author nicksantos@google.com (Nick Santos)
        18 */
        19
        20goog.provide('goog.testing.MockInterface');
        21
        22
        23
        24/** @interface */
        25goog.testing.MockInterface = function() {};
        26
        27
        28/**
        29 * Write down all the expected functions that have been called on the
        30 * mock so far. From here on out, future function calls will be
        31 * compared against this list.
        32 */
        33goog.testing.MockInterface.prototype.$replay = function() {};
        34
        35
        36/**
        37 * Reset the mock.
        38 */
        39goog.testing.MockInterface.prototype.$reset = function() {};
        40
        41
        42/**
        43 * Assert that the expected function calls match the actual calls.
        44 */
        45goog.testing.MockInterface.prototype.$verify = function() {};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/mockmatchers.js.src.html b/docs/api/javascript/source/lib/goog/testing/mockmatchers.js.src.html new file mode 100644 index 0000000000000..8d055a59a5540 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/mockmatchers.js.src.html @@ -0,0 +1 @@ +mockmatchers.js

        lib/goog/testing/mockmatchers.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 Matchers to be used with the mock utilities. They allow for
        17 * flexible matching by type. Custom matchers can be created by passing a
        18 * matcher function into an ArgumentMatcher instance.
        19 *
        20 * For examples, please see the unit test.
        21 *
        22 */
        23
        24
        25goog.provide('goog.testing.mockmatchers');
        26goog.provide('goog.testing.mockmatchers.ArgumentMatcher');
        27goog.provide('goog.testing.mockmatchers.IgnoreArgument');
        28goog.provide('goog.testing.mockmatchers.InstanceOf');
        29goog.provide('goog.testing.mockmatchers.ObjectEquals');
        30goog.provide('goog.testing.mockmatchers.RegexpMatch');
        31goog.provide('goog.testing.mockmatchers.SaveArgument');
        32goog.provide('goog.testing.mockmatchers.TypeOf');
        33
        34goog.require('goog.array');
        35goog.require('goog.dom');
        36goog.require('goog.testing.asserts');
        37
        38
        39
        40/**
        41 * A simple interface for executing argument matching. A match in this case is
        42 * testing to see if a supplied object fits a given criteria. True is returned
        43 * if the given criteria is met.
        44 * @param {Function=} opt_matchFn A function that evaluates a given argument
        45 * and returns true if it meets a given criteria.
        46 * @param {?string=} opt_matchName The name expressing intent as part of
        47 * an error message for when a match fails.
        48 * @constructor
        49 */
        50goog.testing.mockmatchers.ArgumentMatcher =
        51 function(opt_matchFn, opt_matchName) {
        52 /**
        53 * A function that evaluates a given argument and returns true if it meets a
        54 * given criteria.
        55 * @type {Function}
        56 * @private
        57 */
        58 this.matchFn_ = opt_matchFn || null;
        59
        60 /**
        61 * A string indicating the match intent (e.g. isBoolean or isString).
        62 * @type {?string}
        63 * @private
        64 */
        65 this.matchName_ = opt_matchName || null;
        66};
        67
        68
        69/**
        70 * A function that takes a match argument and an optional MockExpectation
        71 * which (if provided) will get error information and returns whether or
        72 * not it matches.
        73 * @param {*} toVerify The argument that should be verified.
        74 * @param {goog.testing.MockExpectation?=} opt_expectation The expectation
        75 * for this match.
        76 * @return {boolean} Whether or not a given argument passes verification.
        77 */
        78goog.testing.mockmatchers.ArgumentMatcher.prototype.matches =
        79 function(toVerify, opt_expectation) {
        80 if (this.matchFn_) {
        81 var isamatch = this.matchFn_(toVerify);
        82 if (!isamatch && opt_expectation) {
        83 if (this.matchName_) {
        84 opt_expectation.addErrorMessage('Expected: ' +
        85 this.matchName_ + ' but was: ' + _displayStringForValue(toVerify));
        86 } else {
        87 opt_expectation.addErrorMessage('Expected: missing mockmatcher' +
        88 ' description but was: ' +
        89 _displayStringForValue(toVerify));
        90 }
        91 }
        92 return isamatch;
        93 } else {
        94 throw Error('No match function defined for this mock matcher');
        95 }
        96};
        97
        98
        99
        100/**
        101 * A matcher that verifies that an argument is an instance of a given class.
        102 * @param {Function} ctor The class that will be used for verification.
        103 * @constructor
        104 * @extends {goog.testing.mockmatchers.ArgumentMatcher}
        105 * @final
        106 */
        107goog.testing.mockmatchers.InstanceOf = function(ctor) {
        108 goog.testing.mockmatchers.ArgumentMatcher.call(this,
        109 function(obj) {
        110 return obj instanceof ctor;
        111 // NOTE: Browser differences on ctor.toString() output
        112 // make using that here problematic. So for now, just let
        113 // people know the instanceOf() failed without providing
        114 // browser specific details...
        115 }, 'instanceOf()');
        116};
        117goog.inherits(goog.testing.mockmatchers.InstanceOf,
        118 goog.testing.mockmatchers.ArgumentMatcher);
        119
        120
        121
        122/**
        123 * A matcher that verifies that an argument is of a given type (e.g. "object").
        124 * @param {string} type The type that a given argument must have.
        125 * @constructor
        126 * @extends {goog.testing.mockmatchers.ArgumentMatcher}
        127 * @final
        128 */
        129goog.testing.mockmatchers.TypeOf = function(type) {
        130 goog.testing.mockmatchers.ArgumentMatcher.call(this,
        131 function(obj) {
        132 return goog.typeOf(obj) == type;
        133 }, 'typeOf(' + type + ')');
        134};
        135goog.inherits(goog.testing.mockmatchers.TypeOf,
        136 goog.testing.mockmatchers.ArgumentMatcher);
        137
        138
        139
        140/**
        141 * A matcher that verifies that an argument matches a given RegExp.
        142 * @param {RegExp} regexp The regular expression that the argument must match.
        143 * @constructor
        144 * @extends {goog.testing.mockmatchers.ArgumentMatcher}
        145 * @final
        146 */
        147goog.testing.mockmatchers.RegexpMatch = function(regexp) {
        148 goog.testing.mockmatchers.ArgumentMatcher.call(this,
        149 function(str) {
        150 return regexp.test(str);
        151 }, 'match(' + regexp + ')');
        152};
        153goog.inherits(goog.testing.mockmatchers.RegexpMatch,
        154 goog.testing.mockmatchers.ArgumentMatcher);
        155
        156
        157
        158/**
        159 * A matcher that always returns true. It is useful when the user does not care
        160 * for some arguments.
        161 * For example: mockFunction('username', 'password', IgnoreArgument);
        162 * @constructor
        163 * @extends {goog.testing.mockmatchers.ArgumentMatcher}
        164 * @final
        165 */
        166goog.testing.mockmatchers.IgnoreArgument = function() {
        167 goog.testing.mockmatchers.ArgumentMatcher.call(this,
        168 function() {
        169 return true;
        170 }, 'true');
        171};
        172goog.inherits(goog.testing.mockmatchers.IgnoreArgument,
        173 goog.testing.mockmatchers.ArgumentMatcher);
        174
        175
        176
        177/**
        178 * A matcher that verifies that the argument is an object that equals the given
        179 * expected object, using a deep comparison.
        180 * @param {Object} expectedObject An object to match against when
        181 * verifying the argument.
        182 * @constructor
        183 * @extends {goog.testing.mockmatchers.ArgumentMatcher}
        184 */
        185goog.testing.mockmatchers.ObjectEquals = function(expectedObject) {
        186 goog.testing.mockmatchers.ArgumentMatcher.call(this,
        187 function(matchObject) {
        188 assertObjectEquals('Expected equal objects', expectedObject,
        189 matchObject);
        190 return true;
        191 }, 'objectEquals(' + expectedObject + ')');
        192};
        193goog.inherits(goog.testing.mockmatchers.ObjectEquals,
        194 goog.testing.mockmatchers.ArgumentMatcher);
        195
        196
        197/** @override */
        198goog.testing.mockmatchers.ObjectEquals.prototype.matches =
        199 function(toVerify, opt_expectation) {
        200 // Override the default matches implementation to capture the exception thrown
        201 // by assertObjectEquals (if any) and add that message to the expectation.
        202 try {
        203 return goog.testing.mockmatchers.ObjectEquals.superClass_.matches.call(
        204 this, toVerify, opt_expectation);
        205 } catch (e) {
        206 if (opt_expectation) {
        207 opt_expectation.addErrorMessage(e.message);
        208 }
        209 return false;
        210 }
        211};
        212
        213
        214
        215/**
        216 * A matcher that saves the argument that it is verifying so that your unit test
        217 * can perform extra tests with this argument later. For example, if the
        218 * argument is a callback method, the unit test can then later call this
        219 * callback to test the asynchronous portion of the call.
        220 * @param {goog.testing.mockmatchers.ArgumentMatcher|Function=} opt_matcher
        221 * Argument matcher or matching function that will be used to validate the
        222 * argument. By default, argument will always be valid.
        223 * @param {?string=} opt_matchName The name expressing intent as part of
        224 * an error message for when a match fails.
        225 * @constructor
        226 * @extends {goog.testing.mockmatchers.ArgumentMatcher}
        227 * @final
        228 */
        229goog.testing.mockmatchers.SaveArgument = function(opt_matcher, opt_matchName) {
        230 goog.testing.mockmatchers.ArgumentMatcher.call(
        231 this, /** @type {Function} */ (opt_matcher), opt_matchName);
        232
        233 if (opt_matcher instanceof goog.testing.mockmatchers.ArgumentMatcher) {
        234 /**
        235 * Delegate match requests to this matcher.
        236 * @type {goog.testing.mockmatchers.ArgumentMatcher}
        237 * @private
        238 */
        239 this.delegateMatcher_ = opt_matcher;
        240 } else if (!opt_matcher) {
        241 this.delegateMatcher_ = goog.testing.mockmatchers.ignoreArgument;
        242 }
        243};
        244goog.inherits(goog.testing.mockmatchers.SaveArgument,
        245 goog.testing.mockmatchers.ArgumentMatcher);
        246
        247
        248/** @override */
        249goog.testing.mockmatchers.SaveArgument.prototype.matches = function(
        250 toVerify, opt_expectation) {
        251 this.arg = toVerify;
        252 if (this.delegateMatcher_) {
        253 return this.delegateMatcher_.matches(toVerify, opt_expectation);
        254 }
        255 return goog.testing.mockmatchers.SaveArgument.superClass_.matches.call(
        256 this, toVerify, opt_expectation);
        257};
        258
        259
        260/**
        261 * Saved argument that was verified.
        262 * @type {*}
        263 */
        264goog.testing.mockmatchers.SaveArgument.prototype.arg;
        265
        266
        267/**
        268 * An instance of the IgnoreArgument matcher. Returns true for all matches.
        269 * @type {goog.testing.mockmatchers.IgnoreArgument}
        270 */
        271goog.testing.mockmatchers.ignoreArgument =
        272 new goog.testing.mockmatchers.IgnoreArgument();
        273
        274
        275/**
        276 * A matcher that verifies that an argument is an array.
        277 * @type {goog.testing.mockmatchers.ArgumentMatcher}
        278 */
        279goog.testing.mockmatchers.isArray =
        280 new goog.testing.mockmatchers.ArgumentMatcher(goog.isArray,
        281 'isArray');
        282
        283
        284/**
        285 * A matcher that verifies that an argument is a array-like. A NodeList is an
        286 * example of a collection that is very close to an array.
        287 * @type {goog.testing.mockmatchers.ArgumentMatcher}
        288 */
        289goog.testing.mockmatchers.isArrayLike =
        290 new goog.testing.mockmatchers.ArgumentMatcher(goog.isArrayLike,
        291 'isArrayLike');
        292
        293
        294/**
        295 * A matcher that verifies that an argument is a date-like.
        296 * @type {goog.testing.mockmatchers.ArgumentMatcher}
        297 */
        298goog.testing.mockmatchers.isDateLike =
        299 new goog.testing.mockmatchers.ArgumentMatcher(goog.isDateLike,
        300 'isDateLike');
        301
        302
        303/**
        304 * A matcher that verifies that an argument is a string.
        305 * @type {goog.testing.mockmatchers.ArgumentMatcher}
        306 */
        307goog.testing.mockmatchers.isString =
        308 new goog.testing.mockmatchers.ArgumentMatcher(goog.isString,
        309 'isString');
        310
        311
        312/**
        313 * A matcher that verifies that an argument is a boolean.
        314 * @type {goog.testing.mockmatchers.ArgumentMatcher}
        315 */
        316goog.testing.mockmatchers.isBoolean =
        317 new goog.testing.mockmatchers.ArgumentMatcher(goog.isBoolean,
        318 'isBoolean');
        319
        320
        321/**
        322 * A matcher that verifies that an argument is a number.
        323 * @type {goog.testing.mockmatchers.ArgumentMatcher}
        324 */
        325goog.testing.mockmatchers.isNumber =
        326 new goog.testing.mockmatchers.ArgumentMatcher(goog.isNumber,
        327 'isNumber');
        328
        329
        330/**
        331 * A matcher that verifies that an argument is a function.
        332 * @type {goog.testing.mockmatchers.ArgumentMatcher}
        333 */
        334goog.testing.mockmatchers.isFunction =
        335 new goog.testing.mockmatchers.ArgumentMatcher(goog.isFunction,
        336 'isFunction');
        337
        338
        339/**
        340 * A matcher that verifies that an argument is an object.
        341 * @type {goog.testing.mockmatchers.ArgumentMatcher}
        342 */
        343goog.testing.mockmatchers.isObject =
        344 new goog.testing.mockmatchers.ArgumentMatcher(goog.isObject,
        345 'isObject');
        346
        347
        348/**
        349 * A matcher that verifies that an argument is like a DOM node.
        350 * @type {goog.testing.mockmatchers.ArgumentMatcher}
        351 */
        352goog.testing.mockmatchers.isNodeLike =
        353 new goog.testing.mockmatchers.ArgumentMatcher(goog.dom.isNodeLike,
        354 'isNodeLike');
        355
        356
        357/**
        358 * A function that checks to see if an array matches a given set of
        359 * expectations. The expectations array can be a mix of ArgumentMatcher
        360 * implementations and values. True will be returned if values are identical or
        361 * if a matcher returns a positive result.
        362 * @param {Array} expectedArr An array of expectations which can be either
        363 * values to check for equality or ArgumentMatchers.
        364 * @param {Array} arr The array to match.
        365 * @param {goog.testing.MockExpectation?=} opt_expectation The expectation
        366 * for this match.
        367 * @return {boolean} Whether or not the given array matches the expectations.
        368 */
        369goog.testing.mockmatchers.flexibleArrayMatcher =
        370 function(expectedArr, arr, opt_expectation) {
        371 return goog.array.equals(expectedArr, arr, function(a, b) {
        372 var errCount = 0;
        373 if (opt_expectation) {
        374 errCount = opt_expectation.getErrorMessageCount();
        375 }
        376 var isamatch = a === b ||
        377 a instanceof goog.testing.mockmatchers.ArgumentMatcher &&
        378 a.matches(b, opt_expectation);
        379 var failureMessage = null;
        380 if (!isamatch) {
        381 failureMessage = goog.testing.asserts.findDifferences(a, b);
        382 isamatch = !failureMessage;
        383 }
        384 if (!isamatch && opt_expectation) {
        385 // If the error count changed, the match sent out an error
        386 // message. If the error count has not changed, then
        387 // we need to send out an error message...
        388 if (errCount == opt_expectation.getErrorMessageCount()) {
        389 // Use the _displayStringForValue() from assert.js
        390 // for consistency...
        391 if (!failureMessage) {
        392 failureMessage = 'Expected: ' + _displayStringForValue(a) +
        393 ' but was: ' + _displayStringForValue(b);
        394 }
        395 opt_expectation.addErrorMessage(failureMessage);
        396 }
        397 }
        398 return isamatch;
        399 });
        400};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/objectpropertystring.js.src.html b/docs/api/javascript/source/lib/goog/testing/objectpropertystring.js.src.html new file mode 100644 index 0000000000000..6c949da174a5f --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/objectpropertystring.js.src.html @@ -0,0 +1 @@ +objectpropertystring.js

        lib/goog/testing/objectpropertystring.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 Helper for passing property names as string literals in
        17 * compiled test code.
        18 *
        19 */
        20
        21goog.provide('goog.testing.ObjectPropertyString');
        22
        23
        24
        25/**
        26 * Object to pass a property name as a string literal and its containing object
        27 * when the JSCompiler is rewriting these names. This should only be used in
        28 * test code.
        29 *
        30 * @param {Object} object The containing object.
        31 * @param {Object|string} propertyString Property name as a string literal.
        32 * @constructor
        33 * @final
        34 */
        35goog.testing.ObjectPropertyString = function(object, propertyString) {
        36 this.object_ = object;
        37 this.propertyString_ = /** @type {string} */ (propertyString);
        38};
        39
        40
        41/**
        42 * @type {Object}
        43 * @private
        44 */
        45goog.testing.ObjectPropertyString.prototype.object_;
        46
        47
        48/**
        49 * @type {string}
        50 * @private
        51 */
        52goog.testing.ObjectPropertyString.prototype.propertyString_;
        53
        54
        55/**
        56 * @return {Object} The object.
        57 */
        58goog.testing.ObjectPropertyString.prototype.getObject = function() {
        59 return this.object_;
        60};
        61
        62
        63/**
        64 * @return {string} The property string.
        65 */
        66goog.testing.ObjectPropertyString.prototype.getPropertyString = function() {
        67 return this.propertyString_;
        68};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/propertyreplacer.js.src.html b/docs/api/javascript/source/lib/goog/testing/propertyreplacer.js.src.html new file mode 100644 index 0000000000000..36e2f6431b769 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/propertyreplacer.js.src.html @@ -0,0 +1 @@ +propertyreplacer.js

        lib/goog/testing/propertyreplacer.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 Helper class for creating stubs for testing.
        17 *
        18 */
        19
        20goog.provide('goog.testing.PropertyReplacer');
        21
        22/** @suppress {extraRequire} Needed for some tests to compile. */
        23goog.require('goog.testing.ObjectPropertyString');
        24goog.require('goog.userAgent');
        25
        26
        27
        28/**
        29 * Helper class for stubbing out variables and object properties for unit tests.
        30 * This class can change the value of some variables before running the test
        31 * cases, and to reset them in the tearDown phase.
        32 * See googletest.StubOutForTesting as an analogy in Python:
        33 * http://protobuf.googlecode.com/svn/trunk/python/stubout.py
        34 *
        35 * Example usage:
        36 * <pre>var stubs = new goog.testing.PropertyReplacer();
        37 *
        38 * function setUp() {
        39 * // Mock functions used in all test cases.
        40 * stubs.set(Math, 'random', function() {
        41 * return 4; // Chosen by fair dice roll. Guaranteed to be random.
        42 * });
        43 * }
        44 *
        45 * function tearDown() {
        46 * stubs.reset();
        47 * }
        48 *
        49 * function testThreeDice() {
        50 * // Mock a constant used only in this test case.
        51 * stubs.set(goog.global, 'DICE_COUNT', 3);
        52 * assertEquals(12, rollAllDice());
        53 * }</pre>
        54 *
        55 * Constraints on altered objects:
        56 * <ul>
        57 * <li>DOM subclasses aren't supported.
        58 * <li>The value of the objects' constructor property must either be equal to
        59 * the real constructor or kept untouched.
        60 * </ul>
        61 *
        62 * @constructor
        63 * @final
        64 */
        65goog.testing.PropertyReplacer = function() {
        66 /**
        67 * Stores the values changed by the set() method in chronological order.
        68 * Its items are objects with 3 fields: 'object', 'key', 'value'. The
        69 * original value for the given key in the given object is stored under the
        70 * 'value' key.
        71 * @type {Array.<Object>}
        72 * @private
        73 */
        74 this.original_ = [];
        75};
        76
        77
        78/**
        79 * Indicates that a key didn't exist before having been set by the set() method.
        80 * @type {Object}
        81 * @private
        82 */
        83goog.testing.PropertyReplacer.NO_SUCH_KEY_ = {};
        84
        85
        86/**
        87 * Tells if the given key exists in the object. Ignores inherited fields.
        88 * @param {Object|Function} obj The JavaScript or native object or function
        89 * whose key is to be checked.
        90 * @param {string} key The key to check.
        91 * @return {boolean} Whether the object has the key as own key.
        92 * @private
        93 */
        94goog.testing.PropertyReplacer.hasKey_ = function(obj, key) {
        95 if (!(key in obj)) {
        96 return false;
        97 }
        98 // hasOwnProperty is only reliable with JavaScript objects. It returns false
        99 // for built-in DOM attributes.
        100 if (Object.prototype.hasOwnProperty.call(obj, key)) {
        101 return true;
        102 }
        103 // In all browsers except Opera obj.constructor never equals to Object if
        104 // obj is an instance of a native class. In Opera we have to fall back on
        105 // examining obj.toString().
        106 if (obj.constructor == Object &&
        107 (!goog.userAgent.OPERA ||
        108 Object.prototype.toString.call(obj) == '[object Object]')) {
        109 return false;
        110 }
        111 try {
        112 // Firefox hack to consider "className" part of the HTML elements or
        113 // "body" part of document. Although they are defined in the prototype of
        114 // HTMLElement or Document, accessing them this way throws an exception.
        115 // <pre>
        116 // var dummy = document.body.constructor.prototype.className
        117 // [Exception... "Cannot modify properties of a WrappedNative"]
        118 // </pre>
        119 var dummy = obj.constructor.prototype[key];
        120 } catch (e) {
        121 return true;
        122 }
        123 return !(key in obj.constructor.prototype);
        124};
        125
        126
        127/**
        128 * Deletes a key from an object. Sets it to undefined or empty string if the
        129 * delete failed.
        130 * @param {Object|Function} obj The object or function to delete a key from.
        131 * @param {string} key The key to delete.
        132 * @private
        133 */
        134goog.testing.PropertyReplacer.deleteKey_ = function(obj, key) {
        135 try {
        136 delete obj[key];
        137 // Delete has no effect for built-in properties of DOM nodes in FF.
        138 if (!goog.testing.PropertyReplacer.hasKey_(obj, key)) {
        139 return;
        140 }
        141 } catch (e) {
        142 // IE throws TypeError when trying to delete properties of native objects
        143 // (e.g. DOM nodes or window), even if they have been added by JavaScript.
        144 }
        145
        146 obj[key] = undefined;
        147 if (obj[key] == 'undefined') {
        148 // Some properties such as className in IE are always evaluated as string
        149 // so undefined will become 'undefined'.
        150 obj[key] = '';
        151 }
        152};
        153
        154
        155/**
        156 * Adds or changes a value in an object while saving its original state.
        157 * @param {Object|Function} obj The JavaScript or native object or function to
        158 * alter. See the constraints in the class description.
        159 * @param {string} key The key to change the value for.
        160 * @param {*} value The new value to set.
        161 */
        162goog.testing.PropertyReplacer.prototype.set = function(obj, key, value) {
        163 var origValue = goog.testing.PropertyReplacer.hasKey_(obj, key) ? obj[key] :
        164 goog.testing.PropertyReplacer.NO_SUCH_KEY_;
        165 this.original_.push({object: obj, key: key, value: origValue});
        166 obj[key] = value;
        167};
        168
        169
        170/**
        171 * Changes an existing value in an object to another one of the same type while
        172 * saving its original state. The advantage of {@code replace} over {@link #set}
        173 * is that {@code replace} protects against typos and erroneously passing tests
        174 * after some members have been renamed during a refactoring.
        175 * @param {Object|Function} obj The JavaScript or native object or function to
        176 * alter. See the constraints in the class description.
        177 * @param {string} key The key to change the value for. It has to be present
        178 * either in {@code obj} or in its prototype chain.
        179 * @param {*} value The new value to set. It has to have the same type as the
        180 * original value. The types are compared with {@link goog.typeOf}.
        181 * @throws {Error} In case of missing key or type mismatch.
        182 */
        183goog.testing.PropertyReplacer.prototype.replace = function(obj, key, value) {
        184 if (!(key in obj)) {
        185 throw Error('Cannot replace missing property "' + key + '" in ' + obj);
        186 }
        187 if (goog.typeOf(obj[key]) != goog.typeOf(value)) {
        188 throw Error('Cannot replace property "' + key + '" in ' + obj +
        189 ' with a value of different type');
        190 }
        191 this.set(obj, key, value);
        192};
        193
        194
        195/**
        196 * Builds an object structure for the provided namespace path. Doesn't
        197 * overwrite those prefixes of the path that are already objects or functions.
        198 * @param {string} path The path to create or alter, e.g. 'goog.ui.Menu'.
        199 * @param {*} value The value to set.
        200 */
        201goog.testing.PropertyReplacer.prototype.setPath = function(path, value) {
        202 var parts = path.split('.');
        203 var obj = goog.global;
        204 for (var i = 0; i < parts.length - 1; i++) {
        205 var part = parts[i];
        206 if (part == 'prototype' && !obj[part]) {
        207 throw Error('Cannot set the prototype of ' + parts.slice(0, i).join('.'));
        208 }
        209 if (!goog.isObject(obj[part]) && !goog.isFunction(obj[part])) {
        210 this.set(obj, part, {});
        211 }
        212 obj = obj[part];
        213 }
        214 this.set(obj, parts[parts.length - 1], value);
        215};
        216
        217
        218/**
        219 * Deletes the key from the object while saving its original value.
        220 * @param {Object|Function} obj The JavaScript or native object or function to
        221 * alter. See the constraints in the class description.
        222 * @param {string} key The key to delete.
        223 */
        224goog.testing.PropertyReplacer.prototype.remove = function(obj, key) {
        225 if (goog.testing.PropertyReplacer.hasKey_(obj, key)) {
        226 this.original_.push({object: obj, key: key, value: obj[key]});
        227 goog.testing.PropertyReplacer.deleteKey_(obj, key);
        228 }
        229};
        230
        231
        232/**
        233 * Resets all changes made by goog.testing.PropertyReplacer.prototype.set.
        234 */
        235goog.testing.PropertyReplacer.prototype.reset = function() {
        236 for (var i = this.original_.length - 1; i >= 0; i--) {
        237 var original = this.original_[i];
        238 if (original.value == goog.testing.PropertyReplacer.NO_SUCH_KEY_) {
        239 goog.testing.PropertyReplacer.deleteKey_(original.object, original.key);
        240 } else {
        241 original.object[original.key] = original.value;
        242 }
        243 delete this.original_[i];
        244 }
        245 this.original_.length = 0;
        246};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/recordfunction.js.src.html b/docs/api/javascript/source/lib/goog/testing/recordfunction.js.src.html new file mode 100644 index 0000000000000..c2c52c25821fd --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/recordfunction.js.src.html @@ -0,0 +1 @@ +recordfunction.js

        lib/goog/testing/recordfunction.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 Helper class for recording the calls of a function.
        17 *
        18 * Example:
        19 * <pre>
        20 * var stubs = new goog.testing.PropertyReplacer();
        21 *
        22 * function tearDown() {
        23 * stubs.reset();
        24 * }
        25 *
        26 * function testShuffle() {
        27 * stubs.set(Math, 'random', goog.testing.recordFunction(Math.random));
        28 * var arr = shuffle([1, 2, 3, 4, 5]);
        29 * assertSameElements([1, 2, 3, 4, 5], arr);
        30 * assertEquals(4, Math.random.getCallCount());
        31 * }
        32 *
        33 * function testOpenDialog() {
        34 * stubs.set(goog.ui, 'Dialog',
        35 * goog.testing.recordConstructor(goog.ui.Dialog));
        36 * openConfirmDialog();
        37 * var lastDialogInstance = goog.ui.Dialog.getLastCall().getThis();
        38 * assertEquals('confirm', lastDialogInstance.getTitle());
        39 * }
        40 * </pre>
        41 *
        42 */
        43
        44goog.provide('goog.testing.FunctionCall');
        45goog.provide('goog.testing.recordConstructor');
        46goog.provide('goog.testing.recordFunction');
        47
        48goog.require('goog.testing.asserts');
        49
        50
        51/**
        52 * Wraps the function into another one which calls the inner function and
        53 * records its calls. The recorded function will have 3 static methods:
        54 * {@code getCallCount}, {@code getCalls} and {@code getLastCall} but won't
        55 * inherit the original function's prototype and static fields.
        56 *
        57 * @param {!Function=} opt_f The function to wrap and record. Defaults to
        58 * {@link goog.nullFunction}.
        59 * @return {!Function} The wrapped function.
        60 */
        61goog.testing.recordFunction = function(opt_f) {
        62 var f = opt_f || goog.nullFunction;
        63 var calls = [];
        64
        65 function recordedFunction() {
        66 try {
        67 var ret = f.apply(this, arguments);
        68 calls.push(new goog.testing.FunctionCall(f, this, arguments, ret, null));
        69 return ret;
        70 } catch (err) {
        71 calls.push(new goog.testing.FunctionCall(f, this, arguments, undefined,
        72 err));
        73 throw err;
        74 }
        75 }
        76
        77 /**
        78 * @return {number} Total number of calls.
        79 */
        80 recordedFunction.getCallCount = function() {
        81 return calls.length;
        82 };
        83
        84 /**
        85 * Asserts that the function was called {@code expected} times.
        86 * @param {number} expected The expected number of calls.
        87 */
        88 recordedFunction.assertCallCount = function(expected) {
        89 var actual = calls.length;
        90 assertEquals(
        91 'Expected ' + expected + ' call(s), but was ' + actual + '.',
        92 expected, actual);
        93 };
        94
        95 /**
        96 * @return {!Array.<!goog.testing.FunctionCall>} All calls of the recorded
        97 * function.
        98 */
        99 recordedFunction.getCalls = function() {
        100 return calls;
        101 };
        102
        103
        104 /**
        105 * @return {goog.testing.FunctionCall} Last call of the recorded function or
        106 * null if it hasn't been called.
        107 */
        108 recordedFunction.getLastCall = function() {
        109 return calls[calls.length - 1] || null;
        110 };
        111
        112 /**
        113 * Returns and removes the last call of the recorded function.
        114 * @return {goog.testing.FunctionCall} Last call of the recorded function or
        115 * null if it hasn't been called.
        116 */
        117 recordedFunction.popLastCall = function() {
        118 return calls.pop() || null;
        119 };
        120
        121 /**
        122 * Resets the recorded function and removes all calls.
        123 */
        124 recordedFunction.reset = function() {
        125 calls.length = 0;
        126 };
        127
        128 return recordedFunction;
        129};
        130
        131
        132/**
        133 * Same as {@link goog.testing.recordFunction} but the recorded function will
        134 * have the same prototype and static fields as the original one. It can be
        135 * used with constructors.
        136 *
        137 * @param {!Function} ctor The function to wrap and record.
        138 * @return {!Function} The wrapped function.
        139 */
        140goog.testing.recordConstructor = function(ctor) {
        141 var recordedConstructor = goog.testing.recordFunction(ctor);
        142 recordedConstructor.prototype = ctor.prototype;
        143 goog.mixin(recordedConstructor, ctor);
        144 return recordedConstructor;
        145};
        146
        147
        148
        149/**
        150 * Struct for a single function call.
        151 * @param {!Function} func The called function.
        152 * @param {!Object} thisContext {@code this} context of called function.
        153 * @param {!Arguments} args Arguments of the called function.
        154 * @param {*} ret Return value of the function or undefined in case of error.
        155 * @param {*} error The error thrown by the function or null if none.
        156 * @constructor
        157 */
        158goog.testing.FunctionCall = function(func, thisContext, args, ret, error) {
        159 this.function_ = func;
        160 this.thisContext_ = thisContext;
        161 this.arguments_ = Array.prototype.slice.call(args);
        162 this.returnValue_ = ret;
        163 this.error_ = error;
        164};
        165
        166
        167/**
        168 * @return {!Function} The called function.
        169 */
        170goog.testing.FunctionCall.prototype.getFunction = function() {
        171 return this.function_;
        172};
        173
        174
        175/**
        176 * @return {!Object} {@code this} context of called function. It is the same as
        177 * the created object if the function is a constructor.
        178 */
        179goog.testing.FunctionCall.prototype.getThis = function() {
        180 return this.thisContext_;
        181};
        182
        183
        184/**
        185 * @return {!Array} Arguments of the called function.
        186 */
        187goog.testing.FunctionCall.prototype.getArguments = function() {
        188 return this.arguments_;
        189};
        190
        191
        192/**
        193 * Returns the nth argument of the called function.
        194 * @param {number} index 0-based index of the argument.
        195 * @return {*} The argument value or undefined if there is no such argument.
        196 */
        197goog.testing.FunctionCall.prototype.getArgument = function(index) {
        198 return this.arguments_[index];
        199};
        200
        201
        202/**
        203 * @return {*} Return value of the function or undefined in case of error.
        204 */
        205goog.testing.FunctionCall.prototype.getReturnValue = function() {
        206 return this.returnValue_;
        207};
        208
        209
        210/**
        211 * @return {*} The error thrown by the function or null if none.
        212 */
        213goog.testing.FunctionCall.prototype.getError = function() {
        214 return this.error_;
        215};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/stacktrace.js.src.html b/docs/api/javascript/source/lib/goog/testing/stacktrace.js.src.html new file mode 100644 index 0000000000000..73406c7bb8402 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/stacktrace.js.src.html @@ -0,0 +1 @@ +stacktrace.js

        lib/goog/testing/stacktrace.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 Tools for parsing and pretty printing error stack traces.
        17 *
        18 */
        19
        20goog.provide('goog.testing.stacktrace');
        21goog.provide('goog.testing.stacktrace.Frame');
        22
        23
        24
        25/**
        26 * Class representing one stack frame.
        27 * @param {string} context Context object, empty in case of global functions or
        28 * if the browser doesn't provide this information.
        29 * @param {string} name Function name, empty in case of anonymous functions.
        30 * @param {string} alias Alias of the function if available. For example the
        31 * function name will be 'c' and the alias will be 'b' if the function is
        32 * defined as <code>a.b = function c() {};</code>.
        33 * @param {string} args Arguments of the function in parentheses if available.
        34 * @param {string} path File path or URL including line number and optionally
        35 * column number separated by colons.
        36 * @constructor
        37 * @final
        38 */
        39goog.testing.stacktrace.Frame = function(context, name, alias, args, path) {
        40 this.context_ = context;
        41 this.name_ = name;
        42 this.alias_ = alias;
        43 this.args_ = args;
        44 this.path_ = path;
        45};
        46
        47
        48/**
        49 * @return {string} The function name or empty string if the function is
        50 * anonymous and the object field which it's assigned to is unknown.
        51 */
        52goog.testing.stacktrace.Frame.prototype.getName = function() {
        53 return this.name_;
        54};
        55
        56
        57/**
        58 * @return {boolean} Whether the stack frame contains an anonymous function.
        59 */
        60goog.testing.stacktrace.Frame.prototype.isAnonymous = function() {
        61 return !this.name_ || this.context_ == '[object Object]';
        62};
        63
        64
        65/**
        66 * Brings one frame of the stack trace into a common format across browsers.
        67 * @return {string} Pretty printed stack frame.
        68 */
        69goog.testing.stacktrace.Frame.prototype.toCanonicalString = function() {
        70 var htmlEscape = goog.testing.stacktrace.htmlEscape_;
        71 var deobfuscate = goog.testing.stacktrace.maybeDeobfuscateFunctionName_;
        72
        73 var canonical = [
        74 this.context_ ? htmlEscape(this.context_) + '.' : '',
        75 this.name_ ? htmlEscape(deobfuscate(this.name_)) : 'anonymous',
        76 htmlEscape(this.args_),
        77 this.alias_ ? ' [as ' + htmlEscape(deobfuscate(this.alias_)) + ']' : ''
        78 ];
        79
        80 if (this.path_) {
        81 canonical.push(' at ');
        82 canonical.push(htmlEscape(this.path_));
        83 }
        84 return canonical.join('');
        85};
        86
        87
        88/**
        89 * Maximum number of steps while the call chain is followed.
        90 * @private {number}
        91 * @const
        92 */
        93goog.testing.stacktrace.MAX_DEPTH_ = 20;
        94
        95
        96/**
        97 * Maximum length of a string that can be matched with a RegExp on
        98 * Firefox 3x. Exceeding this approximate length will cause string.match
        99 * to exceed Firefox's stack quota. This situation can be encountered
        100 * when goog.globalEval is invoked with a long argument; such as
        101 * when loading a module.
        102 * @private {number}
        103 * @const
        104 */
        105goog.testing.stacktrace.MAX_FIREFOX_FRAMESTRING_LENGTH_ = 500000;
        106
        107
        108/**
        109 * RegExp pattern for JavaScript identifiers. We don't support Unicode
        110 * identifiers defined in ECMAScript v3.
        111 * @private {string}
        112 * @const
        113 */
        114goog.testing.stacktrace.IDENTIFIER_PATTERN_ = '[a-zA-Z_$][\\w$]*';
        115
        116
        117/**
        118 * RegExp pattern for function name alias in the V8 stack trace.
        119 * @private {string}
        120 * @const
        121 */
        122goog.testing.stacktrace.V8_ALIAS_PATTERN_ =
        123 '(?: \\[as (' + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ')\\])?';
        124
        125
        126/**
        127 * RegExp pattern for the context of a function call in a V8 stack trace.
        128 * Creates an optional submatch for the namespace identifier including the
        129 * "new" keyword for constructor calls (e.g. "new foo.Bar").
        130 * @private {string}
        131 * @const
        132 */
        133goog.testing.stacktrace.V8_CONTEXT_PATTERN_ =
        134 '(?:((?:new )?(?:\\[object Object\\]|' +
        135 goog.testing.stacktrace.IDENTIFIER_PATTERN_ +
        136 '(?:\\.' + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ')*))\\.)?';
        137
        138
        139/**
        140 * RegExp pattern for function names and constructor calls in the V8 stack
        141 * trace.
        142 * @private {string}
        143 * @const
        144 */
        145goog.testing.stacktrace.V8_FUNCTION_NAME_PATTERN_ =
        146 '(?:new )?(?:' + goog.testing.stacktrace.IDENTIFIER_PATTERN_ +
        147 '|<anonymous>)';
        148
        149
        150/**
        151 * RegExp pattern for function call in the V8 stack trace. Creates 3 submatches
        152 * with context object (optional), function name and function alias (optional).
        153 * @private {string}
        154 * @const
        155 */
        156goog.testing.stacktrace.V8_FUNCTION_CALL_PATTERN_ =
        157 ' ' + goog.testing.stacktrace.V8_CONTEXT_PATTERN_ +
        158 '(' + goog.testing.stacktrace.V8_FUNCTION_NAME_PATTERN_ + ')' +
        159 goog.testing.stacktrace.V8_ALIAS_PATTERN_;
        160
        161
        162/**
        163 * RegExp pattern for an URL + position inside the file.
        164 * @private {string}
        165 * @const
        166 */
        167goog.testing.stacktrace.URL_PATTERN_ =
        168 '((?:http|https|file)://[^\\s)]+|javascript:.*)';
        169
        170
        171/**
        172 * RegExp pattern for an URL + line number + column number in V8.
        173 * The URL is either in submatch 1 or submatch 2.
        174 * @private {string}
        175 * @const
        176 */
        177goog.testing.stacktrace.CHROME_URL_PATTERN_ = ' (?:' +
        178 '\\(unknown source\\)' + '|' +
        179 '\\(native\\)' + '|' +
        180 '\\((.+)\\)|(.+))';
        181
        182
        183/**
        184 * Regular expression for parsing one stack frame in V8. For more information
        185 * on V8 stack frame formats, see
        186 * https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi.
        187 * @private {!RegExp}
        188 * @const
        189 */
        190goog.testing.stacktrace.V8_STACK_FRAME_REGEXP_ = new RegExp('^ at' +
        191 '(?:' + goog.testing.stacktrace.V8_FUNCTION_CALL_PATTERN_ + ')?' +
        192 goog.testing.stacktrace.CHROME_URL_PATTERN_ + '$');
        193
        194
        195/**
        196 * RegExp pattern for function call in the Firefox stack trace.
        197 * Creates 2 submatches with function name (optional) and arguments.
        198 * @private {string}
        199 * @const
        200 */
        201goog.testing.stacktrace.FIREFOX_FUNCTION_CALL_PATTERN_ =
        202 '(' + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ')?' +
        203 '(\\(.*\\))?@';
        204
        205
        206/**
        207 * Regular expression for parsing one stack frame in Firefox.
        208 * @private {!RegExp}
        209 * @const
        210 */
        211goog.testing.stacktrace.FIREFOX_STACK_FRAME_REGEXP_ = new RegExp('^' +
        212 goog.testing.stacktrace.FIREFOX_FUNCTION_CALL_PATTERN_ +
        213 '(?::0|' + goog.testing.stacktrace.URL_PATTERN_ + ')$');
        214
        215
        216/**
        217 * RegExp pattern for an anonymous function call in an Opera stack frame.
        218 * Creates 2 (optional) submatches: the context object and function name.
        219 * @private {string}
        220 * @const
        221 */
        222goog.testing.stacktrace.OPERA_ANONYMOUS_FUNCTION_NAME_PATTERN_ =
        223 '<anonymous function(?:\\: ' +
        224 '(?:(' + goog.testing.stacktrace.IDENTIFIER_PATTERN_ +
        225 '(?:\\.' + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ')*)\\.)?' +
        226 '(' + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + '))?>';
        227
        228
        229/**
        230 * RegExp pattern for a function call in an Opera stack frame.
        231 * Creates 4 (optional) submatches: the function name (if not anonymous),
        232 * the aliased context object and function name (if anonymous), and the
        233 * function call arguments.
        234 * @private {string}
        235 * @const
        236 */
        237goog.testing.stacktrace.OPERA_FUNCTION_CALL_PATTERN_ =
        238 '(?:(?:(' + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ')|' +
        239 goog.testing.stacktrace.OPERA_ANONYMOUS_FUNCTION_NAME_PATTERN_ +
        240 ')(\\(.*\\)))?@';
        241
        242
        243/**
        244 * Regular expression for parsing on stack frame in Opera 11.68 - 12.17.
        245 * Newer versions of Opera use V8 and stack frames should match against
        246 * goog.testing.stacktrace.V8_STACK_FRAME_REGEXP_.
        247 * @private {!RegExp}
        248 * @const
        249 */
        250goog.testing.stacktrace.OPERA_STACK_FRAME_REGEXP_ = new RegExp('^' +
        251 goog.testing.stacktrace.OPERA_FUNCTION_CALL_PATTERN_ +
        252 goog.testing.stacktrace.URL_PATTERN_ + '?$');
        253
        254
        255/**
        256 * Regular expression for finding the function name in its source.
        257 * @private {!RegExp}
        258 * @const
        259 */
        260goog.testing.stacktrace.FUNCTION_SOURCE_REGEXP_ = new RegExp(
        261 '^function (' + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ')');
        262
        263
        264/**
        265 * RegExp pattern for function call in a IE stack trace. This expression allows
        266 * for identifiers like 'Anonymous function', 'eval code', and 'Global code'.
        267 * @private {string}
        268 * @const
        269 */
        270goog.testing.stacktrace.IE_FUNCTION_CALL_PATTERN_ = '(' +
        271 goog.testing.stacktrace.IDENTIFIER_PATTERN_ + '(?:\\s+\\w+)*)';
        272
        273
        274/**
        275 * Regular expression for parsing a stack frame in IE.
        276 * @private {!RegExp}
        277 * @const
        278 */
        279goog.testing.stacktrace.IE_STACK_FRAME_REGEXP_ = new RegExp('^ at ' +
        280 goog.testing.stacktrace.IE_FUNCTION_CALL_PATTERN_ +
        281 '\\s*\\((eval code:[^)]*|' + goog.testing.stacktrace.URL_PATTERN_ +
        282 ')\\)?$');
        283
        284
        285/**
        286 * Creates a stack trace by following the call chain. Based on
        287 * {@link goog.debug.getStacktrace}.
        288 * @return {!Array.<!goog.testing.stacktrace.Frame>} Stack frames.
        289 * @private
        290 * @suppress {es5Strict}
        291 */
        292goog.testing.stacktrace.followCallChain_ = function() {
        293 var frames = [];
        294 var fn = arguments.callee.caller;
        295 var depth = 0;
        296
        297 while (fn && depth < goog.testing.stacktrace.MAX_DEPTH_) {
        298 var fnString = Function.prototype.toString.call(fn);
        299 var match = fnString.match(goog.testing.stacktrace.FUNCTION_SOURCE_REGEXP_);
        300 var functionName = match ? match[1] : '';
        301
        302 var argsBuilder = ['('];
        303 if (fn.arguments) {
        304 for (var i = 0; i < fn.arguments.length; i++) {
        305 var arg = fn.arguments[i];
        306 if (i > 0) {
        307 argsBuilder.push(', ');
        308 }
        309 if (goog.isString(arg)) {
        310 argsBuilder.push('"', arg, '"');
        311 } else {
        312 // Some args are mocks, and we don't want to fail from them not having
        313 // expected a call to toString, so instead insert a static string.
        314 if (arg && arg['$replay']) {
        315 argsBuilder.push('goog.testing.Mock');
        316 } else {
        317 argsBuilder.push(String(arg));
        318 }
        319 }
        320 }
        321 } else {
        322 // Opera 10 doesn't know the arguments of native functions.
        323 argsBuilder.push('unknown');
        324 }
        325 argsBuilder.push(')');
        326 var args = argsBuilder.join('');
        327
        328 frames.push(new goog.testing.stacktrace.Frame('', functionName, '', args,
        329 ''));
        330
        331 /** @preserveTry */
        332 try {
        333 fn = fn.caller;
        334 } catch (e) {
        335 break;
        336 }
        337 depth++;
        338 }
        339
        340 return frames;
        341};
        342
        343
        344/**
        345 * Parses one stack frame.
        346 * @param {string} frameStr The stack frame as string.
        347 * @return {goog.testing.stacktrace.Frame} Stack frame object or null if the
        348 * parsing failed.
        349 * @private
        350 */
        351goog.testing.stacktrace.parseStackFrame_ = function(frameStr) {
        352 // This match includes newer versions of Opera (15+).
        353 var m = frameStr.match(goog.testing.stacktrace.V8_STACK_FRAME_REGEXP_);
        354 if (m) {
        355 return new goog.testing.stacktrace.Frame(m[1] || '', m[2] || '', m[3] || '',
        356 '', m[4] || m[5] || m[6] || '');
        357 }
        358
        359 if (frameStr.length >
        360 goog.testing.stacktrace.MAX_FIREFOX_FRAMESTRING_LENGTH_) {
        361 return goog.testing.stacktrace.parseLongFirefoxFrame_(frameStr);
        362 }
        363
        364 m = frameStr.match(goog.testing.stacktrace.FIREFOX_STACK_FRAME_REGEXP_);
        365 if (m) {
        366 return new goog.testing.stacktrace.Frame('', m[1] || '', '', m[2] || '',
        367 m[3] || '');
        368 }
        369
        370 // Match against Presto Opera 11.68 - 12.17.
        371 m = frameStr.match(goog.testing.stacktrace.OPERA_STACK_FRAME_REGEXP_);
        372 if (m) {
        373 return new goog.testing.stacktrace.Frame(m[2] || '', m[1] || m[3] || '',
        374 '', m[4] || '', m[5] || '');
        375 }
        376
        377 m = frameStr.match(goog.testing.stacktrace.IE_STACK_FRAME_REGEXP_);
        378 if (m) {
        379 return new goog.testing.stacktrace.Frame('', m[1] || '', '', '',
        380 m[2] || '');
        381 }
        382
        383 return null;
        384};
        385
        386
        387/**
        388 * Parses a long firefox stack frame.
        389 * @param {string} frameStr The stack frame as string.
        390 * @return {!goog.testing.stacktrace.Frame} Stack frame object.
        391 * @private
        392 */
        393goog.testing.stacktrace.parseLongFirefoxFrame_ = function(frameStr) {
        394 var firstParen = frameStr.indexOf('(');
        395 var lastAmpersand = frameStr.lastIndexOf('@');
        396 var lastColon = frameStr.lastIndexOf(':');
        397 var functionName = '';
        398 if ((firstParen >= 0) && (firstParen < lastAmpersand)) {
        399 functionName = frameStr.substring(0, firstParen);
        400 }
        401 var loc = '';
        402 if ((lastAmpersand >= 0) && (lastAmpersand + 1 < lastColon)) {
        403 loc = frameStr.substring(lastAmpersand + 1);
        404 }
        405 var args = '';
        406 if ((firstParen >= 0 && lastAmpersand > 0) &&
        407 (firstParen < lastAmpersand)) {
        408 args = frameStr.substring(firstParen, lastAmpersand);
        409 }
        410 return new goog.testing.stacktrace.Frame('', functionName, '', args, loc);
        411};
        412
        413
        414/**
        415 * Function to deobfuscate function names.
        416 * @type {function(string): string}
        417 * @private
        418 */
        419goog.testing.stacktrace.deobfuscateFunctionName_;
        420
        421
        422/**
        423 * Sets function to deobfuscate function names.
        424 * @param {function(string): string} fn function to deobfuscate function names.
        425 */
        426goog.testing.stacktrace.setDeobfuscateFunctionName = function(fn) {
        427 goog.testing.stacktrace.deobfuscateFunctionName_ = fn;
        428};
        429
        430
        431/**
        432 * Deobfuscates a compiled function name with the function passed to
        433 * {@link #setDeobfuscateFunctionName}. Returns the original function name if
        434 * the deobfuscator hasn't been set.
        435 * @param {string} name The function name to deobfuscate.
        436 * @return {string} The deobfuscated function name.
        437 * @private
        438 */
        439goog.testing.stacktrace.maybeDeobfuscateFunctionName_ = function(name) {
        440 return goog.testing.stacktrace.deobfuscateFunctionName_ ?
        441 goog.testing.stacktrace.deobfuscateFunctionName_(name) : name;
        442};
        443
        444
        445/**
        446 * Escapes the special character in HTML.
        447 * @param {string} text Plain text.
        448 * @return {string} Escaped text.
        449 * @private
        450 */
        451goog.testing.stacktrace.htmlEscape_ = function(text) {
        452 return text.replace(/&/g, '&amp;').
        453 replace(/</g, '&lt;').
        454 replace(/>/g, '&gt;').
        455 replace(/"/g, '&quot;');
        456};
        457
        458
        459/**
        460 * Converts the stack frames into canonical format. Chops the beginning and the
        461 * end of it which come from the testing environment, not from the test itself.
        462 * @param {!Array.<goog.testing.stacktrace.Frame>} frames The frames.
        463 * @return {string} Canonical, pretty printed stack trace.
        464 * @private
        465 */
        466goog.testing.stacktrace.framesToString_ = function(frames) {
        467 // Removes the anonymous calls from the end of the stack trace (they come
        468 // from testrunner.js, testcase.js and asserts.js), so the stack trace will
        469 // end with the test... method.
        470 var lastIndex = frames.length - 1;
        471 while (frames[lastIndex] && frames[lastIndex].isAnonymous()) {
        472 lastIndex--;
        473 }
        474
        475 // Removes the beginning of the stack trace until the call of the private
        476 // _assert function (inclusive), so the stack trace will begin with a public
        477 // asserter. Does nothing if _assert is not present in the stack trace.
        478 var privateAssertIndex = -1;
        479 for (var i = 0; i < frames.length; i++) {
        480 if (frames[i] && frames[i].getName() == '_assert') {
        481 privateAssertIndex = i;
        482 break;
        483 }
        484 }
        485
        486 var canonical = [];
        487 for (var i = privateAssertIndex + 1; i <= lastIndex; i++) {
        488 canonical.push('> ');
        489 if (frames[i]) {
        490 canonical.push(frames[i].toCanonicalString());
        491 } else {
        492 canonical.push('(unknown)');
        493 }
        494 canonical.push('\n');
        495 }
        496 return canonical.join('');
        497};
        498
        499
        500/**
        501 * Parses the browser's native stack trace.
        502 * @param {string} stack Stack trace.
        503 * @return {!Array.<goog.testing.stacktrace.Frame>} Stack frames. The
        504 * unrecognized frames will be nulled out.
        505 * @private
        506 */
        507goog.testing.stacktrace.parse_ = function(stack) {
        508 var lines = stack.replace(/\s*$/, '').split('\n');
        509 var frames = [];
        510 for (var i = 0; i < lines.length; i++) {
        511 frames.push(goog.testing.stacktrace.parseStackFrame_(lines[i]));
        512 }
        513 return frames;
        514};
        515
        516
        517/**
        518 * Brings the stack trace into a common format across browsers.
        519 * @param {string} stack Browser-specific stack trace.
        520 * @return {string} Same stack trace in common format.
        521 */
        522goog.testing.stacktrace.canonicalize = function(stack) {
        523 var frames = goog.testing.stacktrace.parse_(stack);
        524 return goog.testing.stacktrace.framesToString_(frames);
        525};
        526
        527
        528/**
        529 * Returns the native stack trace.
        530 * @return {string|!Array.<!CallSite>}
        531 * @private
        532 */
        533goog.testing.stacktrace.getNativeStack_ = function() {
        534 var tmpError = new Error();
        535 if (tmpError.stack) {
        536 return tmpError.stack;
        537 }
        538
        539 // IE10 will only create a stack trace when the Error is thrown.
        540 // We use null.x() to throw an exception because the closure compiler may
        541 // replace "throw" with a function call in an attempt to minimize the binary
        542 // size, which in turn has the side effect of adding an unwanted stack frame.
        543 try {
        544 null.x();
        545 } catch (e) {
        546 return e.stack;
        547 }
        548 return '';
        549};
        550
        551
        552/**
        553 * Gets the native stack trace if available otherwise follows the call chain.
        554 * @return {string} The stack trace in canonical format.
        555 */
        556goog.testing.stacktrace.get = function() {
        557 var stack = goog.testing.stacktrace.getNativeStack_();
        558 var frames;
        559 if (!stack) {
        560 frames = goog.testing.stacktrace.followCallChain_();
        561 } else if (goog.isArray(stack)) {
        562 frames = goog.testing.stacktrace.callSitesToFrames_(stack);
        563 } else {
        564 frames = goog.testing.stacktrace.parse_(stack);
        565 }
        566 return goog.testing.stacktrace.framesToString_(frames);
        567};
        568
        569
        570/**
        571 * Converts an array of CallSite (elements of a stack trace in V8) to an array
        572 * of Frames.
        573 * @param {!Array.<!CallSite>} stack The stack as an array of CallSites.
        574 * @return {!Array.<!goog.testing.stacktrace.Frame>} The stack as an array of
        575 * Frames.
        576 * @private
        577 */
        578goog.testing.stacktrace.callSitesToFrames_ = function(stack) {
        579 var frames = [];
        580 for (var i = 0; i < stack.length; i++) {
        581 var callSite = stack[i];
        582 var functionName = callSite.getFunctionName() || 'unknown';
        583 var fileName = callSite.getFileName();
        584 var path = fileName ? fileName + ':' + callSite.getLineNumber() + ':' +
        585 callSite.getColumnNumber() : 'unknown';
        586 frames.push(
        587 new goog.testing.stacktrace.Frame('', functionName, '', '', path));
        588 }
        589 return frames;
        590};
        591
        592
        593goog.exportSymbol('setDeobfuscateFunctionName',
        594 goog.testing.stacktrace.setDeobfuscateFunctionName);
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/strictmock.js.src.html b/docs/api/javascript/source/lib/goog/testing/strictmock.js.src.html new file mode 100644 index 0000000000000..f54c965314541 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/strictmock.js.src.html @@ -0,0 +1 @@ +strictmock.js

        lib/goog/testing/strictmock.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 This file defines a strict mock implementation.
        17 */
        18
        19goog.provide('goog.testing.StrictMock');
        20
        21goog.require('goog.array');
        22goog.require('goog.testing.Mock');
        23
        24
        25
        26/**
        27 * This is a mock that verifies that methods are called in the order that they
        28 * are specified during the recording phase. Since it verifies order, it
        29 * follows 'fail fast' semantics. If it detects a deviation from the
        30 * expectations, it will throw an exception and not wait for verify to be
        31 * called.
        32 * @param {Object|Function} objectToMock The object that should be mocked, or
        33 * the constructor of an object to mock.
        34 * @param {boolean=} opt_mockStaticMethods An optional argument denoting that
        35 * a mock should be constructed from the static functions of a class.
        36 * @param {boolean=} opt_createProxy An optional argument denoting that
        37 * a proxy for the target mock should be created.
        38 * @constructor
        39 * @extends {goog.testing.Mock}
        40 * @final
        41 */
        42goog.testing.StrictMock = function(objectToMock, opt_mockStaticMethods,
        43 opt_createProxy) {
        44 goog.testing.Mock.call(this, objectToMock, opt_mockStaticMethods,
        45 opt_createProxy);
        46
        47 /**
        48 * An array of MockExpectations.
        49 * @type {Array.<goog.testing.MockExpectation>}
        50 * @private
        51 */
        52 this.$expectations_ = [];
        53};
        54goog.inherits(goog.testing.StrictMock, goog.testing.Mock);
        55
        56
        57/** @override */
        58goog.testing.StrictMock.prototype.$recordExpectation = function() {
        59 this.$expectations_.push(this.$pendingExpectation);
        60};
        61
        62
        63/** @override */
        64goog.testing.StrictMock.prototype.$recordCall = function(name, args) {
        65 if (this.$expectations_.length == 0) {
        66 this.$throwCallException(name, args);
        67 }
        68
        69 // If the current expectation has a different name, make sure it was called
        70 // enough and then discard it. We're through with it.
        71 var currentExpectation = this.$expectations_[0];
        72 while (!this.$verifyCall(currentExpectation, name, args)) {
        73
        74 // This might be an item which has passed its min, and we can now
        75 // look past it, or it might be below its min and generate an error.
        76 if (currentExpectation.actualCalls < currentExpectation.minCalls) {
        77 this.$throwCallException(name, args, currentExpectation);
        78 }
        79
        80 this.$expectations_.shift();
        81 if (this.$expectations_.length < 1) {
        82 // Nothing left, but this may be a failed attempt to call the previous
        83 // item on the list, which may have been between its min and max.
        84 this.$throwCallException(name, args, currentExpectation);
        85 }
        86 currentExpectation = this.$expectations_[0];
        87 }
        88
        89 if (currentExpectation.maxCalls == 0) {
        90 this.$throwCallException(name, args);
        91 }
        92
        93 currentExpectation.actualCalls++;
        94 // If we hit the max number of calls for this expectation, we're finished
        95 // with it.
        96 if (currentExpectation.actualCalls == currentExpectation.maxCalls) {
        97 this.$expectations_.shift();
        98 }
        99
        100 return this.$do(currentExpectation, args);
        101};
        102
        103
        104/** @override */
        105goog.testing.StrictMock.prototype.$reset = function() {
        106 goog.testing.StrictMock.superClass_.$reset.call(this);
        107
        108 goog.array.clear(this.$expectations_);
        109};
        110
        111
        112/** @override */
        113goog.testing.StrictMock.prototype.$verify = function() {
        114 goog.testing.StrictMock.superClass_.$verify.call(this);
        115
        116 while (this.$expectations_.length > 0) {
        117 var expectation = this.$expectations_[0];
        118 if (expectation.actualCalls < expectation.minCalls) {
        119 this.$throwException('Missing a call to ' + expectation.name +
        120 '\nExpected: ' + expectation.minCalls + ' but was: ' +
        121 expectation.actualCalls);
        122
        123 } else {
        124 // Don't need to check max, that's handled when the call is made
        125 this.$expectations_.shift();
        126 }
        127 }
        128};
        129
        130
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/testcase.js.src.html b/docs/api/javascript/source/lib/goog/testing/testcase.js.src.html new file mode 100644 index 0000000000000..38d876d5952f8 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/testcase.js.src.html @@ -0,0 +1 @@ +testcase.js

        lib/goog/testing/testcase.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 A class representing a set of test functions to be run.
        17 *
        18 * Testing code should not have dependencies outside of goog.testing so as to
        19 * reduce the chance of masking missing dependencies.
        20 *
        21 * This file does not compile correctly with --collapse_properties. Use
        22 * --property_renaming=ALL_UNQUOTED instead.
        23 *
        24 */
        25
        26goog.provide('goog.testing.TestCase');
        27goog.provide('goog.testing.TestCase.Error');
        28goog.provide('goog.testing.TestCase.Order');
        29goog.provide('goog.testing.TestCase.Result');
        30goog.provide('goog.testing.TestCase.Test');
        31
        32goog.require('goog.object');
        33goog.require('goog.testing.asserts');
        34goog.require('goog.testing.stacktrace');
        35
        36
        37
        38/**
        39 * A class representing a JsUnit test case. A TestCase is made up of a number
        40 * of test functions which can be run. Individual test cases can override the
        41 * following functions to set up their test environment:
        42 * - runTests - completely override the test's runner
        43 * - setUpPage - called before any of the test functions are run
        44 * - tearDownPage - called after all tests are finished
        45 * - setUp - called before each of the test functions
        46 * - tearDown - called after each of the test functions
        47 * - shouldRunTests - called before a test run, all tests are skipped if it
        48 * returns false. Can be used to disable tests on browsers
        49 * where they aren't expected to pass.
        50 *
        51 * Use {@link #autoDiscoverLifecycle} and {@link #autoDiscoverTests}
        52 *
        53 * @param {string=} opt_name The name of the test case, defaults to
        54 * 'Untitled Test Case'.
        55 * @constructor
        56 */
        57goog.testing.TestCase = function(opt_name) {
        58 /**
        59 * A name for the test case.
        60 * @type {string}
        61 * @private
        62 */
        63 this.name_ = opt_name || 'Untitled Test Case';
        64
        65 /**
        66 * Array of test functions that can be executed.
        67 * @type {!Array.<!goog.testing.TestCase.Test>}
        68 * @private
        69 */
        70 this.tests_ = [];
        71
        72 /**
        73 * Set of test names and/or indices to execute, or null if all tests should
        74 * be executed.
        75 *
        76 * Indices are included to allow automation tools to run a subset of the
        77 * tests without knowing the exact contents of the test file.
        78 *
        79 * Indices should only be used with SORTED ordering.
        80 *
        81 * Example valid values:
        82 * <ul>
        83 * <li>[testName]
        84 * <li>[testName1, testName2]
        85 * <li>[2] - will run the 3rd test in the order specified
        86 * <li>[1,3,5]
        87 * <li>[testName1, testName2, 3, 5] - will work
        88 * <ul>
        89 * @type {Object}
        90 * @private
        91 */
        92 this.testsToRun_ = null;
        93
        94 var search = '';
        95 if (goog.global.location) {
        96 search = goog.global.location.search;
        97 }
        98
        99 // Parse the 'runTests' query parameter into a set of test names and/or
        100 // test indices.
        101 var runTestsMatch = search.match(/(?:\?|&)runTests=([^?&]+)/i);
        102 if (runTestsMatch) {
        103 this.testsToRun_ = {};
        104 var arr = runTestsMatch[1].split(',');
        105 for (var i = 0, len = arr.length; i < len; i++) {
        106 this.testsToRun_[arr[i]] = 1;
        107 }
        108 }
        109
        110 // Checks the URL for a valid order param.
        111 var orderMatch = search.match(/(?:\?|&)order=(natural|random|sorted)/i);
        112 if (orderMatch) {
        113 this.order = orderMatch[1];
        114 }
        115
        116 /**
        117 * Object used to encapsulate the test results.
        118 * @type {goog.testing.TestCase.Result}
        119 * @protected
        120 * @suppress {underscore|visibility}
        121 */
        122 this.result_ = new goog.testing.TestCase.Result(this);
        123
        124 // This silences a compiler warning from the legacy property check, which
        125 // is deprecated. It idly writes to testRunner properties that are used
        126 // in this file.
        127 var testRunnerMethods = {isFinished: true, hasErrors: true};
        128};
        129
        130
        131/**
        132 * The order to run the auto-discovered tests.
        133 * @enum {string}
        134 */
        135goog.testing.TestCase.Order = {
        136 /**
        137 * This is browser dependent and known to be different in FF and Safari
        138 * compared to others.
        139 */
        140 NATURAL: 'natural',
        141
        142 /** Random order. */
        143 RANDOM: 'random',
        144
        145 /** Sorted based on the name. */
        146 SORTED: 'sorted'
        147};
        148
        149
        150/**
        151 * @return {string} The name of the test.
        152 */
        153goog.testing.TestCase.prototype.getName = function() {
        154 return this.name_;
        155};
        156
        157
        158/**
        159 * The maximum amount of time that the test can run before we force it to be
        160 * async. This prevents the test runner from blocking the browser and
        161 * potentially hurting the Selenium test harness.
        162 * @type {number}
        163 */
        164goog.testing.TestCase.maxRunTime = 200;
        165
        166
        167/**
        168 * The order to run the auto-discovered tests in.
        169 * @type {string}
        170 */
        171goog.testing.TestCase.prototype.order = goog.testing.TestCase.Order.SORTED;
        172
        173
        174/**
        175 * Save a reference to {@code window.setTimeout}, so any code that overrides the
        176 * default behavior (the MockClock, for example) doesn't affect our runner.
        177 * @type {function((Function|string), number, *=): number}
        178 * @private
        179 */
        180goog.testing.TestCase.protectedSetTimeout_ = goog.global.setTimeout;
        181
        182
        183/**
        184 * Save a reference to {@code window.clearTimeout}, so any code that overrides
        185 * the default behavior (e.g. MockClock) doesn't affect our runner.
        186 * @type {function((null|number|undefined)): void}
        187 * @private
        188 */
        189goog.testing.TestCase.protectedClearTimeout_ = goog.global.clearTimeout;
        190
        191
        192/**
        193 * Save a reference to {@code window.Date}, so any code that overrides
        194 * the default behavior doesn't affect our runner.
        195 * @type {function(new: Date)}
        196 * @private
        197 */
        198goog.testing.TestCase.protectedDate_ = Date;
        199
        200
        201/**
        202 * Saved string referencing goog.global.setTimeout's string serialization. IE
        203 * sometimes fails to uphold equality for setTimeout, but the string version
        204 * stays the same.
        205 * @type {string}
        206 * @private
        207 */
        208goog.testing.TestCase.setTimeoutAsString_ = String(goog.global.setTimeout);
        209
        210
        211/**
        212 * TODO(user) replace this with prototype.currentTest.
        213 * Name of the current test that is running, or null if none is running.
        214 * @type {?string}
        215 */
        216goog.testing.TestCase.currentTestName = null;
        217
        218
        219/**
        220 * Avoid a dependency on goog.userAgent and keep our own reference of whether
        221 * the browser is IE.
        222 * @type {boolean}
        223 */
        224goog.testing.TestCase.IS_IE = typeof opera == 'undefined' &&
        225 !!goog.global.navigator &&
        226 goog.global.navigator.userAgent.indexOf('MSIE') != -1;
        227
        228
        229/**
        230 * Exception object that was detected before a test runs.
        231 * @type {*}
        232 * @protected
        233 */
        234goog.testing.TestCase.prototype.exceptionBeforeTest;
        235
        236
        237/**
        238 * Whether the test case has ever tried to execute.
        239 * @type {boolean}
        240 */
        241goog.testing.TestCase.prototype.started = false;
        242
        243
        244/**
        245 * Whether the test case is running.
        246 * @type {boolean}
        247 */
        248goog.testing.TestCase.prototype.running = false;
        249
        250
        251/**
        252 * Timestamp for when the test was started.
        253 * @type {number}
        254 * @private
        255 */
        256goog.testing.TestCase.prototype.startTime_ = 0;
        257
        258
        259/**
        260 * Time since the last batch of tests was started, if batchTime exceeds
        261 * {@link #maxRunTime} a timeout will be used to stop the tests blocking the
        262 * browser and a new batch will be started.
        263 * @type {number}
        264 * @private
        265 */
        266goog.testing.TestCase.prototype.batchTime_ = 0;
        267
        268
        269/**
        270 * Pointer to the current test.
        271 * @type {number}
        272 * @private
        273 */
        274goog.testing.TestCase.prototype.currentTestPointer_ = 0;
        275
        276
        277/**
        278 * Optional callback that will be executed when the test has finalized.
        279 * @type {Function}
        280 * @private
        281 */
        282goog.testing.TestCase.prototype.onCompleteCallback_ = null;
        283
        284
        285/**
        286 * Adds a new test to the test case.
        287 * @param {goog.testing.TestCase.Test} test The test to add.
        288 */
        289goog.testing.TestCase.prototype.add = function(test) {
        290 if (this.started) {
        291 throw Error('Tests cannot be added after execute() has been called. ' +
        292 'Test: ' + test.name);
        293 }
        294
        295 this.tests_.push(test);
        296};
        297
        298
        299/**
        300 * Creates and adds a new test.
        301 *
        302 * Convenience function to make syntax less awkward when not using automatic
        303 * test discovery.
        304 *
        305 * @param {string} name The test name.
        306 * @param {!Function} ref Reference to the test function.
        307 * @param {!Object=} opt_scope Optional scope that the test function should be
        308 * called in.
        309 */
        310goog.testing.TestCase.prototype.addNewTest = function(name, ref, opt_scope) {
        311 var test = new goog.testing.TestCase.Test(name, ref, opt_scope || this);
        312 this.add(test);
        313};
        314
        315
        316/**
        317 * Sets the tests.
        318 * @param {!Array.<goog.testing.TestCase.Test>} tests A new test array.
        319 * @protected
        320 */
        321goog.testing.TestCase.prototype.setTests = function(tests) {
        322 this.tests_ = tests;
        323};
        324
        325
        326/**
        327 * Gets the tests.
        328 * @return {!Array.<goog.testing.TestCase.Test>} The test array.
        329 */
        330goog.testing.TestCase.prototype.getTests = function() {
        331 return this.tests_;
        332};
        333
        334
        335/**
        336 * Returns the number of tests contained in the test case.
        337 * @return {number} The number of tests.
        338 */
        339goog.testing.TestCase.prototype.getCount = function() {
        340 return this.tests_.length;
        341};
        342
        343
        344/**
        345 * Returns the number of tests actually run in the test case, i.e. subtracting
        346 * any which are skipped.
        347 * @return {number} The number of un-ignored tests.
        348 */
        349goog.testing.TestCase.prototype.getActuallyRunCount = function() {
        350 return this.testsToRun_ ? goog.object.getCount(this.testsToRun_) : 0;
        351};
        352
        353
        354/**
        355 * Returns the current test and increments the pointer.
        356 * @return {goog.testing.TestCase.Test} The current test case.
        357 */
        358goog.testing.TestCase.prototype.next = function() {
        359 var test;
        360 while ((test = this.tests_[this.currentTestPointer_++])) {
        361 if (!this.testsToRun_ || this.testsToRun_[test.name] ||
        362 this.testsToRun_[this.currentTestPointer_ - 1]) {
        363 return test;
        364 }
        365 }
        366 return null;
        367};
        368
        369
        370/**
        371 * Resets the test case pointer, so that next returns the first test.
        372 */
        373goog.testing.TestCase.prototype.reset = function() {
        374 this.currentTestPointer_ = 0;
        375 this.result_ = new goog.testing.TestCase.Result(this);
        376};
        377
        378
        379/**
        380 * Sets the callback function that should be executed when the tests have
        381 * completed.
        382 * @param {Function} fn The callback function.
        383 */
        384goog.testing.TestCase.prototype.setCompletedCallback = function(fn) {
        385 this.onCompleteCallback_ = fn;
        386};
        387
        388
        389/**
        390 * Can be overridden in test classes to indicate whether the tests in a case
        391 * should be run in that particular situation. For example, this could be used
        392 * to stop tests running in a particular browser, where browser support for
        393 * the class under test was absent.
        394 * @return {boolean} Whether any of the tests in the case should be run.
        395 */
        396goog.testing.TestCase.prototype.shouldRunTests = function() {
        397 return true;
        398};
        399
        400
        401/**
        402 * Executes each of the tests.
        403 */
        404goog.testing.TestCase.prototype.execute = function() {
        405 this.started = true;
        406 this.reset();
        407 this.startTime_ = this.now();
        408 this.running = true;
        409 this.result_.totalCount = this.getCount();
        410
        411 if (!this.shouldRunTests()) {
        412 this.log('shouldRunTests() returned false, skipping these tests.');
        413 this.result_.testSuppressed = true;
        414 this.finalize();
        415 return;
        416 }
        417
        418 this.log('Starting tests: ' + this.name_);
        419 this.cycleTests();
        420};
        421
        422
        423/**
        424 * Finalizes the test case, called when the tests have finished executing.
        425 */
        426goog.testing.TestCase.prototype.finalize = function() {
        427 this.saveMessage('Done');
        428
        429 this.tearDownPage();
        430
        431 var restoredSetTimeout =
        432 goog.testing.TestCase.protectedSetTimeout_ == goog.global.setTimeout &&
        433 goog.testing.TestCase.protectedClearTimeout_ == goog.global.clearTimeout;
        434 if (!restoredSetTimeout && goog.testing.TestCase.IS_IE &&
        435 String(goog.global.setTimeout) ==
        436 goog.testing.TestCase.setTimeoutAsString_) {
        437 // In strange cases, IE's value of setTimeout *appears* to change, but
        438 // the string representation stays stable.
        439 restoredSetTimeout = true;
        440 }
        441
        442 if (!restoredSetTimeout) {
        443 var message = 'ERROR: Test did not restore setTimeout and clearTimeout';
        444 this.saveMessage(message);
        445 var err = new goog.testing.TestCase.Error(this.name_, message);
        446 this.result_.errors.push(err);
        447 }
        448 goog.global.clearTimeout = goog.testing.TestCase.protectedClearTimeout_;
        449 goog.global.setTimeout = goog.testing.TestCase.protectedSetTimeout_;
        450 this.endTime_ = this.now();
        451 this.running = false;
        452 this.result_.runTime = this.endTime_ - this.startTime_;
        453 this.result_.numFilesLoaded = this.countNumFilesLoaded_();
        454 this.result_.complete = true;
        455
        456 this.log(this.result_.getSummary());
        457 if (this.result_.isSuccess()) {
        458 this.log('Tests complete');
        459 } else {
        460 this.log('Tests Failed');
        461 }
        462 if (this.onCompleteCallback_) {
        463 var fn = this.onCompleteCallback_;
        464 // Execute's the completed callback in the context of the global object.
        465 fn();
        466 this.onCompleteCallback_ = null;
        467 }
        468};
        469
        470
        471/**
        472 * Saves a message to the result set.
        473 * @param {string} message The message to save.
        474 */
        475goog.testing.TestCase.prototype.saveMessage = function(message) {
        476 this.result_.messages.push(this.getTimeStamp_() + ' ' + message);
        477};
        478
        479
        480/**
        481 * @return {boolean} Whether the test case is running inside the multi test
        482 * runner.
        483 */
        484goog.testing.TestCase.prototype.isInsideMultiTestRunner = function() {
        485 var top = goog.global['top'];
        486 return top && typeof top['_allTests'] != 'undefined';
        487};
        488
        489
        490/**
        491 * Logs an object to the console, if available.
        492 * @param {*} val The value to log. Will be ToString'd.
        493 */
        494goog.testing.TestCase.prototype.log = function(val) {
        495 if (!this.isInsideMultiTestRunner() && goog.global.console) {
        496 if (typeof val == 'string') {
        497 val = this.getTimeStamp_() + ' : ' + val;
        498 }
        499 if (val instanceof Error && val.stack) {
        500 // Chrome does console.log asynchronously in a different process
        501 // (http://code.google.com/p/chromium/issues/detail?id=50316).
        502 // This is an acute problem for Errors, which almost never survive.
        503 // Grab references to the immutable strings so they survive.
        504 goog.global.console.log(val, val.message, val.stack);
        505 // TODO(gboyer): Consider for Chrome cloning any object if we can ensure
        506 // there are no circular references.
        507 } else {
        508 goog.global.console.log(val);
        509 }
        510 }
        511};
        512
        513
        514/**
        515 * @return {boolean} Whether the test was a success.
        516 */
        517goog.testing.TestCase.prototype.isSuccess = function() {
        518 return !!this.result_ && this.result_.isSuccess();
        519};
        520
        521
        522/**
        523 * Returns a string detailing the results from the test.
        524 * @param {boolean=} opt_verbose If true results will include data about all
        525 * tests, not just what failed.
        526 * @return {string} The results from the test.
        527 */
        528goog.testing.TestCase.prototype.getReport = function(opt_verbose) {
        529 var rv = [];
        530
        531 if (this.running) {
        532 rv.push(this.name_ + ' [RUNNING]');
        533 } else {
        534 var label = this.result_.isSuccess() ? 'PASSED' : 'FAILED';
        535 rv.push(this.name_ + ' [' + label + ']');
        536 }
        537
        538 if (goog.global.location) {
        539 rv.push(this.trimPath_(goog.global.location.href));
        540 }
        541
        542 rv.push(this.result_.getSummary());
        543
        544 if (opt_verbose) {
        545 rv.push('.', this.result_.messages.join('\n'));
        546 } else if (!this.result_.isSuccess()) {
        547 rv.push(this.result_.errors.join('\n'));
        548 }
        549
        550 rv.push(' ');
        551
        552 return rv.join('\n');
        553};
        554
        555
        556/**
        557 * Returns the amount of time it took for the test to run.
        558 * @return {number} The run time, in milliseconds.
        559 */
        560goog.testing.TestCase.prototype.getRunTime = function() {
        561 return this.result_.runTime;
        562};
        563
        564
        565/**
        566 * Returns the number of script files that were loaded in order to run the test.
        567 * @return {number} The number of script files.
        568 */
        569goog.testing.TestCase.prototype.getNumFilesLoaded = function() {
        570 return this.result_.numFilesLoaded;
        571};
        572
        573
        574/**
        575 * Returns the test results object: a map from test names to a list of test
        576 * failures (if any exist).
        577 * @return {!Object.<string, !Array.<string>>} Tests results object.
        578 */
        579goog.testing.TestCase.prototype.getTestResults = function() {
        580 return this.result_.resultsByName;
        581};
        582
        583
        584/**
        585 * Executes each of the tests.
        586 * Overridable by the individual test case. This allows test cases to defer
        587 * when the test is actually started. If overridden, finalize must be called
        588 * by the test to indicate it has finished.
        589 */
        590goog.testing.TestCase.prototype.runTests = function() {
        591 try {
        592 this.setUpPage();
        593 } catch (e) {
        594 this.exceptionBeforeTest = e;
        595 }
        596 this.execute();
        597};
        598
        599
        600/**
        601 * Reorders the tests depending on the {@code order} field.
        602 * @param {Array.<goog.testing.TestCase.Test>} tests An array of tests to
        603 * reorder.
        604 * @private
        605 */
        606goog.testing.TestCase.prototype.orderTests_ = function(tests) {
        607 switch (this.order) {
        608 case goog.testing.TestCase.Order.RANDOM:
        609 // Fisher-Yates shuffle
        610 var i = tests.length;
        611 while (i > 1) {
        612 // goog.math.randomInt is inlined to reduce dependencies.
        613 var j = Math.floor(Math.random() * i); // exclusive
        614 i--;
        615 var tmp = tests[i];
        616 tests[i] = tests[j];
        617 tests[j] = tmp;
        618 }
        619 break;
        620
        621 case goog.testing.TestCase.Order.SORTED:
        622 tests.sort(function(t1, t2) {
        623 if (t1.name == t2.name) {
        624 return 0;
        625 }
        626 return t1.name < t2.name ? -1 : 1;
        627 });
        628 break;
        629
        630 // Do nothing for NATURAL.
        631 }
        632};
        633
        634
        635/**
        636 * Gets list of objects that potentially contain test cases. For IE 8 and below,
        637 * this is the global "this" (for properties set directly on the global this or
        638 * window) and the RuntimeObject (for global variables and functions). For all
        639 * other browsers, the array simply contains the global this.
        640 *
        641 * @param {string=} opt_prefix An optional prefix. If specified, only get things
        642 * under this prefix. Note that the prefix is only honored in IE, since it
        643 * supports the RuntimeObject:
        644 * http://msdn.microsoft.com/en-us/library/ff521039%28VS.85%29.aspx
        645 * TODO: Remove this option.
        646 * @return {!Array.<!Object>} A list of objects that should be inspected.
        647 */
        648goog.testing.TestCase.prototype.getGlobals = function(opt_prefix) {
        649 return goog.testing.TestCase.getGlobals(opt_prefix);
        650};
        651
        652
        653/**
        654 * Gets list of objects that potentially contain test cases. For IE 8 and below,
        655 * this is the global "this" (for properties set directly on the global this or
        656 * window) and the RuntimeObject (for global variables and functions). For all
        657 * other browsers, the array simply contains the global this.
        658 *
        659 * @param {string=} opt_prefix An optional prefix. If specified, only get things
        660 * under this prefix. Note that the prefix is only honored in IE, since it
        661 * supports the RuntimeObject:
        662 * http://msdn.microsoft.com/en-us/library/ff521039%28VS.85%29.aspx
        663 * TODO: Remove this option.
        664 * @return {!Array.<!Object>} A list of objects that should be inspected.
        665 */
        666goog.testing.TestCase.getGlobals = function(opt_prefix) {
        667 // Look in the global scope for most browsers, on IE we use the little known
        668 // RuntimeObject which holds references to all globals. We reference this
        669 // via goog.global so that there isn't an aliasing that throws an exception
        670 // in Firefox.
        671 return typeof goog.global['RuntimeObject'] != 'undefined' ?
        672 [goog.global['RuntimeObject']((opt_prefix || '') + '*'), goog.global] :
        673 [goog.global];
        674};
        675
        676
        677/**
        678 * Gets called before any tests are executed. Can be overridden to set up the
        679 * environment for the whole test case.
        680 */
        681goog.testing.TestCase.prototype.setUpPage = function() {};
        682
        683
        684/**
        685 * Gets called after all tests have been executed. Can be overridden to tear
        686 * down the entire test case.
        687 */
        688goog.testing.TestCase.prototype.tearDownPage = function() {};
        689
        690
        691/**
        692 * Gets called before every goog.testing.TestCase.Test is been executed. Can be
        693 * overridden to add set up functionality to each test.
        694 */
        695goog.testing.TestCase.prototype.setUp = function() {};
        696
        697
        698/**
        699 * Gets called after every goog.testing.TestCase.Test has been executed. Can be
        700 * overriden to add tear down functionality to each test.
        701 */
        702goog.testing.TestCase.prototype.tearDown = function() {};
        703
        704
        705/**
        706 * @return {string} The function name prefix used to auto-discover tests.
        707 * @protected
        708 */
        709goog.testing.TestCase.prototype.getAutoDiscoveryPrefix = function() {
        710 return 'test';
        711};
        712
        713
        714/**
        715 * @return {number} Time since the last batch of tests was started.
        716 * @protected
        717 */
        718goog.testing.TestCase.prototype.getBatchTime = function() {
        719 return this.batchTime_;
        720};
        721
        722
        723/**
        724 * @param {number} batchTime Time since the last batch of tests was started.
        725 * @protected
        726 */
        727goog.testing.TestCase.prototype.setBatchTime = function(batchTime) {
        728 this.batchTime_ = batchTime;
        729};
        730
        731
        732/**
        733 * Creates a {@code goog.testing.TestCase.Test} from an auto-discovered
        734 * function.
        735 * @param {string} name The name of the function.
        736 * @param {function() : void} ref The auto-discovered function.
        737 * @return {!goog.testing.TestCase.Test} The newly created test.
        738 * @protected
        739 */
        740goog.testing.TestCase.prototype.createTestFromAutoDiscoveredFunction =
        741 function(name, ref) {
        742 return new goog.testing.TestCase.Test(name, ref, goog.global);
        743};
        744
        745
        746/**
        747 * Adds any functions defined in the global scope that correspond to
        748 * lifecycle events for the test case. Overrides setUp, tearDown, setUpPage,
        749 * tearDownPage and runTests if they are defined.
        750 */
        751goog.testing.TestCase.prototype.autoDiscoverLifecycle = function() {
        752 if (goog.global['setUp']) {
        753 this.setUp = goog.bind(goog.global['setUp'], goog.global);
        754 }
        755 if (goog.global['tearDown']) {
        756 this.tearDown = goog.bind(goog.global['tearDown'], goog.global);
        757 }
        758 if (goog.global['setUpPage']) {
        759 this.setUpPage = goog.bind(goog.global['setUpPage'], goog.global);
        760 }
        761 if (goog.global['tearDownPage']) {
        762 this.tearDownPage = goog.bind(goog.global['tearDownPage'], goog.global);
        763 }
        764 if (goog.global['runTests']) {
        765 this.runTests = goog.bind(goog.global['runTests'], goog.global);
        766 }
        767 if (goog.global['shouldRunTests']) {
        768 this.shouldRunTests = goog.bind(goog.global['shouldRunTests'], goog.global);
        769 }
        770};
        771
        772
        773/**
        774 * Adds any functions defined in the global scope that are prefixed with "test"
        775 * to the test case.
        776 */
        777goog.testing.TestCase.prototype.autoDiscoverTests = function() {
        778 var prefix = this.getAutoDiscoveryPrefix();
        779 var testSources = this.getGlobals(prefix);
        780
        781 var foundTests = [];
        782
        783 for (var i = 0; i < testSources.length; i++) {
        784 var testSource = testSources[i];
        785 for (var name in testSource) {
        786 if ((new RegExp('^' + prefix)).test(name)) {
        787 var ref;
        788 try {
        789 ref = testSource[name];
        790 } catch (ex) {
        791 // NOTE(brenneman): When running tests from a file:// URL on Firefox
        792 // 3.5 for Windows, any reference to goog.global.sessionStorage raises
        793 // an "Operation is not supported" exception. Ignore any exceptions
        794 // raised by simply accessing global properties.
        795 ref = undefined;
        796 }
        797
        798 if (goog.isFunction(ref)) {
        799 foundTests.push(this.createTestFromAutoDiscoveredFunction(name, ref));
        800 }
        801 }
        802 }
        803 }
        804
        805 this.orderTests_(foundTests);
        806
        807 for (var i = 0; i < foundTests.length; i++) {
        808 this.add(foundTests[i]);
        809 }
        810
        811 this.log(this.getCount() + ' tests auto-discovered');
        812
        813 // TODO(user): Do this as a separate call. Unfortunately, a lot of projects
        814 // currently override autoDiscoverTests and expect lifecycle events to be
        815 // registered as a part of this call.
        816 this.autoDiscoverLifecycle();
        817};
        818
        819
        820/**
        821 * Checks to see if the test should be marked as failed before it is run.
        822 *
        823 * If there was an error in setUpPage, we treat that as a failure for all tests
        824 * and mark them all as having failed.
        825 *
        826 * @param {goog.testing.TestCase.Test} testCase The current test case.
        827 * @return {boolean} Whether the test was marked as failed.
        828 * @protected
        829 */
        830goog.testing.TestCase.prototype.maybeFailTestEarly = function(testCase) {
        831 if (this.exceptionBeforeTest) {
        832 // We just use the first error to report an error on a failed test.
        833 testCase.name = 'setUpPage for ' + testCase.name;
        834 this.doError(testCase, this.exceptionBeforeTest);
        835 return true;
        836 }
        837 return false;
        838};
        839
        840
        841/**
        842 * Cycles through the tests, breaking out using a setTimeout if the execution
        843 * time has execeeded {@link #maxRunTime}.
        844 */
        845goog.testing.TestCase.prototype.cycleTests = function() {
        846 this.saveMessage('Start');
        847 this.batchTime_ = this.now();
        848 var nextTest;
        849 while ((nextTest = this.next()) && this.running) {
        850 this.result_.runCount++;
        851 // Execute the test and handle the error, we execute all tests rather than
        852 // stopping after a single error.
        853 var cleanedUp = false;
        854 try {
        855 this.log('Running test: ' + nextTest.name);
        856
        857 if (this.maybeFailTestEarly(nextTest)) {
        858 cleanedUp = true;
        859 } else {
        860 goog.testing.TestCase.currentTestName = nextTest.name;
        861 this.setUp();
        862 nextTest.execute();
        863 this.tearDown();
        864 goog.testing.TestCase.currentTestName = null;
        865
        866 cleanedUp = true;
        867
        868 this.doSuccess(nextTest);
        869 }
        870 } catch (e) {
        871 this.doError(nextTest, e);
        872
        873 if (!cleanedUp) {
        874 try {
        875 this.tearDown();
        876 } catch (e2) {} // Fail silently if tearDown is throwing the errors.
        877 }
        878 }
        879
        880 // If the max run time is exceeded call this function again async so as not
        881 // to block the browser.
        882 if (this.currentTestPointer_ < this.tests_.length &&
        883 this.now() - this.batchTime_ > goog.testing.TestCase.maxRunTime) {
        884 this.saveMessage('Breaking async');
        885 this.timeout(goog.bind(this.cycleTests, this), 0);
        886 return;
        887 }
        888 }
        889 // Tests are done.
        890 this.finalize();
        891};
        892
        893
        894/**
        895 * Counts the number of files that were loaded for dependencies that are
        896 * required to run the test.
        897 * @return {number} The number of files loaded.
        898 * @private
        899 */
        900goog.testing.TestCase.prototype.countNumFilesLoaded_ = function() {
        901 var scripts = document.getElementsByTagName('script');
        902 var count = 0;
        903 for (var i = 0, n = scripts.length; i < n; i++) {
        904 if (scripts[i].src) {
        905 count++;
        906 }
        907 }
        908 return count;
        909};
        910
        911
        912/**
        913 * Calls a function after a delay, using the protected timeout.
        914 * @param {Function} fn The function to call.
        915 * @param {number} time Delay in milliseconds.
        916 * @return {number} The timeout id.
        917 * @protected
        918 */
        919goog.testing.TestCase.prototype.timeout = function(fn, time) {
        920 // NOTE: invoking protectedSetTimeout_ as a member of goog.testing.TestCase
        921 // would result in an Illegal Invocation error. The method must be executed
        922 // with the global context.
        923 var protectedSetTimeout = goog.testing.TestCase.protectedSetTimeout_;
        924 return protectedSetTimeout(fn, time);
        925};
        926
        927
        928/**
        929 * Clears a timeout created by {@code this.timeout()}.
        930 * @param {number} id A timeout id.
        931 * @protected
        932 */
        933goog.testing.TestCase.prototype.clearTimeout = function(id) {
        934 // NOTE: see execution note for protectedSetTimeout above.
        935 var protectedClearTimeout = goog.testing.TestCase.protectedClearTimeout_;
        936 protectedClearTimeout(id);
        937};
        938
        939
        940/**
        941 * @return {number} The current time in milliseconds, don't use goog.now as some
        942 * tests override it.
        943 * @protected
        944 */
        945goog.testing.TestCase.prototype.now = function() {
        946 // Cannot use "new goog.testing.TestCase.protectedDate_()" due to b/8323223.
        947 var protectedDate = goog.testing.TestCase.protectedDate_;
        948 return new protectedDate().getTime();
        949};
        950
        951
        952/**
        953 * Returns the current time.
        954 * @return {string} HH:MM:SS.
        955 * @private
        956 */
        957goog.testing.TestCase.prototype.getTimeStamp_ = function() {
        958 // Cannot use "new goog.testing.TestCase.protectedDate_()" due to b/8323223.
        959 var protectedDate = goog.testing.TestCase.protectedDate_;
        960 var d = new protectedDate();
        961
        962 // Ensure millis are always 3-digits
        963 var millis = '00' + d.getMilliseconds();
        964 millis = millis.substr(millis.length - 3);
        965
        966 return this.pad_(d.getHours()) + ':' + this.pad_(d.getMinutes()) + ':' +
        967 this.pad_(d.getSeconds()) + '.' + millis;
        968};
        969
        970
        971/**
        972 * Pads a number to make it have a leading zero if it's less than 10.
        973 * @param {number} number The number to pad.
        974 * @return {string} The resulting string.
        975 * @private
        976 */
        977goog.testing.TestCase.prototype.pad_ = function(number) {
        978 return number < 10 ? '0' + number : String(number);
        979};
        980
        981
        982/**
        983 * Trims a path to be only that after google3.
        984 * @param {string} path The path to trim.
        985 * @return {string} The resulting string.
        986 * @private
        987 */
        988goog.testing.TestCase.prototype.trimPath_ = function(path) {
        989 return path.substring(path.indexOf('google3') + 8);
        990};
        991
        992
        993/**
        994 * Handles a test that passed.
        995 * @param {goog.testing.TestCase.Test} test The test that passed.
        996 * @protected
        997 */
        998goog.testing.TestCase.prototype.doSuccess = function(test) {
        999 this.result_.successCount++;
        1000 // An empty list of error messages indicates that the test passed.
        1001 // If we already have a failure for this test, do not set to empty list.
        1002 if (!(test.name in this.result_.resultsByName)) {
        1003 this.result_.resultsByName[test.name] = [];
        1004 }
        1005 var message = test.name + ' : PASSED';
        1006 this.saveMessage(message);
        1007 this.log(message);
        1008};
        1009
        1010
        1011/**
        1012 * Handles a test that failed.
        1013 * @param {goog.testing.TestCase.Test} test The test that failed.
        1014 * @param {*=} opt_e The exception object associated with the
        1015 * failure or a string.
        1016 * @protected
        1017 */
        1018goog.testing.TestCase.prototype.doError = function(test, opt_e) {
        1019 var message = test.name + ' : FAILED';
        1020 this.log(message);
        1021 this.saveMessage(message);
        1022 var err = this.logError(test.name, opt_e);
        1023 this.result_.errors.push(err);
        1024 if (test.name in this.result_.resultsByName) {
        1025 this.result_.resultsByName[test.name].push(err.toString());
        1026 } else {
        1027 this.result_.resultsByName[test.name] = [err.toString()];
        1028 }
        1029};
        1030
        1031
        1032/**
        1033 * @param {string} name Failed test name.
        1034 * @param {*=} opt_e The exception object associated with the
        1035 * failure or a string.
        1036 * @return {!goog.testing.TestCase.Error} Error object.
        1037 */
        1038goog.testing.TestCase.prototype.logError = function(name, opt_e) {
        1039 var errMsg = null;
        1040 var stack = null;
        1041 if (opt_e) {
        1042 this.log(opt_e);
        1043 if (goog.isString(opt_e)) {
        1044 errMsg = opt_e;
        1045 } else {
        1046 errMsg = opt_e.message || opt_e.description || opt_e.toString();
        1047 stack = opt_e.stack ? goog.testing.stacktrace.canonicalize(opt_e.stack) :
        1048 opt_e['stackTrace'];
        1049 }
        1050 } else {
        1051 errMsg = 'An unknown error occurred';
        1052 }
        1053 var err = new goog.testing.TestCase.Error(name, errMsg, stack);
        1054
        1055 // Avoid double logging.
        1056 if (!opt_e || !opt_e['isJsUnitException'] ||
        1057 !opt_e['loggedJsUnitException']) {
        1058 this.saveMessage(err.toString());
        1059 }
        1060 if (opt_e && opt_e['isJsUnitException']) {
        1061 opt_e['loggedJsUnitException'] = true;
        1062 }
        1063
        1064 return err;
        1065};
        1066
        1067
        1068
        1069/**
        1070 * A class representing a single test function.
        1071 * @param {string} name The test name.
        1072 * @param {Function} ref Reference to the test function.
        1073 * @param {Object=} opt_scope Optional scope that the test function should be
        1074 * called in.
        1075 * @constructor
        1076 */
        1077goog.testing.TestCase.Test = function(name, ref, opt_scope) {
        1078 /**
        1079 * The name of the test.
        1080 * @type {string}
        1081 */
        1082 this.name = name;
        1083
        1084 /**
        1085 * Reference to the test function.
        1086 * @type {Function}
        1087 */
        1088 this.ref = ref;
        1089
        1090 /**
        1091 * Scope that the test function should be called in.
        1092 * @type {Object}
        1093 */
        1094 this.scope = opt_scope || null;
        1095};
        1096
        1097
        1098/**
        1099 * Executes the test function.
        1100 */
        1101goog.testing.TestCase.Test.prototype.execute = function() {
        1102 this.ref.call(this.scope);
        1103};
        1104
        1105
        1106
        1107/**
        1108 * A class for representing test results. A bag of public properties.
        1109 * @param {goog.testing.TestCase} testCase The test case that owns this result.
        1110 * @constructor
        1111 * @final
        1112 */
        1113goog.testing.TestCase.Result = function(testCase) {
        1114 /**
        1115 * The test case that owns this result.
        1116 * @type {goog.testing.TestCase}
        1117 * @private
        1118 */
        1119 this.testCase_ = testCase;
        1120
        1121 /**
        1122 * Total number of tests that should have been run.
        1123 * @type {number}
        1124 */
        1125 this.totalCount = 0;
        1126
        1127 /**
        1128 * Total number of tests that were actually run.
        1129 * @type {number}
        1130 */
        1131 this.runCount = 0;
        1132
        1133 /**
        1134 * Number of successful tests.
        1135 * @type {number}
        1136 */
        1137 this.successCount = 0;
        1138
        1139 /**
        1140 * The amount of time the tests took to run.
        1141 * @type {number}
        1142 */
        1143 this.runTime = 0;
        1144
        1145 /**
        1146 * The number of files loaded to run this test.
        1147 * @type {number}
        1148 */
        1149 this.numFilesLoaded = 0;
        1150
        1151 /**
        1152 * Whether this test case was suppressed by shouldRunTests() returning false.
        1153 * @type {boolean}
        1154 */
        1155 this.testSuppressed = false;
        1156
        1157 /**
        1158 * Test results for each test that was run. The test name is always added
        1159 * as the key in the map, and the array of strings is an optional list
        1160 * of failure messages. If the array is empty, the test passed. Otherwise,
        1161 * the test failed.
        1162 * @type {!Object.<string, !Array.<string>>}
        1163 */
        1164 this.resultsByName = {};
        1165
        1166 /**
        1167 * Errors encountered while running the test.
        1168 * @type {!Array.<goog.testing.TestCase.Error>}
        1169 */
        1170 this.errors = [];
        1171
        1172 /**
        1173 * Messages to show the user after running the test.
        1174 * @type {!Array.<string>}
        1175 */
        1176 this.messages = [];
        1177
        1178 /**
        1179 * Whether the tests have completed.
        1180 * @type {boolean}
        1181 */
        1182 this.complete = false;
        1183};
        1184
        1185
        1186/**
        1187 * @return {boolean} Whether the test was successful.
        1188 */
        1189goog.testing.TestCase.Result.prototype.isSuccess = function() {
        1190 return this.complete && this.errors.length == 0;
        1191};
        1192
        1193
        1194/**
        1195 * @return {string} A summary of the tests, including total number of tests that
        1196 * passed, failed, and the time taken.
        1197 */
        1198goog.testing.TestCase.Result.prototype.getSummary = function() {
        1199 var summary = this.runCount + ' of ' + this.totalCount + ' tests run in ' +
        1200 this.runTime + 'ms.\n';
        1201 if (this.testSuppressed) {
        1202 summary += 'Tests not run because shouldRunTests() returned false.';
        1203 } else {
        1204 var failures = this.totalCount - this.successCount;
        1205 var suppressionMessage = '';
        1206
        1207 var countOfRunTests = this.testCase_.getActuallyRunCount();
        1208 if (countOfRunTests) {
        1209 failures = countOfRunTests - this.successCount;
        1210 suppressionMessage = ', ' +
        1211 (this.totalCount - countOfRunTests) + ' suppressed by querystring';
        1212 }
        1213 summary += this.successCount + ' passed, ' +
        1214 failures + ' failed' + suppressionMessage + '.\n' +
        1215 Math.round(this.runTime / this.runCount) + ' ms/test. ' +
        1216 this.numFilesLoaded + ' files loaded.';
        1217 }
        1218
        1219 return summary;
        1220};
        1221
        1222
        1223/**
        1224 * Initializes the given test case with the global test runner 'G_testRunner'.
        1225 * @param {goog.testing.TestCase} testCase The test case to install.
        1226 */
        1227goog.testing.TestCase.initializeTestRunner = function(testCase) {
        1228 testCase.autoDiscoverTests();
        1229 var gTestRunner = goog.global['G_testRunner'];
        1230 if (gTestRunner) {
        1231 gTestRunner['initialize'](testCase);
        1232 } else {
        1233 throw Error('G_testRunner is undefined. Please ensure goog.testing.jsunit' +
        1234 ' is included.');
        1235 }
        1236};
        1237
        1238
        1239
        1240/**
        1241 * A class representing an error thrown by the test
        1242 * @param {string} source The name of the test which threw the error.
        1243 * @param {string} message The error message.
        1244 * @param {string=} opt_stack A string showing the execution stack.
        1245 * @constructor
        1246 * @final
        1247 */
        1248goog.testing.TestCase.Error = function(source, message, opt_stack) {
        1249 /**
        1250 * The name of the test which threw the error.
        1251 * @type {string}
        1252 */
        1253 this.source = source;
        1254
        1255 /**
        1256 * Reference to the test function.
        1257 * @type {string}
        1258 */
        1259 this.message = message;
        1260
        1261 /**
        1262 * Scope that the test function should be called in.
        1263 * @type {?string}
        1264 */
        1265 this.stack = opt_stack || null;
        1266};
        1267
        1268
        1269/**
        1270 * Returns a string representing the error object.
        1271 * @return {string} A string representation of the error.
        1272 * @override
        1273 */
        1274goog.testing.TestCase.Error.prototype.toString = function() {
        1275 return 'ERROR in ' + this.source + '\n' +
        1276 this.message + (this.stack ? '\n' + this.stack : '');
        1277};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/testrunner.js.src.html b/docs/api/javascript/source/lib/goog/testing/testrunner.js.src.html new file mode 100644 index 0000000000000..023ab7f47946d --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/testrunner.js.src.html @@ -0,0 +1 @@ +testrunner.js

        lib/goog/testing/testrunner.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 The test runner is a singleton object that is used to execute
        17 * a goog.testing.TestCases, display the results, and expose the results to
        18 * Selenium for automation. If a TestCase hasn't been registered with the
        19 * runner by the time window.onload occurs, the testRunner will try to auto-
        20 * discover JsUnit style test pages.
        21 *
        22 * The hooks for selenium are (see http://go/selenium-hook-setup):-
        23 * - Boolean G_testRunner.isFinished()
        24 * - Boolean G_testRunner.isSuccess()
        25 * - String G_testRunner.getReport()
        26 * - number G_testRunner.getRunTime()
        27 * - Object.<string, Array.<string>> G_testRunner.getTestResults()
        28 *
        29 * Testing code should not have dependencies outside of goog.testing so as to
        30 * reduce the chance of masking missing dependencies.
        31 *
        32 */
        33
        34goog.provide('goog.testing.TestRunner');
        35
        36goog.require('goog.testing.TestCase');
        37
        38
        39
        40/**
        41 * Construct a test runner.
        42 *
        43 * NOTE(user): This is currently pretty weird, I'm essentially trying to
        44 * create a wrapper that the Selenium test can hook into to query the state of
        45 * the running test case, while making goog.testing.TestCase general.
        46 *
        47 * @constructor
        48 */
        49goog.testing.TestRunner = function() {
        50 /**
        51 * Errors that occurred in the window.
        52 * @type {Array.<string>}
        53 */
        54 this.errors = [];
        55};
        56
        57
        58/**
        59 * Reference to the active test case.
        60 * @type {goog.testing.TestCase?}
        61 */
        62goog.testing.TestRunner.prototype.testCase = null;
        63
        64
        65/**
        66 * Whether the test runner has been initialized yet.
        67 * @type {boolean}
        68 */
        69goog.testing.TestRunner.prototype.initialized = false;
        70
        71
        72/**
        73 * Element created in the document to add test results to.
        74 * @type {Element}
        75 * @private
        76 */
        77goog.testing.TestRunner.prototype.logEl_ = null;
        78
        79
        80/**
        81 * Function to use when filtering errors.
        82 * @type {(function(string))?}
        83 * @private
        84 */
        85goog.testing.TestRunner.prototype.errorFilter_ = null;
        86
        87
        88/**
        89 * Whether an empty test case counts as an error.
        90 * @type {boolean}
        91 * @private
        92 */
        93goog.testing.TestRunner.prototype.strict_ = true;
        94
        95
        96/**
        97 * Initializes the test runner.
        98 * @param {goog.testing.TestCase} testCase The test case to initialize with.
        99 */
        100goog.testing.TestRunner.prototype.initialize = function(testCase) {
        101 if (this.testCase && this.testCase.running) {
        102 throw Error('The test runner is already waiting for a test to complete');
        103 }
        104 this.testCase = testCase;
        105 this.initialized = true;
        106};
        107
        108
        109/**
        110 * By default, the test runner is strict, and fails if it runs an empty
        111 * test case.
        112 * @param {boolean} strict Whether the test runner should fail on an empty
        113 * test case.
        114 */
        115goog.testing.TestRunner.prototype.setStrict = function(strict) {
        116 this.strict_ = strict;
        117};
        118
        119
        120/**
        121 * @return {boolean} Whether the test runner should fail on an empty
        122 * test case.
        123 */
        124goog.testing.TestRunner.prototype.isStrict = function() {
        125 return this.strict_;
        126};
        127
        128
        129/**
        130 * Returns true if the test runner is initialized.
        131 * Used by Selenium Hooks.
        132 * @return {boolean} Whether the test runner is active.
        133 */
        134goog.testing.TestRunner.prototype.isInitialized = function() {
        135 return this.initialized;
        136};
        137
        138
        139/**
        140 * Returns true if the test runner is finished.
        141 * Used by Selenium Hooks.
        142 * @return {boolean} Whether the test runner is active.
        143 */
        144goog.testing.TestRunner.prototype.isFinished = function() {
        145 return this.errors.length > 0 ||
        146 this.initialized && !!this.testCase && this.testCase.started &&
        147 !this.testCase.running;
        148};
        149
        150
        151/**
        152 * Returns true if the test case didn't fail.
        153 * Used by Selenium Hooks.
        154 * @return {boolean} Whether the current test returned successfully.
        155 */
        156goog.testing.TestRunner.prototype.isSuccess = function() {
        157 return !this.hasErrors() && !!this.testCase && this.testCase.isSuccess();
        158};
        159
        160
        161/**
        162 * Returns true if the test case runner has errors that were caught outside of
        163 * the test case.
        164 * @return {boolean} Whether there were JS errors.
        165 */
        166goog.testing.TestRunner.prototype.hasErrors = function() {
        167 return this.errors.length > 0;
        168};
        169
        170
        171/**
        172 * Logs an error that occurred. Used in the case of environment setting up
        173 * an onerror handler.
        174 * @param {string} msg Error message.
        175 */
        176goog.testing.TestRunner.prototype.logError = function(msg) {
        177 if (!this.errorFilter_ || this.errorFilter_.call(null, msg)) {
        178 this.errors.push(msg);
        179 }
        180};
        181
        182
        183/**
        184 * Log failure in current running test.
        185 * @param {Error} ex Exception.
        186 */
        187goog.testing.TestRunner.prototype.logTestFailure = function(ex) {
        188 var testName = /** @type {string} */ (goog.testing.TestCase.currentTestName);
        189 if (this.testCase) {
        190 this.testCase.logError(testName, ex);
        191 } else {
        192 // NOTE: Do not forget to log the original exception raised.
        193 throw new Error('Test runner not initialized with a test case. Original ' +
        194 'exception: ' + ex.message);
        195 }
        196};
        197
        198
        199/**
        200 * Sets a function to use as a filter for errors.
        201 * @param {function(string)} fn Filter function.
        202 */
        203goog.testing.TestRunner.prototype.setErrorFilter = function(fn) {
        204 this.errorFilter_ = fn;
        205};
        206
        207
        208/**
        209 * Returns a report of the test case that ran.
        210 * Used by Selenium Hooks.
        211 * @param {boolean=} opt_verbose If true results will include data about all
        212 * tests, not just what failed.
        213 * @return {string} A report summary of the test.
        214 */
        215goog.testing.TestRunner.prototype.getReport = function(opt_verbose) {
        216 var report = [];
        217 if (this.testCase) {
        218 report.push(this.testCase.getReport(opt_verbose));
        219 }
        220 if (this.errors.length > 0) {
        221 report.push('JavaScript errors detected by test runner:');
        222 report.push.apply(report, this.errors);
        223 report.push('\n');
        224 }
        225 return report.join('\n');
        226};
        227
        228
        229/**
        230 * Returns the amount of time it took for the test to run.
        231 * Used by Selenium Hooks.
        232 * @return {number} The run time, in milliseconds.
        233 */
        234goog.testing.TestRunner.prototype.getRunTime = function() {
        235 return this.testCase ? this.testCase.getRunTime() : 0;
        236};
        237
        238
        239/**
        240 * Returns the number of script files that were loaded in order to run the test.
        241 * @return {number} The number of script files.
        242 */
        243goog.testing.TestRunner.prototype.getNumFilesLoaded = function() {
        244 return this.testCase ? this.testCase.getNumFilesLoaded() : 0;
        245};
        246
        247
        248/**
        249 * Executes a test case and prints the results to the window.
        250 */
        251goog.testing.TestRunner.prototype.execute = function() {
        252 if (!this.testCase) {
        253 throw Error('The test runner must be initialized with a test case ' +
        254 'before execute can be called.');
        255 }
        256
        257 if (this.strict_ && this.testCase.getCount() == 0) {
        258 throw Error(
        259 'No tests found in given test case: ' +
        260 this.testCase.getName() + ' ' +
        261 'By default, the test runner fails if a test case has no tests. ' +
        262 'To modify this behavior, see goog.testing.TestRunner\'s ' +
        263 'setStrict() method, or G_testRunner.setStrict()');
        264 }
        265
        266 this.testCase.setCompletedCallback(goog.bind(this.onComplete_, this));
        267 this.testCase.runTests();
        268};
        269
        270
        271/**
        272 * Writes the results to the document when the test case completes.
        273 * @private
        274 */
        275goog.testing.TestRunner.prototype.onComplete_ = function() {
        276 var log = this.testCase.getReport(true);
        277 if (this.errors.length > 0) {
        278 log += '\n' + this.errors.join('\n');
        279 }
        280
        281 if (!this.logEl_) {
        282 var el = document.getElementById('closureTestRunnerLog');
        283 if (el == null) {
        284 el = document.createElement('div');
        285 document.body.appendChild(el);
        286 }
        287 this.logEl_ = el;
        288 }
        289
        290 // Highlight the page to indicate the overall outcome.
        291 this.writeLog(log);
        292
        293 // TODO(user): Make this work with multiple test cases (b/8603638).
        294 var runAgainLink = document.createElement('a');
        295 runAgainLink.style.display = 'inline-block';
        296 runAgainLink.style.fontSize = 'small';
        297 runAgainLink.style.marginBottom = '16px';
        298 runAgainLink.href = '';
        299 runAgainLink.onclick = goog.bind(function() {
        300 this.execute();
        301 return false;
        302 }, this);
        303 runAgainLink.innerHTML = 'Run again without reloading';
        304 this.logEl_.appendChild(runAgainLink);
        305};
        306
        307
        308/**
        309 * Writes a nicely formatted log out to the document.
        310 * @param {string} log The string to write.
        311 */
        312goog.testing.TestRunner.prototype.writeLog = function(log) {
        313 var lines = log.split('\n');
        314 for (var i = 0; i < lines.length; i++) {
        315 var line = lines[i];
        316 var color;
        317 var isFailOrError = /FAILED/.test(line) || /ERROR/.test(line);
        318 if (/PASSED/.test(line)) {
        319 color = 'darkgreen';
        320 } else if (isFailOrError) {
        321 color = 'darkred';
        322 } else {
        323 color = '#333';
        324 }
        325 var div = document.createElement('div');
        326 if (line.substr(0, 2) == '> ') {
        327 // The stack trace may contain links so it has to be interpreted as HTML.
        328 div.innerHTML = line;
        329 } else {
        330 div.appendChild(document.createTextNode(line));
        331 }
        332
        333 var testNameMatch =
        334 /(\S+) (\[[^\]]*] )?: (FAILED|ERROR|PASSED)/.exec(line);
        335 if (testNameMatch) {
        336 // Build a URL to run the test individually. If this test was already
        337 // part of another subset test, we need to overwrite the old runTests
        338 // query parameter. We also need to do this without bringing in any
        339 // extra dependencies, otherwise we could mask missing dependency bugs.
        340 var newSearch = 'runTests=' + testNameMatch[1];
        341 var search = window.location.search;
        342 if (search) {
        343 var oldTests = /runTests=([^&]*)/.exec(search);
        344 if (oldTests) {
        345 newSearch = search.substr(0, oldTests.index) +
        346 newSearch +
        347 search.substr(oldTests.index + oldTests[0].length);
        348 } else {
        349 newSearch = search + '&' + newSearch;
        350 }
        351 } else {
        352 newSearch = '?' + newSearch;
        353 }
        354 var href = window.location.href;
        355 var hash = window.location.hash;
        356 if (hash && hash.charAt(0) != '#') {
        357 hash = '#' + hash;
        358 }
        359 href = href.split('#')[0].split('?')[0] + newSearch + hash;
        360
        361 // Add the link.
        362 var a = document.createElement('A');
        363 a.innerHTML = '(run individually)';
        364 a.style.fontSize = '0.8em';
        365 a.style.color = '#888';
        366 a.href = href;
        367 div.appendChild(document.createTextNode(' '));
        368 div.appendChild(a);
        369 }
        370
        371 div.style.color = color;
        372 div.style.font = 'normal 100% monospace';
        373 div.style.wordWrap = 'break-word';
        374 if (i == 0) {
        375 // Highlight the first line as a header that indicates the test outcome.
        376 div.style.padding = '20px';
        377 div.style.marginBottom = '10px';
        378 if (isFailOrError) {
        379 div.style.border = '5px solid ' + color;
        380 div.style.backgroundColor = '#ffeeee';
        381 } else {
        382 div.style.border = '1px solid black';
        383 div.style.backgroundColor = '#eeffee';
        384 }
        385 }
        386
        387 try {
        388 div.style.whiteSpace = 'pre-wrap';
        389 } catch (e) {
        390 // NOTE(brenneman): IE raises an exception when assigning to pre-wrap.
        391 // Thankfully, it doesn't collapse whitespace when using monospace fonts,
        392 // so it will display correctly if we ignore the exception.
        393 }
        394
        395 if (i < 2) {
        396 div.style.fontWeight = 'bold';
        397 }
        398 this.logEl_.appendChild(div);
        399 }
        400};
        401
        402
        403/**
        404 * Logs a message to the current test case.
        405 * @param {string} s The text to output to the log.
        406 */
        407goog.testing.TestRunner.prototype.log = function(s) {
        408 if (this.testCase) {
        409 this.testCase.log(s);
        410 }
        411};
        412
        413
        414// TODO(nnaze): Properly handle serving test results when multiple test cases
        415// are run.
        416/**
        417 * @return {Object.<string, !Array.<string>>} A map of test names to a list of
        418 * test failures (if any) to provide formatted data for the test runner.
        419 */
        420goog.testing.TestRunner.prototype.getTestResults = function() {
        421 if (this.testCase) {
        422 return this.testCase.getTestResults();
        423 }
        424 return null;
        425};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/testing/watchers.js.src.html b/docs/api/javascript/source/lib/goog/testing/watchers.js.src.html new file mode 100644 index 0000000000000..af097a8e5a3f0 --- /dev/null +++ b/docs/api/javascript/source/lib/goog/testing/watchers.js.src.html @@ -0,0 +1 @@ +watchers.js

        lib/goog/testing/watchers.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 Simple notifiers for the Closure testing framework.
        17 *
        18 * @author johnlenz@google.com (John Lenz)
        19 */
        20
        21goog.provide('goog.testing.watchers');
        22
        23
        24/** @private {!Array.<function()>} */
        25goog.testing.watchers.resetWatchers_ = [];
        26
        27
        28/**
        29 * Fires clock reset watching functions.
        30 */
        31goog.testing.watchers.signalClockReset = function() {
        32 var watchers = goog.testing.watchers.resetWatchers_;
        33 for (var i = 0; i < watchers.length; i++) {
        34 goog.testing.watchers.resetWatchers_[i]();
        35 }
        36};
        37
        38
        39/**
        40 * Enqueues a function to be called when the clock used for setTimeout is reset.
        41 * @param {function()} fn
        42 */
        43goog.testing.watchers.watchClockReset = function(fn) {
        44 goog.testing.watchers.resetWatchers_.push(fn);
        45};
        46
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/uri/uri.js.src.html b/docs/api/javascript/source/lib/goog/uri/uri.js.src.html index b7fbd0fd60785..108deeafbeb55 100644 --- a/docs/api/javascript/source/lib/goog/uri/uri.js.src.html +++ b/docs/api/javascript/source/lib/goog/uri/uri.js.src.html @@ -1 +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 +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 * Reserved characters (see RFC 3986 section 2.2) can be present in
        52 * their percent-encoded form in scheme, domain, and path URI components and
        53 * will not be auto-decoded. For example:
        54 * <code>goog.Uri.parse('rel%61tive/path%2fto/resource').getPath()</code> will
        55 * return <code>relative/path%2fto/resource</code>.
        56 *
        57 * The constructor accepts an optional unparsed, raw URI string. The parser
        58 * is relaxed, so special characters that aren't escaped but don't cause
        59 * ambiguities will not cause parse failures.
        60 *
        61 * All setters return <code>this</code> and so may be chained, a la
        62 * <code>goog.Uri.parse('/foo').setFragment('part').toString()</code>.
        63 *
        64 * @param {*=} opt_uri Optional string URI to parse
        65 * (use goog.Uri.create() to create a URI from parts), or if
        66 * a goog.Uri is passed, a clone is created.
        67 * @param {boolean=} opt_ignoreCase If true, #getParameterValue will ignore
        68 * the case of the parameter name.
        69 *
        70 * @constructor
        71 */
        72goog.Uri = function(opt_uri, opt_ignoreCase) {
        73 // Parse in the uri string
        74 var m;
        75 if (opt_uri instanceof goog.Uri) {
        76 this.ignoreCase_ = goog.isDef(opt_ignoreCase) ?
        77 opt_ignoreCase : opt_uri.getIgnoreCase();
        78 this.setScheme(opt_uri.getScheme());
        79 this.setUserInfo(opt_uri.getUserInfo());
        80 this.setDomain(opt_uri.getDomain());
        81 this.setPort(opt_uri.getPort());
        82 this.setPath(opt_uri.getPath());
        83 this.setQueryData(opt_uri.getQueryData().clone());
        84 this.setFragment(opt_uri.getFragment());
        85 } else if (opt_uri && (m = goog.uri.utils.split(String(opt_uri)))) {
        86 this.ignoreCase_ = !!opt_ignoreCase;
        87
        88 // Set the parts -- decoding as we do so.
        89 // COMPATABILITY NOTE - In IE, unmatched fields may be empty strings,
        90 // whereas in other browsers they will be undefined.
        91 this.setScheme(m[goog.uri.utils.ComponentIndex.SCHEME] || '', true);
        92 this.setUserInfo(m[goog.uri.utils.ComponentIndex.USER_INFO] || '', true);
        93 this.setDomain(m[goog.uri.utils.ComponentIndex.DOMAIN] || '', true);
        94 this.setPort(m[goog.uri.utils.ComponentIndex.PORT]);
        95 this.setPath(m[goog.uri.utils.ComponentIndex.PATH] || '', true);
        96 this.setQueryData(m[goog.uri.utils.ComponentIndex.QUERY_DATA] || '', true);
        97 this.setFragment(m[goog.uri.utils.ComponentIndex.FRAGMENT] || '', true);
        98
        99 } else {
        100 this.ignoreCase_ = !!opt_ignoreCase;
        101 this.queryData_ = new goog.Uri.QueryData(null, null, this.ignoreCase_);
        102 }
        103};
        104
        105
        106/**
        107 * If true, we preserve the type of query parameters set programmatically.
        108 *
        109 * This means that if you set a parameter to a boolean, and then call
        110 * getParameterValue, you will get a boolean back.
        111 *
        112 * If false, we will coerce parameters to strings, just as they would
        113 * appear in real URIs.
        114 *
        115 * TODO(nicksantos): Remove this once people have time to fix all tests.
        116 *
        117 * @type {boolean}
        118 */
        119goog.Uri.preserveParameterTypesCompatibilityFlag = false;
        120
        121
        122/**
        123 * Parameter name added to stop caching.
        124 * @type {string}
        125 */
        126goog.Uri.RANDOM_PARAM = goog.uri.utils.StandardQueryParam.RANDOM;
        127
        128
        129/**
        130 * Scheme such as "http".
        131 * @type {string}
        132 * @private
        133 */
        134goog.Uri.prototype.scheme_ = '';
        135
        136
        137/**
        138 * User credentials in the form "username:password".
        139 * @type {string}
        140 * @private
        141 */
        142goog.Uri.prototype.userInfo_ = '';
        143
        144
        145/**
        146 * Domain part, e.g. "www.google.com".
        147 * @type {string}
        148 * @private
        149 */
        150goog.Uri.prototype.domain_ = '';
        151
        152
        153/**
        154 * Port, e.g. 8080.
        155 * @type {?number}
        156 * @private
        157 */
        158goog.Uri.prototype.port_ = null;
        159
        160
        161/**
        162 * Path, e.g. "/tests/img.png".
        163 * @type {string}
        164 * @private
        165 */
        166goog.Uri.prototype.path_ = '';
        167
        168
        169/**
        170 * Object representing query data.
        171 * @type {!goog.Uri.QueryData}
        172 * @private
        173 */
        174goog.Uri.prototype.queryData_;
        175
        176
        177/**
        178 * The fragment without the #.
        179 * @type {string}
        180 * @private
        181 */
        182goog.Uri.prototype.fragment_ = '';
        183
        184
        185/**
        186 * Whether or not this Uri should be treated as Read Only.
        187 * @type {boolean}
        188 * @private
        189 */
        190goog.Uri.prototype.isReadOnly_ = false;
        191
        192
        193/**
        194 * Whether or not to ignore case when comparing query params.
        195 * @type {boolean}
        196 * @private
        197 */
        198goog.Uri.prototype.ignoreCase_ = false;
        199
        200
        201/**
        202 * @return {string} The string form of the url.
        203 * @override
        204 */
        205goog.Uri.prototype.toString = function() {
        206 var out = [];
        207
        208 var scheme = this.getScheme();
        209 if (scheme) {
        210 out.push(goog.Uri.encodeSpecialChars_(
        211 scheme, goog.Uri.reDisallowedInSchemeOrUserInfo_, true), ':');
        212 }
        213
        214 var domain = this.getDomain();
        215 if (domain) {
        216 out.push('//');
        217
        218 var userInfo = this.getUserInfo();
        219 if (userInfo) {
        220 out.push(goog.Uri.encodeSpecialChars_(
        221 userInfo, goog.Uri.reDisallowedInSchemeOrUserInfo_, true), '@');
        222 }
        223
        224 out.push(goog.Uri.removeDoubleEncoding_(goog.string.urlEncode(domain)));
        225
        226 var port = this.getPort();
        227 if (port != null) {
        228 out.push(':', String(port));
        229 }
        230 }
        231
        232 var path = this.getPath();
        233 if (path) {
        234 if (this.hasDomain() && path.charAt(0) != '/') {
        235 out.push('/');
        236 }
        237 out.push(goog.Uri.encodeSpecialChars_(
        238 path,
        239 path.charAt(0) == '/' ?
        240 goog.Uri.reDisallowedInAbsolutePath_ :
        241 goog.Uri.reDisallowedInRelativePath_,
        242 true));
        243 }
        244
        245 var query = this.getEncodedQuery();
        246 if (query) {
        247 out.push('?', query);
        248 }
        249
        250 var fragment = this.getFragment();
        251 if (fragment) {
        252 out.push('#', goog.Uri.encodeSpecialChars_(
        253 fragment, goog.Uri.reDisallowedInFragment_));
        254 }
        255 return out.join('');
        256};
        257
        258
        259/**
        260 * Resolves the given relative URI (a goog.Uri object), using the URI
        261 * represented by this instance as the base URI.
        262 *
        263 * There are several kinds of relative URIs:<br>
        264 * 1. foo - replaces the last part of the path, the whole query and fragment<br>
        265 * 2. /foo - replaces the the path, the query and fragment<br>
        266 * 3. //foo - replaces everything from the domain on. foo is a domain name<br>
        267 * 4. ?foo - replace the query and fragment<br>
        268 * 5. #foo - replace the fragment only
        269 *
        270 * Additionally, if relative URI has a non-empty path, all ".." and "."
        271 * segments will be resolved, as described in RFC 3986.
        272 *
        273 * @param {goog.Uri} relativeUri The relative URI to resolve.
        274 * @return {!goog.Uri} The resolved URI.
        275 */
        276goog.Uri.prototype.resolve = function(relativeUri) {
        277
        278 var absoluteUri = this.clone();
        279
        280 // we satisfy these conditions by looking for the first part of relativeUri
        281 // that is not blank and applying defaults to the rest
        282
        283 var overridden = relativeUri.hasScheme();
        284
        285 if (overridden) {
        286 absoluteUri.setScheme(relativeUri.getScheme());
        287 } else {
        288 overridden = relativeUri.hasUserInfo();
        289 }
        290
        291 if (overridden) {
        292 absoluteUri.setUserInfo(relativeUri.getUserInfo());
        293 } else {
        294 overridden = relativeUri.hasDomain();
        295 }
        296
        297 if (overridden) {
        298 absoluteUri.setDomain(relativeUri.getDomain());
        299 } else {
        300 overridden = relativeUri.hasPort();
        301 }
        302
        303 var path = relativeUri.getPath();
        304 if (overridden) {
        305 absoluteUri.setPort(relativeUri.getPort());
        306 } else {
        307 overridden = relativeUri.hasPath();
        308 if (overridden) {
        309 // resolve path properly
        310 if (path.charAt(0) != '/') {
        311 // path is relative
        312 if (this.hasDomain() && !this.hasPath()) {
        313 // RFC 3986, section 5.2.3, case 1
        314 path = '/' + path;
        315 } else {
        316 // RFC 3986, section 5.2.3, case 2
        317 var lastSlashIndex = absoluteUri.getPath().lastIndexOf('/');
        318 if (lastSlashIndex != -1) {
        319 path = absoluteUri.getPath().substr(0, lastSlashIndex + 1) + path;
        320 }
        321 }
        322 }
        323 path = goog.Uri.removeDotSegments(path);
        324 }
        325 }
        326
        327 if (overridden) {
        328 absoluteUri.setPath(path);
        329 } else {
        330 overridden = relativeUri.hasQuery();
        331 }
        332
        333 if (overridden) {
        334 absoluteUri.setQueryData(relativeUri.getDecodedQuery());
        335 } else {
        336 overridden = relativeUri.hasFragment();
        337 }
        338
        339 if (overridden) {
        340 absoluteUri.setFragment(relativeUri.getFragment());
        341 }
        342
        343 return absoluteUri;
        344};
        345
        346
        347/**
        348 * Clones the URI instance.
        349 * @return {!goog.Uri} New instance of the URI object.
        350 */
        351goog.Uri.prototype.clone = function() {
        352 return new goog.Uri(this);
        353};
        354
        355
        356/**
        357 * @return {string} The encoded scheme/protocol for the URI.
        358 */
        359goog.Uri.prototype.getScheme = function() {
        360 return this.scheme_;
        361};
        362
        363
        364/**
        365 * Sets the scheme/protocol.
        366 * @param {string} newScheme New scheme value.
        367 * @param {boolean=} opt_decode Optional param for whether to decode new value.
        368 * @return {!goog.Uri} Reference to this URI object.
        369 */
        370goog.Uri.prototype.setScheme = function(newScheme, opt_decode) {
        371 this.enforceReadOnly();
        372 this.scheme_ = opt_decode ? goog.Uri.decodeOrEmpty_(newScheme, true) :
        373 newScheme;
        374
        375 // remove an : at the end of the scheme so somebody can pass in
        376 // window.location.protocol
        377 if (this.scheme_) {
        378 this.scheme_ = this.scheme_.replace(/:$/, '');
        379 }
        380 return this;
        381};
        382
        383
        384/**
        385 * @return {boolean} Whether the scheme has been set.
        386 */
        387goog.Uri.prototype.hasScheme = function() {
        388 return !!this.scheme_;
        389};
        390
        391
        392/**
        393 * @return {string} The decoded user info.
        394 */
        395goog.Uri.prototype.getUserInfo = function() {
        396 return this.userInfo_;
        397};
        398
        399
        400/**
        401 * Sets the userInfo.
        402 * @param {string} newUserInfo New userInfo value.
        403 * @param {boolean=} opt_decode Optional param for whether to decode new value.
        404 * @return {!goog.Uri} Reference to this URI object.
        405 */
        406goog.Uri.prototype.setUserInfo = function(newUserInfo, opt_decode) {
        407 this.enforceReadOnly();
        408 this.userInfo_ = opt_decode ? goog.Uri.decodeOrEmpty_(newUserInfo) :
        409 newUserInfo;
        410 return this;
        411};
        412
        413
        414/**
        415 * @return {boolean} Whether the user info has been set.
        416 */
        417goog.Uri.prototype.hasUserInfo = function() {
        418 return !!this.userInfo_;
        419};
        420
        421
        422/**
        423 * @return {string} The decoded domain.
        424 */
        425goog.Uri.prototype.getDomain = function() {
        426 return this.domain_;
        427};
        428
        429
        430/**
        431 * Sets the domain.
        432 * @param {string} newDomain New domain value.
        433 * @param {boolean=} opt_decode Optional param for whether to decode new value.
        434 * @return {!goog.Uri} Reference to this URI object.
        435 */
        436goog.Uri.prototype.setDomain = function(newDomain, opt_decode) {
        437 this.enforceReadOnly();
        438 this.domain_ = opt_decode ? goog.Uri.decodeOrEmpty_(newDomain, true) :
        439 newDomain;
        440 return this;
        441};
        442
        443
        444/**
        445 * @return {boolean} Whether the domain has been set.
        446 */
        447goog.Uri.prototype.hasDomain = function() {
        448 return !!this.domain_;
        449};
        450
        451
        452/**
        453 * @return {?number} The port number.
        454 */
        455goog.Uri.prototype.getPort = function() {
        456 return this.port_;
        457};
        458
        459
        460/**
        461 * Sets the port number.
        462 * @param {*} newPort Port number. Will be explicitly casted to a number.
        463 * @return {!goog.Uri} Reference to this URI object.
        464 */
        465goog.Uri.prototype.setPort = function(newPort) {
        466 this.enforceReadOnly();
        467
        468 if (newPort) {
        469 newPort = Number(newPort);
        470 if (isNaN(newPort) || newPort < 0) {
        471 throw Error('Bad port number ' + newPort);
        472 }
        473 this.port_ = newPort;
        474 } else {
        475 this.port_ = null;
        476 }
        477
        478 return this;
        479};
        480
        481
        482/**
        483 * @return {boolean} Whether the port has been set.
        484 */
        485goog.Uri.prototype.hasPort = function() {
        486 return this.port_ != null;
        487};
        488
        489
        490/**
        491 * @return {string} The decoded path.
        492 */
        493goog.Uri.prototype.getPath = function() {
        494 return this.path_;
        495};
        496
        497
        498/**
        499 * Sets the path.
        500 * @param {string} newPath New path value.
        501 * @param {boolean=} opt_decode Optional param for whether to decode new value.
        502 * @return {!goog.Uri} Reference to this URI object.
        503 */
        504goog.Uri.prototype.setPath = function(newPath, opt_decode) {
        505 this.enforceReadOnly();
        506 this.path_ = opt_decode ? goog.Uri.decodeOrEmpty_(newPath, true) : newPath;
        507 return this;
        508};
        509
        510
        511/**
        512 * @return {boolean} Whether the path has been set.
        513 */
        514goog.Uri.prototype.hasPath = function() {
        515 return !!this.path_;
        516};
        517
        518
        519/**
        520 * @return {boolean} Whether the query string has been set.
        521 */
        522goog.Uri.prototype.hasQuery = function() {
        523 return this.queryData_.toString() !== '';
        524};
        525
        526
        527/**
        528 * Sets the query data.
        529 * @param {goog.Uri.QueryData|string|undefined} queryData QueryData object.
        530 * @param {boolean=} opt_decode Optional param for whether to decode new value.
        531 * Applies only if queryData is a string.
        532 * @return {!goog.Uri} Reference to this URI object.
        533 */
        534goog.Uri.prototype.setQueryData = function(queryData, opt_decode) {
        535 this.enforceReadOnly();
        536
        537 if (queryData instanceof goog.Uri.QueryData) {
        538 this.queryData_ = queryData;
        539 this.queryData_.setIgnoreCase(this.ignoreCase_);
        540 } else {
        541 if (!opt_decode) {
        542 // QueryData accepts encoded query string, so encode it if
        543 // opt_decode flag is not true.
        544 queryData = goog.Uri.encodeSpecialChars_(queryData,
        545 goog.Uri.reDisallowedInQuery_);
        546 }
        547 this.queryData_ = new goog.Uri.QueryData(queryData, null, this.ignoreCase_);
        548 }
        549
        550 return this;
        551};
        552
        553
        554/**
        555 * Sets the URI query.
        556 * @param {string} newQuery New query value.
        557 * @param {boolean=} opt_decode Optional param for whether to decode new value.
        558 * @return {!goog.Uri} Reference to this URI object.
        559 */
        560goog.Uri.prototype.setQuery = function(newQuery, opt_decode) {
        561 return this.setQueryData(newQuery, opt_decode);
        562};
        563
        564
        565/**
        566 * @return {string} The encoded URI query, not including the ?.
        567 */
        568goog.Uri.prototype.getEncodedQuery = function() {
        569 return this.queryData_.toString();
        570};
        571
        572
        573/**
        574 * @return {string} The decoded URI query, not including the ?.
        575 */
        576goog.Uri.prototype.getDecodedQuery = function() {
        577 return this.queryData_.toDecodedString();
        578};
        579
        580
        581/**
        582 * Returns the query data.
        583 * @return {!goog.Uri.QueryData} QueryData object.
        584 */
        585goog.Uri.prototype.getQueryData = function() {
        586 return this.queryData_;
        587};
        588
        589
        590/**
        591 * @return {string} The encoded URI query, not including the ?.
        592 *
        593 * Warning: This method, unlike other getter methods, returns encoded
        594 * value, instead of decoded one.
        595 */
        596goog.Uri.prototype.getQuery = function() {
        597 return this.getEncodedQuery();
        598};
        599
        600
        601/**
        602 * Sets the value of the named query parameters, clearing previous values for
        603 * that key.
        604 *
        605 * @param {string} key The parameter to set.
        606 * @param {*} value The new value.
        607 * @return {!goog.Uri} Reference to this URI object.
        608 */
        609goog.Uri.prototype.setParameterValue = function(key, value) {
        610 this.enforceReadOnly();
        611 this.queryData_.set(key, value);
        612 return this;
        613};
        614
        615
        616/**
        617 * Sets the values of the named query parameters, clearing previous values for
        618 * that key. Not new values will currently be moved to the end of the query
        619 * string.
        620 *
        621 * So, <code>goog.Uri.parse('foo?a=b&c=d&e=f').setParameterValues('c', ['new'])
        622 * </code> yields <tt>foo?a=b&e=f&c=new</tt>.</p>
        623 *
        624 * @param {string} key The parameter to set.
        625 * @param {*} values The new values. If values is a single
        626 * string then it will be treated as the sole value.
        627 * @return {!goog.Uri} Reference to this URI object.
        628 */
        629goog.Uri.prototype.setParameterValues = function(key, values) {
        630 this.enforceReadOnly();
        631
        632 if (!goog.isArray(values)) {
        633 values = [String(values)];
        634 }
        635
        636 // TODO(nicksantos): This cast shouldn't be necessary.
        637 this.queryData_.setValues(key, /** @type {Array} */ (values));
        638
        639 return this;
        640};
        641
        642
        643/**
        644 * Returns the value<b>s</b> for a given cgi parameter as a list of decoded
        645 * query parameter values.
        646 * @param {string} name The parameter to get values for.
        647 * @return {!Array} The values for a given cgi parameter as a list of
        648 * decoded query parameter values.
        649 */
        650goog.Uri.prototype.getParameterValues = function(name) {
        651 return this.queryData_.getValues(name);
        652};
        653
        654
        655/**
        656 * Returns the first value for a given cgi parameter or undefined if the given
        657 * parameter name does not appear in the query string.
        658 * @param {string} paramName Unescaped parameter name.
        659 * @return {string|undefined} The first value for a given cgi parameter or
        660 * undefined if the given parameter name does not appear in the query
        661 * string.
        662 */
        663goog.Uri.prototype.getParameterValue = function(paramName) {
        664 // NOTE(nicksantos): This type-cast is a lie when
        665 // preserveParameterTypesCompatibilityFlag is set to true.
        666 // But this should only be set to true in tests.
        667 return /** @type {string|undefined} */ (this.queryData_.get(paramName));
        668};
        669
        670
        671/**
        672 * @return {string} The URI fragment, not including the #.
        673 */
        674goog.Uri.prototype.getFragment = function() {
        675 return this.fragment_;
        676};
        677
        678
        679/**
        680 * Sets the URI fragment.
        681 * @param {string} newFragment New fragment value.
        682 * @param {boolean=} opt_decode Optional param for whether to decode new value.
        683 * @return {!goog.Uri} Reference to this URI object.
        684 */
        685goog.Uri.prototype.setFragment = function(newFragment, opt_decode) {
        686 this.enforceReadOnly();
        687 this.fragment_ = opt_decode ? goog.Uri.decodeOrEmpty_(newFragment) :
        688 newFragment;
        689 return this;
        690};
        691
        692
        693/**
        694 * @return {boolean} Whether the URI has a fragment set.
        695 */
        696goog.Uri.prototype.hasFragment = function() {
        697 return !!this.fragment_;
        698};
        699
        700
        701/**
        702 * Returns true if this has the same domain as that of uri2.
        703 * @param {goog.Uri} uri2 The URI object to compare to.
        704 * @return {boolean} true if same domain; false otherwise.
        705 */
        706goog.Uri.prototype.hasSameDomainAs = function(uri2) {
        707 return ((!this.hasDomain() && !uri2.hasDomain()) ||
        708 this.getDomain() == uri2.getDomain()) &&
        709 ((!this.hasPort() && !uri2.hasPort()) ||
        710 this.getPort() == uri2.getPort());
        711};
        712
        713
        714/**
        715 * Adds a random parameter to the Uri.
        716 * @return {!goog.Uri} Reference to this Uri object.
        717 */
        718goog.Uri.prototype.makeUnique = function() {
        719 this.enforceReadOnly();
        720 this.setParameterValue(goog.Uri.RANDOM_PARAM, goog.string.getRandomString());
        721
        722 return this;
        723};
        724
        725
        726/**
        727 * Removes the named query parameter.
        728 *
        729 * @param {string} key The parameter to remove.
        730 * @return {!goog.Uri} Reference to this URI object.
        731 */
        732goog.Uri.prototype.removeParameter = function(key) {
        733 this.enforceReadOnly();
        734 this.queryData_.remove(key);
        735 return this;
        736};
        737
        738
        739/**
        740 * Sets whether Uri is read only. If this goog.Uri is read-only,
        741 * enforceReadOnly_ will be called at the start of any function that may modify
        742 * this Uri.
        743 * @param {boolean} isReadOnly whether this goog.Uri should be read only.
        744 * @return {!goog.Uri} Reference to this Uri object.
        745 */
        746goog.Uri.prototype.setReadOnly = function(isReadOnly) {
        747 this.isReadOnly_ = isReadOnly;
        748 return this;
        749};
        750
        751
        752/**
        753 * @return {boolean} Whether the URI is read only.
        754 */
        755goog.Uri.prototype.isReadOnly = function() {
        756 return this.isReadOnly_;
        757};
        758
        759
        760/**
        761 * Checks if this Uri has been marked as read only, and if so, throws an error.
        762 * This should be called whenever any modifying function is called.
        763 */
        764goog.Uri.prototype.enforceReadOnly = function() {
        765 if (this.isReadOnly_) {
        766 throw Error('Tried to modify a read-only Uri');
        767 }
        768};
        769
        770
        771/**
        772 * Sets whether to ignore case.
        773 * NOTE: If there are already key/value pairs in the QueryData, and
        774 * ignoreCase_ is set to false, the keys will all be lower-cased.
        775 * @param {boolean} ignoreCase whether this goog.Uri should ignore case.
        776 * @return {!goog.Uri} Reference to this Uri object.
        777 */
        778goog.Uri.prototype.setIgnoreCase = function(ignoreCase) {
        779 this.ignoreCase_ = ignoreCase;
        780 if (this.queryData_) {
        781 this.queryData_.setIgnoreCase(ignoreCase);
        782 }
        783 return this;
        784};
        785
        786
        787/**
        788 * @return {boolean} Whether to ignore case.
        789 */
        790goog.Uri.prototype.getIgnoreCase = function() {
        791 return this.ignoreCase_;
        792};
        793
        794
        795//==============================================================================
        796// Static members
        797//==============================================================================
        798
        799
        800/**
        801 * Creates a uri from the string form. Basically an alias of new goog.Uri().
        802 * If a Uri object is passed to parse then it will return a clone of the object.
        803 *
        804 * @param {*} uri Raw URI string or instance of Uri
        805 * object.
        806 * @param {boolean=} opt_ignoreCase Whether to ignore the case of parameter
        807 * names in #getParameterValue.
        808 * @return {!goog.Uri} The new URI object.
        809 */
        810goog.Uri.parse = function(uri, opt_ignoreCase) {
        811 return uri instanceof goog.Uri ?
        812 uri.clone() : new goog.Uri(uri, opt_ignoreCase);
        813};
        814
        815
        816/**
        817 * Creates a new goog.Uri object from unencoded parts.
        818 *
        819 * @param {?string=} opt_scheme Scheme/protocol or full URI to parse.
        820 * @param {?string=} opt_userInfo username:password.
        821 * @param {?string=} opt_domain www.google.com.
        822 * @param {?number=} opt_port 9830.
        823 * @param {?string=} opt_path /some/path/to/a/file.html.
        824 * @param {string|goog.Uri.QueryData=} opt_query a=1&b=2.
        825 * @param {?string=} opt_fragment The fragment without the #.
        826 * @param {boolean=} opt_ignoreCase Whether to ignore parameter name case in
        827 * #getParameterValue.
        828 *
        829 * @return {!goog.Uri} The new URI object.
        830 */
        831goog.Uri.create = function(opt_scheme, opt_userInfo, opt_domain, opt_port,
        832 opt_path, opt_query, opt_fragment, opt_ignoreCase) {
        833
        834 var uri = new goog.Uri(null, opt_ignoreCase);
        835
        836 // Only set the parts if they are defined and not empty strings.
        837 opt_scheme && uri.setScheme(opt_scheme);
        838 opt_userInfo && uri.setUserInfo(opt_userInfo);
        839 opt_domain && uri.setDomain(opt_domain);
        840 opt_port && uri.setPort(opt_port);
        841 opt_path && uri.setPath(opt_path);
        842 opt_query && uri.setQueryData(opt_query);
        843 opt_fragment && uri.setFragment(opt_fragment);
        844
        845 return uri;
        846};
        847
        848
        849/**
        850 * Resolves a relative Uri against a base Uri, accepting both strings and
        851 * Uri objects.
        852 *
        853 * @param {*} base Base Uri.
        854 * @param {*} rel Relative Uri.
        855 * @return {!goog.Uri} Resolved uri.
        856 */
        857goog.Uri.resolve = function(base, rel) {
        858 if (!(base instanceof goog.Uri)) {
        859 base = goog.Uri.parse(base);
        860 }
        861
        862 if (!(rel instanceof goog.Uri)) {
        863 rel = goog.Uri.parse(rel);
        864 }
        865
        866 return base.resolve(rel);
        867};
        868
        869
        870/**
        871 * Removes dot segments in given path component, as described in
        872 * RFC 3986, section 5.2.4.
        873 *
        874 * @param {string} path A non-empty path component.
        875 * @return {string} Path component with removed dot segments.
        876 */
        877goog.Uri.removeDotSegments = function(path) {
        878 if (path == '..' || path == '.') {
        879 return '';
        880
        881 } else if (!goog.string.contains(path, './') &&
        882 !goog.string.contains(path, '/.')) {
        883 // This optimization detects uris which do not contain dot-segments,
        884 // and as a consequence do not require any processing.
        885 return path;
        886
        887 } else {
        888 var leadingSlash = goog.string.startsWith(path, '/');
        889 var segments = path.split('/');
        890 var out = [];
        891
        892 for (var pos = 0; pos < segments.length; ) {
        893 var segment = segments[pos++];
        894
        895 if (segment == '.') {
        896 if (leadingSlash && pos == segments.length) {
        897 out.push('');
        898 }
        899 } else if (segment == '..') {
        900 if (out.length > 1 || out.length == 1 && out[0] != '') {
        901 out.pop();
        902 }
        903 if (leadingSlash && pos == segments.length) {
        904 out.push('');
        905 }
        906 } else {
        907 out.push(segment);
        908 leadingSlash = true;
        909 }
        910 }
        911
        912 return out.join('/');
        913 }
        914};
        915
        916
        917/**
        918 * Decodes a value or returns the empty string if it isn't defined or empty.
        919 * @param {string|undefined} val Value to decode.
        920 * @param {boolean=} opt_preserveReserved If true, restricted characters will
        921 * not be decoded.
        922 * @return {string} Decoded value.
        923 * @private
        924 */
        925goog.Uri.decodeOrEmpty_ = function(val, opt_preserveReserved) {
        926 // Don't use UrlDecode() here because val is not a query parameter.
        927 if (!val) {
        928 return '';
        929 }
        930
        931 return opt_preserveReserved ? decodeURI(val) : decodeURIComponent(val);
        932};
        933
        934
        935/**
        936 * If unescapedPart is non null, then escapes any characters in it that aren't
        937 * valid characters in a url and also escapes any special characters that
        938 * appear in extra.
        939 *
        940 * @param {*} unescapedPart The string to encode.
        941 * @param {RegExp} extra A character set of characters in [\01-\177].
        942 * @param {boolean=} opt_removeDoubleEncoding If true, remove double percent
        943 * encoding.
        944 * @return {?string} null iff unescapedPart == null.
        945 * @private
        946 */
        947goog.Uri.encodeSpecialChars_ = function(unescapedPart, extra,
        948 opt_removeDoubleEncoding) {
        949 if (goog.isString(unescapedPart)) {
        950 var encoded = encodeURI(unescapedPart).
        951 replace(extra, goog.Uri.encodeChar_);
        952 if (opt_removeDoubleEncoding) {
        953 // encodeURI double-escapes %XX sequences used to represent restricted
        954 // characters in some URI components, remove the double escaping here.
        955 encoded = goog.Uri.removeDoubleEncoding_(encoded);
        956 }
        957 return encoded;
        958 }
        959 return null;
        960};
        961
        962
        963/**
        964 * Converts a character in [\01-\177] to its unicode character equivalent.
        965 * @param {string} ch One character string.
        966 * @return {string} Encoded string.
        967 * @private
        968 */
        969goog.Uri.encodeChar_ = function(ch) {
        970 var n = ch.charCodeAt(0);
        971 return '%' + ((n >> 4) & 0xf).toString(16) + (n & 0xf).toString(16);
        972};
        973
        974
        975/**
        976 * Removes double percent-encoding from a string.
        977 * @param {string} doubleEncodedString String
        978 * @return {string} String with double encoding removed.
        979 * @private
        980 */
        981goog.Uri.removeDoubleEncoding_ = function(doubleEncodedString) {
        982 return doubleEncodedString.replace(/%25([0-9a-fA-F]{2})/g, '%$1');
        983};
        984
        985
        986/**
        987 * Regular expression for characters that are disallowed in the scheme or
        988 * userInfo part of the URI.
        989 * @type {RegExp}
        990 * @private
        991 */
        992goog.Uri.reDisallowedInSchemeOrUserInfo_ = /[#\/\?@]/g;
        993
        994
        995/**
        996 * Regular expression for characters that are disallowed in a relative path.
        997 * Colon is included due to RFC 3986 3.3.
        998 * @type {RegExp}
        999 * @private
        1000 */
        1001goog.Uri.reDisallowedInRelativePath_ = /[\#\?:]/g;
        1002
        1003
        1004/**
        1005 * Regular expression for characters that are disallowed in an absolute path.
        1006 * @type {RegExp}
        1007 * @private
        1008 */
        1009goog.Uri.reDisallowedInAbsolutePath_ = /[\#\?]/g;
        1010
        1011
        1012/**
        1013 * Regular expression for characters that are disallowed in the query.
        1014 * @type {RegExp}
        1015 * @private
        1016 */
        1017goog.Uri.reDisallowedInQuery_ = /[\#\?@]/g;
        1018
        1019
        1020/**
        1021 * Regular expression for characters that are disallowed in the fragment.
        1022 * @type {RegExp}
        1023 * @private
        1024 */
        1025goog.Uri.reDisallowedInFragment_ = /#/g;
        1026
        1027
        1028/**
        1029 * Checks whether two URIs have the same domain.
        1030 * @param {string} uri1String First URI string.
        1031 * @param {string} uri2String Second URI string.
        1032 * @return {boolean} true if the two URIs have the same domain; false otherwise.
        1033 */
        1034goog.Uri.haveSameDomain = function(uri1String, uri2String) {
        1035 // Differs from goog.uri.utils.haveSameDomain, since this ignores scheme.
        1036 // TODO(gboyer): Have this just call goog.uri.util.haveSameDomain.
        1037 var pieces1 = goog.uri.utils.split(uri1String);
        1038 var pieces2 = goog.uri.utils.split(uri2String);
        1039 return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] ==
        1040 pieces2[goog.uri.utils.ComponentIndex.DOMAIN] &&
        1041 pieces1[goog.uri.utils.ComponentIndex.PORT] ==
        1042 pieces2[goog.uri.utils.ComponentIndex.PORT];
        1043};
        1044
        1045
        1046
        1047/**
        1048 * Class used to represent URI query parameters. It is essentially a hash of
        1049 * name-value pairs, though a name can be present more than once.
        1050 *
        1051 * Has the same interface as the collections in goog.structs.
        1052 *
        1053 * @param {?string=} opt_query Optional encoded query string to parse into
        1054 * the object.
        1055 * @param {goog.Uri=} opt_uri Optional uri object that should have its
        1056 * cache invalidated when this object updates. Deprecated -- this
        1057 * is no longer required.
        1058 * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter
        1059 * name in #get.
        1060 * @constructor
        1061 * @final
        1062 */
        1063goog.Uri.QueryData = function(opt_query, opt_uri, opt_ignoreCase) {
        1064 /**
        1065 * Encoded query string, or null if it requires computing from the key map.
        1066 * @type {?string}
        1067 * @private
        1068 */
        1069 this.encodedQuery_ = opt_query || null;
        1070
        1071 /**
        1072 * If true, ignore the case of the parameter name in #get.
        1073 * @type {boolean}
        1074 * @private
        1075 */
        1076 this.ignoreCase_ = !!opt_ignoreCase;
        1077};
        1078
        1079
        1080/**
        1081 * If the underlying key map is not yet initialized, it parses the
        1082 * query string and fills the map with parsed data.
        1083 * @private
        1084 */
        1085goog.Uri.QueryData.prototype.ensureKeyMapInitialized_ = function() {
        1086 if (!this.keyMap_) {
        1087 this.keyMap_ = new goog.structs.Map();
        1088 this.count_ = 0;
        1089
        1090 if (this.encodedQuery_) {
        1091 var pairs = this.encodedQuery_.split('&');
        1092 for (var i = 0; i < pairs.length; i++) {
        1093 var indexOfEquals = pairs[i].indexOf('=');
        1094 var name = null;
        1095 var value = null;
        1096 if (indexOfEquals >= 0) {
        1097 name = pairs[i].substring(0, indexOfEquals);
        1098 value = pairs[i].substring(indexOfEquals + 1);
        1099 } else {
        1100 name = pairs[i];
        1101 }
        1102 name = goog.string.urlDecode(name);
        1103 name = this.getKeyName_(name);
        1104 this.add(name, value ? goog.string.urlDecode(value) : '');
        1105 }
        1106 }
        1107 }
        1108};
        1109
        1110
        1111/**
        1112 * Creates a new query data instance from a map of names and values.
        1113 *
        1114 * @param {!goog.structs.Map|!Object} map Map of string parameter
        1115 * names to parameter value. If parameter value is an array, it is
        1116 * treated as if the key maps to each individual value in the
        1117 * array.
        1118 * @param {goog.Uri=} opt_uri URI object that should have its cache
        1119 * invalidated when this object updates.
        1120 * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter
        1121 * name in #get.
        1122 * @return {!goog.Uri.QueryData} The populated query data instance.
        1123 */
        1124goog.Uri.QueryData.createFromMap = function(map, opt_uri, opt_ignoreCase) {
        1125 var keys = goog.structs.getKeys(map);
        1126 if (typeof keys == 'undefined') {
        1127 throw Error('Keys are undefined');
        1128 }
        1129
        1130 var queryData = new goog.Uri.QueryData(null, null, opt_ignoreCase);
        1131 var values = goog.structs.getValues(map);
        1132 for (var i = 0; i < keys.length; i++) {
        1133 var key = keys[i];
        1134 var value = values[i];
        1135 if (!goog.isArray(value)) {
        1136 queryData.add(key, value);
        1137 } else {
        1138 queryData.setValues(key, value);
        1139 }
        1140 }
        1141 return queryData;
        1142};
        1143
        1144
        1145/**
        1146 * Creates a new query data instance from parallel arrays of parameter names
        1147 * and values. Allows for duplicate parameter names. Throws an error if the
        1148 * lengths of the arrays differ.
        1149 *
        1150 * @param {Array.<string>} keys Parameter names.
        1151 * @param {Array} values Parameter values.
        1152 * @param {goog.Uri=} opt_uri URI object that should have its cache
        1153 * invalidated when this object updates.
        1154 * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter
        1155 * name in #get.
        1156 * @return {!goog.Uri.QueryData} The populated query data instance.
        1157 */
        1158goog.Uri.QueryData.createFromKeysValues = function(
        1159 keys, values, opt_uri, opt_ignoreCase) {
        1160 if (keys.length != values.length) {
        1161 throw Error('Mismatched lengths for keys/values');
        1162 }
        1163 var queryData = new goog.Uri.QueryData(null, null, opt_ignoreCase);
        1164 for (var i = 0; i < keys.length; i++) {
        1165 queryData.add(keys[i], values[i]);
        1166 }
        1167 return queryData;
        1168};
        1169
        1170
        1171/**
        1172 * The map containing name/value or name/array-of-values pairs.
        1173 * May be null if it requires parsing from the query string.
        1174 *
        1175 * We need to use a Map because we cannot guarantee that the key names will
        1176 * not be problematic for IE.
        1177 *
        1178 * @type {goog.structs.Map.<string, Array>}
        1179 * @private
        1180 */
        1181goog.Uri.QueryData.prototype.keyMap_ = null;
        1182
        1183
        1184/**
        1185 * The number of params, or null if it requires computing.
        1186 * @type {?number}
        1187 * @private
        1188 */
        1189goog.Uri.QueryData.prototype.count_ = null;
        1190
        1191
        1192/**
        1193 * @return {?number} The number of parameters.
        1194 */
        1195goog.Uri.QueryData.prototype.getCount = function() {
        1196 this.ensureKeyMapInitialized_();
        1197 return this.count_;
        1198};
        1199
        1200
        1201/**
        1202 * Adds a key value pair.
        1203 * @param {string} key Name.
        1204 * @param {*} value Value.
        1205 * @return {!goog.Uri.QueryData} Instance of this object.
        1206 */
        1207goog.Uri.QueryData.prototype.add = function(key, value) {
        1208 this.ensureKeyMapInitialized_();
        1209 this.invalidateCache_();
        1210
        1211 key = this.getKeyName_(key);
        1212 var values = this.keyMap_.get(key);
        1213 if (!values) {
        1214 this.keyMap_.set(key, (values = []));
        1215 }
        1216 values.push(value);
        1217 this.count_++;
        1218 return this;
        1219};
        1220
        1221
        1222/**
        1223 * Removes all the params with the given key.
        1224 * @param {string} key Name.
        1225 * @return {boolean} Whether any parameter was removed.
        1226 */
        1227goog.Uri.QueryData.prototype.remove = function(key) {
        1228 this.ensureKeyMapInitialized_();
        1229
        1230 key = this.getKeyName_(key);
        1231 if (this.keyMap_.containsKey(key)) {
        1232 this.invalidateCache_();
        1233
        1234 // Decrement parameter count.
        1235 this.count_ -= this.keyMap_.get(key).length;
        1236 return this.keyMap_.remove(key);
        1237 }
        1238 return false;
        1239};
        1240
        1241
        1242/**
        1243 * Clears the parameters.
        1244 */
        1245goog.Uri.QueryData.prototype.clear = function() {
        1246 this.invalidateCache_();
        1247 this.keyMap_ = null;
        1248 this.count_ = 0;
        1249};
        1250
        1251
        1252/**
        1253 * @return {boolean} Whether we have any parameters.
        1254 */
        1255goog.Uri.QueryData.prototype.isEmpty = function() {
        1256 this.ensureKeyMapInitialized_();
        1257 return this.count_ == 0;
        1258};
        1259
        1260
        1261/**
        1262 * Whether there is a parameter with the given name
        1263 * @param {string} key The parameter name to check for.
        1264 * @return {boolean} Whether there is a parameter with the given name.
        1265 */
        1266goog.Uri.QueryData.prototype.containsKey = function(key) {
        1267 this.ensureKeyMapInitialized_();
        1268 key = this.getKeyName_(key);
        1269 return this.keyMap_.containsKey(key);
        1270};
        1271
        1272
        1273/**
        1274 * Whether there is a parameter with the given value.
        1275 * @param {*} value The value to check for.
        1276 * @return {boolean} Whether there is a parameter with the given value.
        1277 */
        1278goog.Uri.QueryData.prototype.containsValue = function(value) {
        1279 // NOTE(arv): This solution goes through all the params even if it was the
        1280 // first param. We can get around this by not reusing code or by switching to
        1281 // iterators.
        1282 var vals = this.getValues();
        1283 return goog.array.contains(vals, value);
        1284};
        1285
        1286
        1287/**
        1288 * Returns all the keys of the parameters. If a key is used multiple times
        1289 * it will be included multiple times in the returned array
        1290 * @return {!Array.<string>} All the keys of the parameters.
        1291 */
        1292goog.Uri.QueryData.prototype.getKeys = function() {
        1293 this.ensureKeyMapInitialized_();
        1294 // We need to get the values to know how many keys to add.
        1295 var vals = /** @type {Array.<Array|*>} */ (this.keyMap_.getValues());
        1296 var keys = this.keyMap_.getKeys();
        1297 var rv = [];
        1298 for (var i = 0; i < keys.length; i++) {
        1299 var val = vals[i];
        1300 for (var j = 0; j < val.length; j++) {
        1301 rv.push(keys[i]);
        1302 }
        1303 }
        1304 return rv;
        1305};
        1306
        1307
        1308/**
        1309 * Returns all the values of the parameters with the given name. If the query
        1310 * data has no such key this will return an empty array. If no key is given
        1311 * all values wil be returned.
        1312 * @param {string=} opt_key The name of the parameter to get the values for.
        1313 * @return {!Array} All the values of the parameters with the given name.
        1314 */
        1315goog.Uri.QueryData.prototype.getValues = function(opt_key) {
        1316 this.ensureKeyMapInitialized_();
        1317 var rv = [];
        1318 if (goog.isString(opt_key)) {
        1319 if (this.containsKey(opt_key)) {
        1320 rv = goog.array.concat(rv, this.keyMap_.get(this.getKeyName_(opt_key)));
        1321 }
        1322 } else {
        1323 // Return all values.
        1324 var values = /** @type {Array.<Array|*>} */ (this.keyMap_.getValues());
        1325 for (var i = 0; i < values.length; i++) {
        1326 rv = goog.array.concat(rv, values[i]);
        1327 }
        1328 }
        1329 return rv;
        1330};
        1331
        1332
        1333/**
        1334 * Sets a key value pair and removes all other keys with the same value.
        1335 *
        1336 * @param {string} key Name.
        1337 * @param {*} value Value.
        1338 * @return {!goog.Uri.QueryData} Instance of this object.
        1339 */
        1340goog.Uri.QueryData.prototype.set = function(key, value) {
        1341 this.ensureKeyMapInitialized_();
        1342 this.invalidateCache_();
        1343
        1344 // TODO(user): This could be better written as
        1345 // this.remove(key), this.add(key, value), but that would reorder
        1346 // the key (since the key is first removed and then added at the
        1347 // end) and we would have to fix unit tests that depend on key
        1348 // ordering.
        1349 key = this.getKeyName_(key);
        1350 if (this.containsKey(key)) {
        1351 this.count_ -= this.keyMap_.get(key).length;
        1352 }
        1353 this.keyMap_.set(key, [value]);
        1354 this.count_++;
        1355 return this;
        1356};
        1357
        1358
        1359/**
        1360 * Returns the first value associated with the key. If the query data has no
        1361 * such key this will return undefined or the optional default.
        1362 * @param {string} key The name of the parameter to get the value for.
        1363 * @param {*=} opt_default The default value to return if the query data
        1364 * has no such key.
        1365 * @return {*} The first string value associated with the key, or opt_default
        1366 * if there's no value.
        1367 */
        1368goog.Uri.QueryData.prototype.get = function(key, opt_default) {
        1369 var values = key ? this.getValues(key) : [];
        1370 if (goog.Uri.preserveParameterTypesCompatibilityFlag) {
        1371 return values.length > 0 ? values[0] : opt_default;
        1372 } else {
        1373 return values.length > 0 ? String(values[0]) : opt_default;
        1374 }
        1375};
        1376
        1377
        1378/**
        1379 * Sets the values for a key. If the key already exists, this will
        1380 * override all of the existing values that correspond to the key.
        1381 * @param {string} key The key to set values for.
        1382 * @param {Array} values The values to set.
        1383 */
        1384goog.Uri.QueryData.prototype.setValues = function(key, values) {
        1385 this.remove(key);
        1386
        1387 if (values.length > 0) {
        1388 this.invalidateCache_();
        1389 this.keyMap_.set(this.getKeyName_(key), goog.array.clone(values));
        1390 this.count_ += values.length;
        1391 }
        1392};
        1393
        1394
        1395/**
        1396 * @return {string} Encoded query string.
        1397 * @override
        1398 */
        1399goog.Uri.QueryData.prototype.toString = function() {
        1400 if (this.encodedQuery_) {
        1401 return this.encodedQuery_;
        1402 }
        1403
        1404 if (!this.keyMap_) {
        1405 return '';
        1406 }
        1407
        1408 var sb = [];
        1409
        1410 // In the past, we use this.getKeys() and this.getVals(), but that
        1411 // generates a lot of allocations as compared to simply iterating
        1412 // over the keys.
        1413 var keys = this.keyMap_.getKeys();
        1414 for (var i = 0; i < keys.length; i++) {
        1415 var key = keys[i];
        1416 var encodedKey = goog.string.urlEncode(key);
        1417 var val = this.getValues(key);
        1418 for (var j = 0; j < val.length; j++) {
        1419 var param = encodedKey;
        1420 // Ensure that null and undefined are encoded into the url as
        1421 // literal strings.
        1422 if (val[j] !== '') {
        1423 param += '=' + goog.string.urlEncode(val[j]);
        1424 }
        1425 sb.push(param);
        1426 }
        1427 }
        1428
        1429 return this.encodedQuery_ = sb.join('&');
        1430};
        1431
        1432
        1433/**
        1434 * @return {string} Decoded query string.
        1435 */
        1436goog.Uri.QueryData.prototype.toDecodedString = function() {
        1437 return goog.Uri.decodeOrEmpty_(this.toString());
        1438};
        1439
        1440
        1441/**
        1442 * Invalidate the cache.
        1443 * @private
        1444 */
        1445goog.Uri.QueryData.prototype.invalidateCache_ = function() {
        1446 this.encodedQuery_ = null;
        1447};
        1448
        1449
        1450/**
        1451 * Removes all keys that are not in the provided list. (Modifies this object.)
        1452 * @param {Array.<string>} keys The desired keys.
        1453 * @return {!goog.Uri.QueryData} a reference to this object.
        1454 */
        1455goog.Uri.QueryData.prototype.filterKeys = function(keys) {
        1456 this.ensureKeyMapInitialized_();
        1457 this.keyMap_.forEach(
        1458 function(value, key) {
        1459 if (!goog.array.contains(keys, key)) {
        1460 this.remove(key);
        1461 }
        1462 }, this);
        1463 return this;
        1464};
        1465
        1466
        1467/**
        1468 * Clone the query data instance.
        1469 * @return {!goog.Uri.QueryData} New instance of the QueryData object.
        1470 */
        1471goog.Uri.QueryData.prototype.clone = function() {
        1472 var rv = new goog.Uri.QueryData();
        1473 rv.encodedQuery_ = this.encodedQuery_;
        1474 if (this.keyMap_) {
        1475 rv.keyMap_ = this.keyMap_.clone();
        1476 rv.count_ = this.count_;
        1477 }
        1478 return rv;
        1479};
        1480
        1481
        1482/**
        1483 * Helper function to get the key name from a JavaScript object. Converts
        1484 * the object to a string, and to lower case if necessary.
        1485 * @private
        1486 * @param {*} arg The object to get a key name from.
        1487 * @return {string} valid key name which can be looked up in #keyMap_.
        1488 */
        1489goog.Uri.QueryData.prototype.getKeyName_ = function(arg) {
        1490 var keyName = String(arg);
        1491 if (this.ignoreCase_) {
        1492 keyName = keyName.toLowerCase();
        1493 }
        1494 return keyName;
        1495};
        1496
        1497
        1498/**
        1499 * Ignore case in parameter names.
        1500 * NOTE: If there are already key/value pairs in the QueryData, and
        1501 * ignoreCase_ is set to false, the keys will all be lower-cased.
        1502 * @param {boolean} ignoreCase whether this goog.Uri should ignore case.
        1503 */
        1504goog.Uri.QueryData.prototype.setIgnoreCase = function(ignoreCase) {
        1505 var resetKeys = ignoreCase && !this.ignoreCase_;
        1506 if (resetKeys) {
        1507 this.ensureKeyMapInitialized_();
        1508 this.invalidateCache_();
        1509 this.keyMap_.forEach(
        1510 function(value, key) {
        1511 var lowerCase = key.toLowerCase();
        1512 if (key != lowerCase) {
        1513 this.remove(key);
        1514 this.setValues(lowerCase, value);
        1515 }
        1516 }, this);
        1517 }
        1518 this.ignoreCase_ = ignoreCase;
        1519};
        1520
        1521
        1522/**
        1523 * Extends a query data object with another query data or map like object. This
        1524 * operates 'in-place', it does not create a new QueryData object.
        1525 *
        1526 * @param {...(goog.Uri.QueryData|goog.structs.Map|Object)} var_args The object
        1527 * from which key value pairs will be copied.
        1528 */
        1529goog.Uri.QueryData.prototype.extend = function(var_args) {
        1530 for (var i = 0; i < arguments.length; i++) {
        1531 var data = arguments[i];
        1532 goog.structs.forEach(data,
        1533 /** @this {goog.Uri.QueryData} */
        1534 function(value, key) {
        1535 this.add(key, value);
        1536 }, this);
        1537 }
        1538};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/uri/utils.js.src.html b/docs/api/javascript/source/lib/goog/uri/utils.js.src.html index 8ffa2dfec3a53..15b173923b685 100644 --- a/docs/api/javascript/source/lib/goog/uri/utils.js.src.html +++ b/docs/api/javascript/source/lib/goog/uri/utils.js.src.html @@ -1 +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 +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 * @param {boolean=} opt_preserveReserved If true, percent-encoding of RFC-3986
        302 * reserved characters will not be removed.
        303 * @return {?string} The string URI-decoded, or null if uri is null.
        304 * @private
        305 */
        306goog.uri.utils.decodeIfPossible_ = function(uri, opt_preserveReserved) {
        307 if (!uri) {
        308 return uri;
        309 }
        310
        311 return opt_preserveReserved ? decodeURI(uri) : decodeURIComponent(uri);
        312};
        313
        314
        315/**
        316 * Gets a URI component by index.
        317 *
        318 * It is preferred to use the getPathEncoded() variety of functions ahead,
        319 * since they are more readable.
        320 *
        321 * @param {goog.uri.utils.ComponentIndex} componentIndex The component index.
        322 * @param {string} uri The URI to examine.
        323 * @return {?string} The still-encoded component, or null if the component
        324 * is not present.
        325 * @private
        326 */
        327goog.uri.utils.getComponentByIndex_ = function(componentIndex, uri) {
        328 // Convert undefined, null, and empty string into null.
        329 return goog.uri.utils.split(uri)[componentIndex] || null;
        330};
        331
        332
        333/**
        334 * @param {string} uri The URI to examine.
        335 * @return {?string} The protocol or scheme, or null if none. Does not
        336 * include trailing colons or slashes.
        337 */
        338goog.uri.utils.getScheme = function(uri) {
        339 return goog.uri.utils.getComponentByIndex_(
        340 goog.uri.utils.ComponentIndex.SCHEME, uri);
        341};
        342
        343
        344/**
        345 * Gets the effective scheme for the URL. If the URL is relative then the
        346 * scheme is derived from the page's location.
        347 * @param {string} uri The URI to examine.
        348 * @return {string} The protocol or scheme, always lower case.
        349 */
        350goog.uri.utils.getEffectiveScheme = function(uri) {
        351 var scheme = goog.uri.utils.getScheme(uri);
        352 if (!scheme && self.location) {
        353 var protocol = self.location.protocol;
        354 scheme = protocol.substr(0, protocol.length - 1);
        355 }
        356 // NOTE: When called from a web worker in Firefox 3.5, location maybe null.
        357 // All other browsers with web workers support self.location from the worker.
        358 return scheme ? scheme.toLowerCase() : '';
        359};
        360
        361
        362/**
        363 * @param {string} uri The URI to examine.
        364 * @return {?string} The user name still encoded, or null if none.
        365 */
        366goog.uri.utils.getUserInfoEncoded = function(uri) {
        367 return goog.uri.utils.getComponentByIndex_(
        368 goog.uri.utils.ComponentIndex.USER_INFO, uri);
        369};
        370
        371
        372/**
        373 * @param {string} uri The URI to examine.
        374 * @return {?string} The decoded user info, or null if none.
        375 */
        376goog.uri.utils.getUserInfo = function(uri) {
        377 return goog.uri.utils.decodeIfPossible_(
        378 goog.uri.utils.getUserInfoEncoded(uri));
        379};
        380
        381
        382/**
        383 * @param {string} uri The URI to examine.
        384 * @return {?string} The domain name still encoded, or null if none.
        385 */
        386goog.uri.utils.getDomainEncoded = function(uri) {
        387 return goog.uri.utils.getComponentByIndex_(
        388 goog.uri.utils.ComponentIndex.DOMAIN, uri);
        389};
        390
        391
        392/**
        393 * @param {string} uri The URI to examine.
        394 * @return {?string} The decoded domain, or null if none.
        395 */
        396goog.uri.utils.getDomain = function(uri) {
        397 return goog.uri.utils.decodeIfPossible_(
        398 goog.uri.utils.getDomainEncoded(uri), true /* opt_preserveReserved */);
        399};
        400
        401
        402/**
        403 * @param {string} uri The URI to examine.
        404 * @return {?number} The port number, or null if none.
        405 */
        406goog.uri.utils.getPort = function(uri) {
        407 // Coerce to a number. If the result of getComponentByIndex_ is null or
        408 // non-numeric, the number coersion yields NaN. This will then return
        409 // null for all non-numeric cases (though also zero, which isn't a relevant
        410 // port number).
        411 return Number(goog.uri.utils.getComponentByIndex_(
        412 goog.uri.utils.ComponentIndex.PORT, uri)) || null;
        413};
        414
        415
        416/**
        417 * @param {string} uri The URI to examine.
        418 * @return {?string} The path still encoded, or null if none. Includes the
        419 * leading slash, if any.
        420 */
        421goog.uri.utils.getPathEncoded = function(uri) {
        422 return goog.uri.utils.getComponentByIndex_(
        423 goog.uri.utils.ComponentIndex.PATH, uri);
        424};
        425
        426
        427/**
        428 * @param {string} uri The URI to examine.
        429 * @return {?string} The decoded path, or null if none. Includes the leading
        430 * slash, if any.
        431 */
        432goog.uri.utils.getPath = function(uri) {
        433 return goog.uri.utils.decodeIfPossible_(
        434 goog.uri.utils.getPathEncoded(uri), true /* opt_preserveReserved */);
        435};
        436
        437
        438/**
        439 * @param {string} uri The URI to examine.
        440 * @return {?string} The query data still encoded, or null if none. Does not
        441 * include the question mark itself.
        442 */
        443goog.uri.utils.getQueryData = function(uri) {
        444 return goog.uri.utils.getComponentByIndex_(
        445 goog.uri.utils.ComponentIndex.QUERY_DATA, uri);
        446};
        447
        448
        449/**
        450 * @param {string} uri The URI to examine.
        451 * @return {?string} The fragment identifier, or null if none. Does not
        452 * include the hash mark itself.
        453 */
        454goog.uri.utils.getFragmentEncoded = function(uri) {
        455 // The hash mark may not appear in any other part of the URL.
        456 var hashIndex = uri.indexOf('#');
        457 return hashIndex < 0 ? null : uri.substr(hashIndex + 1);
        458};
        459
        460
        461/**
        462 * @param {string} uri The URI to examine.
        463 * @param {?string} fragment The encoded fragment identifier, or null if none.
        464 * Does not include the hash mark itself.
        465 * @return {string} The URI with the fragment set.
        466 */
        467goog.uri.utils.setFragmentEncoded = function(uri, fragment) {
        468 return goog.uri.utils.removeFragment(uri) + (fragment ? '#' + fragment : '');
        469};
        470
        471
        472/**
        473 * @param {string} uri The URI to examine.
        474 * @return {?string} The decoded fragment identifier, or null if none. Does
        475 * not include the hash mark.
        476 */
        477goog.uri.utils.getFragment = function(uri) {
        478 return goog.uri.utils.decodeIfPossible_(
        479 goog.uri.utils.getFragmentEncoded(uri));
        480};
        481
        482
        483/**
        484 * Extracts everything up to the port of the URI.
        485 * @param {string} uri The URI string.
        486 * @return {string} Everything up to and including the port.
        487 */
        488goog.uri.utils.getHost = function(uri) {
        489 var pieces = goog.uri.utils.split(uri);
        490 return goog.uri.utils.buildFromEncodedParts(
        491 pieces[goog.uri.utils.ComponentIndex.SCHEME],
        492 pieces[goog.uri.utils.ComponentIndex.USER_INFO],
        493 pieces[goog.uri.utils.ComponentIndex.DOMAIN],
        494 pieces[goog.uri.utils.ComponentIndex.PORT]);
        495};
        496
        497
        498/**
        499 * Extracts the path of the URL and everything after.
        500 * @param {string} uri The URI string.
        501 * @return {string} The URI, starting at the path and including the query
        502 * parameters and fragment identifier.
        503 */
        504goog.uri.utils.getPathAndAfter = function(uri) {
        505 var pieces = goog.uri.utils.split(uri);
        506 return goog.uri.utils.buildFromEncodedParts(null, null, null, null,
        507 pieces[goog.uri.utils.ComponentIndex.PATH],
        508 pieces[goog.uri.utils.ComponentIndex.QUERY_DATA],
        509 pieces[goog.uri.utils.ComponentIndex.FRAGMENT]);
        510};
        511
        512
        513/**
        514 * Gets the URI with the fragment identifier removed.
        515 * @param {string} uri The URI to examine.
        516 * @return {string} Everything preceding the hash mark.
        517 */
        518goog.uri.utils.removeFragment = function(uri) {
        519 // The hash mark may not appear in any other part of the URL.
        520 var hashIndex = uri.indexOf('#');
        521 return hashIndex < 0 ? uri : uri.substr(0, hashIndex);
        522};
        523
        524
        525/**
        526 * Ensures that two URI's have the exact same domain, scheme, and port.
        527 *
        528 * Unlike the version in goog.Uri, this checks protocol, and therefore is
        529 * suitable for checking against the browser's same-origin policy.
        530 *
        531 * @param {string} uri1 The first URI.
        532 * @param {string} uri2 The second URI.
        533 * @return {boolean} Whether they have the same scheme, domain and port.
        534 */
        535goog.uri.utils.haveSameDomain = function(uri1, uri2) {
        536 var pieces1 = goog.uri.utils.split(uri1);
        537 var pieces2 = goog.uri.utils.split(uri2);
        538 return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] ==
        539 pieces2[goog.uri.utils.ComponentIndex.DOMAIN] &&
        540 pieces1[goog.uri.utils.ComponentIndex.SCHEME] ==
        541 pieces2[goog.uri.utils.ComponentIndex.SCHEME] &&
        542 pieces1[goog.uri.utils.ComponentIndex.PORT] ==
        543 pieces2[goog.uri.utils.ComponentIndex.PORT];
        544};
        545
        546
        547/**
        548 * Asserts that there are no fragment or query identifiers, only in uncompiled
        549 * mode.
        550 * @param {string} uri The URI to examine.
        551 * @private
        552 */
        553goog.uri.utils.assertNoFragmentsOrQueries_ = function(uri) {
        554 // NOTE: would use goog.asserts here, but jscompiler doesn't know that
        555 // indexOf has no side effects.
        556 if (goog.DEBUG && (uri.indexOf('#') >= 0 || uri.indexOf('?') >= 0)) {
        557 throw Error('goog.uri.utils: Fragment or query identifiers are not ' +
        558 'supported: [' + uri + ']');
        559 }
        560};
        561
        562
        563/**
        564 * Supported query parameter values by the parameter serializing utilities.
        565 *
        566 * If a value is null or undefined, the key-value pair is skipped, as an easy
        567 * way to omit parameters conditionally. Non-array parameters are converted
        568 * to a string and URI encoded. Array values are expanded into multiple
        569 * &key=value pairs, with each element stringized and URI-encoded.
        570 *
        571 * @typedef {*}
        572 */
        573goog.uri.utils.QueryValue;
        574
        575
        576/**
        577 * An array representing a set of query parameters with alternating keys
        578 * and values.
        579 *
        580 * Keys are assumed to be URI encoded already and live at even indices. See
        581 * goog.uri.utils.QueryValue for details on how parameter values are encoded.
        582 *
        583 * Example:
        584 * <pre>
        585 * var data = [
        586 * // Simple param: ?name=BobBarker
        587 * 'name', 'BobBarker',
        588 * // Conditional param -- may be omitted entirely.
        589 * 'specialDietaryNeeds', hasDietaryNeeds() ? getDietaryNeeds() : null,
        590 * // Multi-valued param: &house=LosAngeles&house=NewYork&house=null
        591 * 'house', ['LosAngeles', 'NewYork', null]
        592 * ];
        593 * </pre>
        594 *
        595 * @typedef {!Array.<string|goog.uri.utils.QueryValue>}
        596 */
        597goog.uri.utils.QueryArray;
        598
        599
        600/**
        601 * Appends a URI and query data in a string buffer with special preconditions.
        602 *
        603 * Internal implementation utility, performing very few object allocations.
        604 *
        605 * @param {!Array.<string|undefined>} buffer A string buffer. The first element
        606 * must be the base URI, and may have a fragment identifier. If the array
        607 * contains more than one element, the second element must be an ampersand,
        608 * and may be overwritten, depending on the base URI. Undefined elements
        609 * are treated as empty-string.
        610 * @return {string} The concatenated URI and query data.
        611 * @private
        612 */
        613goog.uri.utils.appendQueryData_ = function(buffer) {
        614 if (buffer[1]) {
        615 // At least one query parameter was added. We need to check the
        616 // punctuation mark, which is currently an ampersand, and also make sure
        617 // there aren't any interfering fragment identifiers.
        618 var baseUri = /** @type {string} */ (buffer[0]);
        619 var hashIndex = baseUri.indexOf('#');
        620 if (hashIndex >= 0) {
        621 // Move the fragment off the base part of the URI into the end.
        622 buffer.push(baseUri.substr(hashIndex));
        623 buffer[0] = baseUri = baseUri.substr(0, hashIndex);
        624 }
        625 var questionIndex = baseUri.indexOf('?');
        626 if (questionIndex < 0) {
        627 // No question mark, so we need a question mark instead of an ampersand.
        628 buffer[1] = '?';
        629 } else if (questionIndex == baseUri.length - 1) {
        630 // Question mark is the very last character of the existing URI, so don't
        631 // append an additional delimiter.
        632 buffer[1] = undefined;
        633 }
        634 }
        635
        636 return buffer.join('');
        637};
        638
        639
        640/**
        641 * Appends key=value pairs to an array, supporting multi-valued objects.
        642 * @param {string} key The key prefix.
        643 * @param {goog.uri.utils.QueryValue} value The value to serialize.
        644 * @param {!Array.<string>} pairs The array to which the 'key=value' strings
        645 * should be appended.
        646 * @private
        647 */
        648goog.uri.utils.appendKeyValuePairs_ = function(key, value, pairs) {
        649 if (goog.isArray(value)) {
        650 // Convince the compiler it's an array.
        651 goog.asserts.assertArray(value);
        652 for (var j = 0; j < value.length; j++) {
        653 // Convert to string explicitly, to short circuit the null and array
        654 // logic in this function -- this ensures that null and undefined get
        655 // written as literal 'null' and 'undefined', and arrays don't get
        656 // expanded out but instead encoded in the default way.
        657 goog.uri.utils.appendKeyValuePairs_(key, String(value[j]), pairs);
        658 }
        659 } else if (value != null) {
        660 // Skip a top-level null or undefined entirely.
        661 pairs.push('&', key,
        662 // Check for empty string. Zero gets encoded into the url as literal
        663 // strings. For empty string, skip the equal sign, to be consistent
        664 // with UriBuilder.java.
        665 value === '' ? '' : '=',
        666 goog.string.urlEncode(value));
        667 }
        668};
        669
        670
        671/**
        672 * Builds a buffer of query data from a sequence of alternating keys and values.
        673 *
        674 * @param {!Array.<string|undefined>} buffer A string buffer to append to. The
        675 * first element appended will be an '&', and may be replaced by the caller.
        676 * @param {goog.uri.utils.QueryArray|Arguments} keysAndValues An array with
        677 * alternating keys and values -- see the typedef.
        678 * @param {number=} opt_startIndex A start offset into the arary, defaults to 0.
        679 * @return {!Array.<string|undefined>} The buffer argument.
        680 * @private
        681 */
        682goog.uri.utils.buildQueryDataBuffer_ = function(
        683 buffer, keysAndValues, opt_startIndex) {
        684 goog.asserts.assert(Math.max(keysAndValues.length - (opt_startIndex || 0),
        685 0) % 2 == 0, 'goog.uri.utils: Key/value lists must be even in length.');
        686
        687 for (var i = opt_startIndex || 0; i < keysAndValues.length; i += 2) {
        688 goog.uri.utils.appendKeyValuePairs_(
        689 keysAndValues[i], keysAndValues[i + 1], buffer);
        690 }
        691
        692 return buffer;
        693};
        694
        695
        696/**
        697 * Builds a query data string from a sequence of alternating keys and values.
        698 * Currently generates "&key&" for empty args.
        699 *
        700 * @param {goog.uri.utils.QueryArray} keysAndValues Alternating keys and
        701 * values. See the typedef.
        702 * @param {number=} opt_startIndex A start offset into the arary, defaults to 0.
        703 * @return {string} The encoded query string, in the form 'a=1&b=2'.
        704 */
        705goog.uri.utils.buildQueryData = function(keysAndValues, opt_startIndex) {
        706 var buffer = goog.uri.utils.buildQueryDataBuffer_(
        707 [], keysAndValues, opt_startIndex);
        708 buffer[0] = ''; // Remove the leading ampersand.
        709 return buffer.join('');
        710};
        711
        712
        713/**
        714 * Builds a buffer of query data from a map.
        715 *
        716 * @param {!Array.<string|undefined>} buffer A string buffer to append to. The
        717 * first element appended will be an '&', and may be replaced by the caller.
        718 * @param {Object.<goog.uri.utils.QueryValue>} map An object where keys are
        719 * URI-encoded parameter keys, and the values conform to the contract
        720 * specified in the goog.uri.utils.QueryValue typedef.
        721 * @return {!Array.<string|undefined>} The buffer argument.
        722 * @private
        723 */
        724goog.uri.utils.buildQueryDataBufferFromMap_ = function(buffer, map) {
        725 for (var key in map) {
        726 goog.uri.utils.appendKeyValuePairs_(key, map[key], buffer);
        727 }
        728
        729 return buffer;
        730};
        731
        732
        733/**
        734 * Builds a query data string from a map.
        735 * Currently generates "&key&" for empty args.
        736 *
        737 * @param {Object} map An object where keys are URI-encoded parameter keys,
        738 * and the values are arbitrary types or arrays. Keys with a null value
        739 * are dropped.
        740 * @return {string} The encoded query string, in the form 'a=1&b=2'.
        741 */
        742goog.uri.utils.buildQueryDataFromMap = function(map) {
        743 var buffer = goog.uri.utils.buildQueryDataBufferFromMap_([], map);
        744 buffer[0] = '';
        745 return buffer.join('');
        746};
        747
        748
        749/**
        750 * Appends URI parameters to an existing URI.
        751 *
        752 * The variable arguments may contain alternating keys and values. Keys are
        753 * assumed to be already URI encoded. The values should not be URI-encoded,
        754 * and will instead be encoded by this function.
        755 * <pre>
        756 * appendParams('http://www.foo.com?existing=true',
        757 * 'key1', 'value1',
        758 * 'key2', 'value?willBeEncoded',
        759 * 'key3', ['valueA', 'valueB', 'valueC'],
        760 * 'key4', null);
        761 * result: 'http://www.foo.com?existing=true&' +
        762 * 'key1=value1&' +
        763 * 'key2=value%3FwillBeEncoded&' +
        764 * 'key3=valueA&key3=valueB&key3=valueC'
        765 * </pre>
        766 *
        767 * A single call to this function will not exhibit quadratic behavior in IE,
        768 * whereas multiple repeated calls may, although the effect is limited by
        769 * fact that URL's generally can't exceed 2kb.
        770 *
        771 * @param {string} uri The original URI, which may already have query data.
        772 * @param {...(goog.uri.utils.QueryArray|string|goog.uri.utils.QueryValue)} var_args
        773 * An array or argument list conforming to goog.uri.utils.QueryArray.
        774 * @return {string} The URI with all query parameters added.
        775 */
        776goog.uri.utils.appendParams = function(uri, var_args) {
        777 return goog.uri.utils.appendQueryData_(
        778 arguments.length == 2 ?
        779 goog.uri.utils.buildQueryDataBuffer_([uri], arguments[1], 0) :
        780 goog.uri.utils.buildQueryDataBuffer_([uri], arguments, 1));
        781};
        782
        783
        784/**
        785 * Appends query parameters from a map.
        786 *
        787 * @param {string} uri The original URI, which may already have query data.
        788 * @param {Object} map An object where keys are URI-encoded parameter keys,
        789 * and the values are arbitrary types or arrays. Keys with a null value
        790 * are dropped.
        791 * @return {string} The new parameters.
        792 */
        793goog.uri.utils.appendParamsFromMap = function(uri, map) {
        794 return goog.uri.utils.appendQueryData_(
        795 goog.uri.utils.buildQueryDataBufferFromMap_([uri], map));
        796};
        797
        798
        799/**
        800 * Appends a single URI parameter.
        801 *
        802 * Repeated calls to this can exhibit quadratic behavior in IE6 due to the
        803 * way string append works, though it should be limited given the 2kb limit.
        804 *
        805 * @param {string} uri The original URI, which may already have query data.
        806 * @param {string} key The key, which must already be URI encoded.
        807 * @param {*=} opt_value The value, which will be stringized and encoded
        808 * (assumed not already to be encoded). If omitted, undefined, or null, the
        809 * key will be added as a valueless parameter.
        810 * @return {string} The URI with the query parameter added.
        811 */
        812goog.uri.utils.appendParam = function(uri, key, opt_value) {
        813 var paramArr = [uri, '&', key];
        814 if (goog.isDefAndNotNull(opt_value)) {
        815 paramArr.push('=', goog.string.urlEncode(opt_value));
        816 }
        817 return goog.uri.utils.appendQueryData_(paramArr);
        818};
        819
        820
        821/**
        822 * Finds the next instance of a query parameter with the specified name.
        823 *
        824 * Does not instantiate any objects.
        825 *
        826 * @param {string} uri The URI to search. May contain a fragment identifier
        827 * if opt_hashIndex is specified.
        828 * @param {number} startIndex The index to begin searching for the key at. A
        829 * match may be found even if this is one character after the ampersand.
        830 * @param {string} keyEncoded The URI-encoded key.
        831 * @param {number} hashOrEndIndex Index to stop looking at. If a hash
        832 * mark is present, it should be its index, otherwise it should be the
        833 * length of the string.
        834 * @return {number} The position of the first character in the key's name,
        835 * immediately after either a question mark or a dot.
        836 * @private
        837 */
        838goog.uri.utils.findParam_ = function(
        839 uri, startIndex, keyEncoded, hashOrEndIndex) {
        840 var index = startIndex;
        841 var keyLength = keyEncoded.length;
        842
        843 // Search for the key itself and post-filter for surronuding punctuation,
        844 // rather than expensively building a regexp.
        845 while ((index = uri.indexOf(keyEncoded, index)) >= 0 &&
        846 index < hashOrEndIndex) {
        847 var precedingChar = uri.charCodeAt(index - 1);
        848 // Ensure that the preceding character is '&' or '?'.
        849 if (precedingChar == goog.uri.utils.CharCode_.AMPERSAND ||
        850 precedingChar == goog.uri.utils.CharCode_.QUESTION) {
        851 // Ensure the following character is '&', '=', '#', or NaN
        852 // (end of string).
        853 var followingChar = uri.charCodeAt(index + keyLength);
        854 if (!followingChar ||
        855 followingChar == goog.uri.utils.CharCode_.EQUAL ||
        856 followingChar == goog.uri.utils.CharCode_.AMPERSAND ||
        857 followingChar == goog.uri.utils.CharCode_.HASH) {
        858 return index;
        859 }
        860 }
        861 index += keyLength + 1;
        862 }
        863
        864 return -1;
        865};
        866
        867
        868/**
        869 * Regular expression for finding a hash mark or end of string.
        870 * @type {RegExp}
        871 * @private
        872 */
        873goog.uri.utils.hashOrEndRe_ = /#|$/;
        874
        875
        876/**
        877 * Determines if the URI contains a specific key.
        878 *
        879 * Performs no object instantiations.
        880 *
        881 * @param {string} uri The URI to process. May contain a fragment
        882 * identifier.
        883 * @param {string} keyEncoded The URI-encoded key. Case-sensitive.
        884 * @return {boolean} Whether the key is present.
        885 */
        886goog.uri.utils.hasParam = function(uri, keyEncoded) {
        887 return goog.uri.utils.findParam_(uri, 0, keyEncoded,
        888 uri.search(goog.uri.utils.hashOrEndRe_)) >= 0;
        889};
        890
        891
        892/**
        893 * Gets the first value of a query parameter.
        894 * @param {string} uri The URI to process. May contain a fragment.
        895 * @param {string} keyEncoded The URI-encoded key. Case-sensitive.
        896 * @return {?string} The first value of the parameter (URI-decoded), or null
        897 * if the parameter is not found.
        898 */
        899goog.uri.utils.getParamValue = function(uri, keyEncoded) {
        900 var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);
        901 var foundIndex = goog.uri.utils.findParam_(
        902 uri, 0, keyEncoded, hashOrEndIndex);
        903
        904 if (foundIndex < 0) {
        905 return null;
        906 } else {
        907 var endPosition = uri.indexOf('&', foundIndex);
        908 if (endPosition < 0 || endPosition > hashOrEndIndex) {
        909 endPosition = hashOrEndIndex;
        910 }
        911 // Progress forth to the end of the "key=" or "key&" substring.
        912 foundIndex += keyEncoded.length + 1;
        913 // Use substr, because it (unlike substring) will return empty string
        914 // if foundIndex > endPosition.
        915 return goog.string.urlDecode(
        916 uri.substr(foundIndex, endPosition - foundIndex));
        917 }
        918};
        919
        920
        921/**
        922 * Gets all values of a query parameter.
        923 * @param {string} uri The URI to process. May contain a framgnet.
        924 * @param {string} keyEncoded The URI-encoded key. Case-snsitive.
        925 * @return {!Array.<string>} All URI-decoded values with the given key.
        926 * If the key is not found, this will have length 0, but never be null.
        927 */
        928goog.uri.utils.getParamValues = function(uri, keyEncoded) {
        929 var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);
        930 var position = 0;
        931 var foundIndex;
        932 var result = [];
        933
        934 while ((foundIndex = goog.uri.utils.findParam_(
        935 uri, position, keyEncoded, hashOrEndIndex)) >= 0) {
        936 // Find where this parameter ends, either the '&' or the end of the
        937 // query parameters.
        938 position = uri.indexOf('&', foundIndex);
        939 if (position < 0 || position > hashOrEndIndex) {
        940 position = hashOrEndIndex;
        941 }
        942
        943 // Progress forth to the end of the "key=" or "key&" substring.
        944 foundIndex += keyEncoded.length + 1;
        945 // Use substr, because it (unlike substring) will return empty string
        946 // if foundIndex > position.
        947 result.push(goog.string.urlDecode(uri.substr(
        948 foundIndex, position - foundIndex)));
        949 }
        950
        951 return result;
        952};
        953
        954
        955/**
        956 * Regexp to find trailing question marks and ampersands.
        957 * @type {RegExp}
        958 * @private
        959 */
        960goog.uri.utils.trailingQueryPunctuationRe_ = /[?&]($|#)/;
        961
        962
        963/**
        964 * Removes all instances of a query parameter.
        965 * @param {string} uri The URI to process. Must not contain a fragment.
        966 * @param {string} keyEncoded The URI-encoded key.
        967 * @return {string} The URI with all instances of the parameter removed.
        968 */
        969goog.uri.utils.removeParam = function(uri, keyEncoded) {
        970 var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);
        971 var position = 0;
        972 var foundIndex;
        973 var buffer = [];
        974
        975 // Look for a query parameter.
        976 while ((foundIndex = goog.uri.utils.findParam_(
        977 uri, position, keyEncoded, hashOrEndIndex)) >= 0) {
        978 // Get the portion of the query string up to, but not including, the ?
        979 // or & starting the parameter.
        980 buffer.push(uri.substring(position, foundIndex));
        981 // Progress to immediately after the '&'. If not found, go to the end.
        982 // Avoid including the hash mark.
        983 position = Math.min((uri.indexOf('&', foundIndex) + 1) || hashOrEndIndex,
        984 hashOrEndIndex);
        985 }
        986
        987 // Append everything that is remaining.
        988 buffer.push(uri.substr(position));
        989
        990 // Join the buffer, and remove trailing punctuation that remains.
        991 return buffer.join('').replace(
        992 goog.uri.utils.trailingQueryPunctuationRe_, '$1');
        993};
        994
        995
        996/**
        997 * Replaces all existing definitions of a parameter with a single definition.
        998 *
        999 * Repeated calls to this can exhibit quadratic behavior due to the need to
        1000 * find existing instances and reconstruct the string, though it should be
        1001 * limited given the 2kb limit. Consider using appendParams to append multiple
        1002 * parameters in bulk.
        1003 *
        1004 * @param {string} uri The original URI, which may already have query data.
        1005 * @param {string} keyEncoded The key, which must already be URI encoded.
        1006 * @param {*} value The value, which will be stringized and encoded (assumed
        1007 * not already to be encoded).
        1008 * @return {string} The URI with the query parameter added.
        1009 */
        1010goog.uri.utils.setParam = function(uri, keyEncoded, value) {
        1011 return goog.uri.utils.appendParam(
        1012 goog.uri.utils.removeParam(uri, keyEncoded), keyEncoded, value);
        1013};
        1014
        1015
        1016/**
        1017 * Generates a URI path using a given URI and a path with checks to
        1018 * prevent consecutive "//". The baseUri passed in must not contain
        1019 * query or fragment identifiers. The path to append may not contain query or
        1020 * fragment identifiers.
        1021 *
        1022 * @param {string} baseUri URI to use as the base.
        1023 * @param {string} path Path to append.
        1024 * @return {string} Updated URI.
        1025 */
        1026goog.uri.utils.appendPath = function(baseUri, path) {
        1027 goog.uri.utils.assertNoFragmentsOrQueries_(baseUri);
        1028
        1029 // Remove any trailing '/'
        1030 if (goog.string.endsWith(baseUri, '/')) {
        1031 baseUri = baseUri.substr(0, baseUri.length - 1);
        1032 }
        1033 // Remove any leading '/'
        1034 if (goog.string.startsWith(path, '/')) {
        1035 path = path.substr(1);
        1036 }
        1037 return goog.string.buildString(baseUri, '/', path);
        1038};
        1039
        1040
        1041/**
        1042 * Replaces the path.
        1043 * @param {string} uri URI to use as the base.
        1044 * @param {string} path New path.
        1045 * @return {string} Updated URI.
        1046 */
        1047goog.uri.utils.setPath = function(uri, path) {
        1048 // Add any missing '/'.
        1049 if (!goog.string.startsWith(path, '/')) {
        1050 path = '/' + path;
        1051 }
        1052 var parts = goog.uri.utils.split(uri);
        1053 return goog.uri.utils.buildFromEncodedParts(
        1054 parts[goog.uri.utils.ComponentIndex.SCHEME],
        1055 parts[goog.uri.utils.ComponentIndex.USER_INFO],
        1056 parts[goog.uri.utils.ComponentIndex.DOMAIN],
        1057 parts[goog.uri.utils.ComponentIndex.PORT],
        1058 path,
        1059 parts[goog.uri.utils.ComponentIndex.QUERY_DATA],
        1060 parts[goog.uri.utils.ComponentIndex.FRAGMENT]);
        1061};
        1062
        1063
        1064/**
        1065 * Standard supported query parameters.
        1066 * @enum {string}
        1067 */
        1068goog.uri.utils.StandardQueryParam = {
        1069
        1070 /** Unused parameter for unique-ifying. */
        1071 RANDOM: 'zx'
        1072};
        1073
        1074
        1075/**
        1076 * Sets the zx parameter of a URI to a random value.
        1077 * @param {string} uri Any URI.
        1078 * @return {string} That URI with the "zx" parameter added or replaced to
        1079 * contain a random string.
        1080 */
        1081goog.uri.utils.makeUnique = function(uri) {
        1082 return goog.uri.utils.setParam(uri,
        1083 goog.uri.utils.StandardQueryParam.RANDOM, goog.string.getRandomString());
        1084};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/goog/useragent/product.js.src.html b/docs/api/javascript/source/lib/goog/useragent/product.js.src.html index a79a97b3abe3d..67b3fd65d4843 100644 --- a/docs/api/javascript/source/lib/goog/useragent/product.js.src.html +++ b/docs/api/javascript/source/lib/goog/useragent/product.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/useragent/product_isversion.js.src.html b/docs/api/javascript/source/lib/goog/useragent/product_isversion.js.src.html index 4f99683e9f05a..18025d8cac1c8 100644 --- a/docs/api/javascript/source/lib/goog/useragent/product_isversion.js.src.html +++ b/docs/api/javascript/source/lib/goog/useragent/product_isversion.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/goog/useragent/useragent.js.src.html b/docs/api/javascript/source/lib/goog/useragent/useragent.js.src.html index 48508b1f84697..09d123f439d2c 100644 --- a/docs/api/javascript/source/lib/goog/useragent/useragent.js.src.html +++ b/docs/api/javascript/source/lib/goog/useragent/useragent.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/abstractbuilder.js.src.html b/docs/api/javascript/source/lib/webdriver/abstractbuilder.js.src.html index 242c7a74000d2..a0de85ae2ea10 100644 --- a/docs/api/javascript/source/lib/webdriver/abstractbuilder.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/abstractbuilder.js.src.html @@ -1 +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 +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 * Sets the logging preferences for the created session. Preferences may be
        119 * changed by repeated calls, or by calling {@link #withCapabilities}.
        120 * @param {!(webdriver.logging.Preferences|Object.<string, string>)} prefs The
        121 * desired logging preferences.
        122 * @return {!webdriver.AbstractBuilder} This Builder instance for chain calling.
        123 */
        124webdriver.AbstractBuilder.prototype.setLoggingPreferences = function(prefs) {
        125 this.capabilities_.set(webdriver.Capability.LOGGING_PREFS, prefs);
        126 return this;
        127};
        128
        129
        130/**
        131 * Builds a new {@link webdriver.WebDriver} instance using this builder's
        132 * current configuration.
        133 * @return {!webdriver.WebDriver} A new WebDriver client.
        134 */
        135webdriver.AbstractBuilder.prototype.build = goog.abstractMethod;
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/webdriver/actionsequence.js.src.html b/docs/api/javascript/source/lib/webdriver/actionsequence.js.src.html index 711b4dea642b0..4ae23ef62e904 100644 --- a/docs/api/javascript/source/lib/webdriver/actionsequence.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/actionsequence.js.src.html @@ -1 +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 +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).getId().
        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/docs/api/javascript/source/lib/webdriver/builder.js.src.html b/docs/api/javascript/source/lib/webdriver/builder.js.src.html index 8e10924159e43..c51d70d294a4c 100644 --- a/docs/api/javascript/source/lib/webdriver/builder.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/builder.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/button.js.src.html b/docs/api/javascript/source/lib/webdriver/button.js.src.html index 2a8728a6903ab..6bf866ce7a52c 100644 --- a/docs/api/javascript/source/lib/webdriver/button.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/button.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/capabilities.js.src.html b/docs/api/javascript/source/lib/webdriver/capabilities.js.src.html index bd1a54bae5497..dd5cdf0ea9253 100644 --- a/docs/api/javascript/source/lib/webdriver/capabilities.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/capabilities.js.src.html @@ -1 +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 +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');
        22goog.provide('webdriver.ProxyConfig');
        23
        24goog.require('webdriver.logging.Preferences');
        25
        26
        27
        28/**
        29 * Recognized browser names.
        30 * @enum {string}
        31 */
        32webdriver.Browser = {
        33 ANDROID: 'android',
        34 CHROME: 'chrome',
        35 FIREFOX: 'firefox',
        36 INTERNET_EXPLORER: 'internet explorer',
        37 IPAD: 'iPad',
        38 IPHONE: 'iPhone',
        39 OPERA: 'opera',
        40 PHANTOM_JS: 'phantomjs',
        41 SAFARI: 'safari',
        42 HTMLUNIT: 'htmlunit'
        43};
        44
        45
        46
        47/**
        48 * Describes how a proxy should be configured for a WebDriver session.
        49 * Proxy configuration object, as defined by the WebDriver wire protocol.
        50 * @typedef {(
        51 * {proxyType: string}|
        52 * {proxyType: string,
        53 * proxyAutoconfigUrl: string}|
        54 * {proxyType: string,
        55 * ftpProxy: string,
        56 * httpProxy: string,
        57 * sslProxy: string,
        58 * noProxy: string})}
        59 */
        60webdriver.ProxyConfig;
        61
        62
        63
        64/**
        65 * Common webdriver capability keys.
        66 * @enum {string}
        67 */
        68webdriver.Capability = {
        69
        70 /**
        71 * Indicates whether a driver should accept all SSL certs by default. This
        72 * capability only applies when requesting a new session. To query whether
        73 * a driver can handle insecure SSL certs, see
        74 * {@link webdriver.Capability.SECURE_SSL}.
        75 */
        76 ACCEPT_SSL_CERTS: 'acceptSslCerts',
        77
        78
        79 /**
        80 * The browser name. Common browser names are defined in the
        81 * {@link webdriver.Browser} enum.
        82 */
        83 BROWSER_NAME: 'browserName',
        84
        85 /**
        86 * Defines how elements should be scrolled into the viewport for interaction.
        87 * This capability will be set to zero (0) if elements are aligned with the
        88 * top of the viewport, or one (1) if aligned with the bottom. The default
        89 * behavior is to align with the top of the viewport.
        90 */
        91 ELEMENT_SCROLL_BEHAVIOR: 'elementScrollBehavior',
        92
        93 /**
        94 * Whether the driver is capable of handling modal alerts (e.g. alert,
        95 * confirm, prompt). To define how a driver <i>should</i> handle alerts,
        96 * use {@link webdriver.Capability.UNEXPECTED_ALERT_BEHAVIOR}.
        97 */
        98 HANDLES_ALERTS: 'handlesAlerts',
        99
        100 /**
        101 * Key for the logging driver logging preferences.
        102 */
        103 LOGGING_PREFS: 'loggingPrefs',
        104
        105 /**
        106 * Whether this session generates native events when simulating user input.
        107 */
        108 NATIVE_EVENTS: 'nativeEvents',
        109
        110 /**
        111 * Describes the platform the browser is running on. Will be one of
        112 * ANDROID, IOS, LINUX, MAC, UNIX, or WINDOWS. When <i>requesting</i> a
        113 * session, ANY may be used to indicate no platform preference (this is
        114 * semantically equivalent to omitting the platform capability).
        115 */
        116 PLATFORM: 'platform',
        117
        118 /**
        119 * Describes the proxy configuration to use for a new WebDriver session.
        120 */
        121 PROXY: 'proxy',
        122
        123 /** Whether the driver supports changing the brower's orientation. */
        124 ROTATABLE: 'rotatable',
        125
        126 /**
        127 * Whether a driver is only capable of handling secure SSL certs. To request
        128 * that a driver accept insecure SSL certs by default, use
        129 * {@link webdriver.Capability.ACCEPT_SSL_CERTS}.
        130 */
        131 SECURE_SSL: 'secureSsl',
        132
        133 /** Whether the driver supports manipulating the app cache. */
        134 SUPPORTS_APPLICATION_CACHE: 'applicationCacheEnabled',
        135
        136 /** Whether the driver supports locating elements with CSS selectors. */
        137 SUPPORTS_CSS_SELECTORS: 'cssSelectorsEnabled',
        138
        139 /** Whether the browser supports JavaScript. */
        140 SUPPORTS_JAVASCRIPT: 'javascriptEnabled',
        141
        142 /** Whether the driver supports controlling the browser's location info. */
        143 SUPPORTS_LOCATION_CONTEXT: 'locationContextEnabled',
        144
        145 /** Whether the driver supports taking screenshots. */
        146 TAKES_SCREENSHOT: 'takesScreenshot',
        147
        148 /**
        149 * Defines how the driver should handle unexpected alerts. The value should
        150 * be one of "accept", "dismiss", or "ignore.
        151 */
        152 UNEXPECTED_ALERT_BEHAVIOR: 'unexpectedAlertBehavior',
        153
        154 /** Defines the browser version. */
        155 VERSION: 'version'
        156};
        157
        158
        159
        160/**
        161 * @param {(webdriver.Capabilities|Object)=} opt_other Another set of
        162 * capabilities to merge into this instance.
        163 * @constructor
        164 */
        165webdriver.Capabilities = function(opt_other) {
        166
        167 /** @private {!Object} */
        168 this.caps_ = {};
        169
        170 if (opt_other) {
        171 this.merge(opt_other);
        172 }
        173};
        174
        175
        176/**
        177 * @return {!webdriver.Capabilities} A basic set of capabilities for Android.
        178 */
        179webdriver.Capabilities.android = function() {
        180 return new webdriver.Capabilities().
        181 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.ANDROID).
        182 set(webdriver.Capability.PLATFORM, 'ANDROID');
        183};
        184
        185
        186/**
        187 * @return {!webdriver.Capabilities} A basic set of capabilities for Chrome.
        188 */
        189webdriver.Capabilities.chrome = function() {
        190 return new webdriver.Capabilities().
        191 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.CHROME);
        192};
        193
        194
        195/**
        196 * @return {!webdriver.Capabilities} A basic set of capabilities for Firefox.
        197 */
        198webdriver.Capabilities.firefox = function() {
        199 return new webdriver.Capabilities().
        200 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.FIREFOX);
        201};
        202
        203
        204/**
        205 * @return {!webdriver.Capabilities} A basic set of capabilities for
        206 * Internet Explorer.
        207 */
        208webdriver.Capabilities.ie = function() {
        209 return new webdriver.Capabilities().
        210 set(webdriver.Capability.BROWSER_NAME,
        211 webdriver.Browser.INTERNET_EXPLORER).
        212 set(webdriver.Capability.PLATFORM, 'WINDOWS');
        213};
        214
        215
        216/**
        217 * @return {!webdriver.Capabilities} A basic set of capabilities for iPad.
        218 */
        219webdriver.Capabilities.ipad = function() {
        220 return new webdriver.Capabilities().
        221 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.IPAD).
        222 set(webdriver.Capability.PLATFORM, 'MAC');
        223};
        224
        225
        226/**
        227 * @return {!webdriver.Capabilities} A basic set of capabilities for iPhone.
        228 */
        229webdriver.Capabilities.iphone = function() {
        230 return new webdriver.Capabilities().
        231 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.IPHONE).
        232 set(webdriver.Capability.PLATFORM, 'MAC');
        233};
        234
        235
        236/**
        237 * @return {!webdriver.Capabilities} A basic set of capabilities for Opera.
        238 */
        239webdriver.Capabilities.opera = function() {
        240 return new webdriver.Capabilities().
        241 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.OPERA);
        242};
        243
        244
        245/**
        246 * @return {!webdriver.Capabilities} A basic set of capabilities for
        247 * PhantomJS.
        248 */
        249webdriver.Capabilities.phantomjs = function() {
        250 return new webdriver.Capabilities().
        251 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.PHANTOM_JS);
        252};
        253
        254
        255/**
        256 * @return {!webdriver.Capabilities} A basic set of capabilities for Safari.
        257 */
        258webdriver.Capabilities.safari = function() {
        259 return new webdriver.Capabilities().
        260 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.SAFARI);
        261};
        262
        263
        264/**
        265 * @return {!webdriver.Capabilities} A basic set of capabilities for HTMLUnit.
        266 */
        267webdriver.Capabilities.htmlunit = function() {
        268 return new webdriver.Capabilities().
        269 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.HTMLUNIT);
        270};
        271
        272
        273/**
        274 * @return {!webdriver.Capabilities} A basic set of capabilities for HTMLUnit
        275 * with enabled Javascript.
        276 */
        277webdriver.Capabilities.htmlunitwithjs = function() {
        278 return new webdriver.Capabilities().
        279 set(webdriver.Capability.BROWSER_NAME, webdriver.Browser.HTMLUNIT).
        280 set(webdriver.Capability.SUPPORTS_JAVASCRIPT, true);
        281};
        282
        283
        284/** @return {!Object} The JSON representation of this instance. */
        285webdriver.Capabilities.prototype.toJSON = function() {
        286 return this.caps_;
        287};
        288
        289
        290/**
        291 * Merges another set of capabilities into this instance. Any duplicates in
        292 * the provided set will override those already set on this instance.
        293 * @param {!(webdriver.Capabilities|Object)} other The capabilities to
        294 * merge into this instance.
        295 * @return {!webdriver.Capabilities} A self reference.
        296 */
        297webdriver.Capabilities.prototype.merge = function(other) {
        298 var caps = other instanceof webdriver.Capabilities ?
        299 other.caps_ : other;
        300 for (var key in caps) {
        301 if (caps.hasOwnProperty(key)) {
        302 this.set(key, caps[key]);
        303 }
        304 }
        305 return this;
        306};
        307
        308
        309/**
        310 * @param {string} key The capability to set.
        311 * @param {*} value The capability value. Capability values must be JSON
        312 * serializable. Pass {@code null} to unset the capability.
        313 * @return {!webdriver.Capabilities} A self reference.
        314 */
        315webdriver.Capabilities.prototype.set = function(key, value) {
        316 if (goog.isDefAndNotNull(value)) {
        317 this.caps_[key] = value;
        318 } else {
        319 delete this.caps_[key];
        320 }
        321 return this;
        322};
        323
        324
        325/**
        326 * @param {string} key The capability to return.
        327 * @return {*} The capability with the given key, or {@code null} if it has
        328 * not been set.
        329 */
        330webdriver.Capabilities.prototype.get = function(key) {
        331 var val = null;
        332 if (this.caps_.hasOwnProperty(key)) {
        333 val = this.caps_[key];
        334 }
        335 return goog.isDefAndNotNull(val) ? val : null;
        336};
        337
        338
        339/**
        340 * @param {string} key The capability to check.
        341 * @return {boolean} Whether the specified capability is set.
        342 */
        343webdriver.Capabilities.prototype.has = function(key) {
        344 return !!this.get(key);
        345};
        346
        347
        348/**
        349 * Sets the logging preferences. Preferences may be specified as a
        350 * {@link webdriver.logging.Preferences} instance, or a as a map of log-type to
        351 * log-level.
        352 * @param {!(webdriver.logging.Preferences|Object.<string, string>)} prefs The
        353 * logging preferences.
        354 * @return {!webdriver.Capabilities} A self reference.
        355 */
        356webdriver.Capabilities.prototype.setLoggingPrefs = function(prefs) {
        357 return this.set(webdriver.Capability.LOGGING_PREFS, prefs);
        358};
        359
        360
        361/**
        362 * Sets the proxy configuration for this instance.
        363 * @param {webdriver.ProxyConfig} proxy The desired proxy configuration.
        364 * @return {!webdriver.Capabilities} A self reference.
        365 */
        366webdriver.Capabilities.prototype.setProxy = function(proxy) {
        367 return this.set(webdriver.Capability.PROXY, proxy);
        368};
        369
        370
        371/**
        372 * Sets whether native events should be used.
        373 * @param {boolean} enabled Whether to enable native events.
        374 * @return {!webdriver.Capabilities} A self reference.
        375 */
        376webdriver.Capabilities.prototype.setEnableNativeEvents = function(enabled) {
        377 return this.set(webdriver.Capability.NATIVE_EVENTS, enabled);
        378};
        379
        380
        381/**
        382 * Sets how elements should be scrolled into view for interaction.
        383 * @param {number} behavior The desired scroll behavior: either 0 to align with
        384 * the top of the viewport or 1 to align with the bottom.
        385 * @return {!webdriver.Capabilities} A self reference.
        386 */
        387webdriver.Capabilities.prototype.setScrollBehavior = function(behavior) {
        388 return this.set(webdriver.Capability.ELEMENT_SCROLL_BEHAVIOR, behavior);
        389};
        390
        391
        392/**
        393 * Sets the default action to take with an unexpected alert before returning
        394 * an error.
        395 * @param {string} behavior The desired behavior; should be "accept", "dismiss",
        396 * or "ignore". Defaults to "dismiss".
        397 * @return {!webdriver.Capabilities} A self reference.
        398 */
        399webdriver.Capabilities.prototype.setAlertBehavior = function(behavior) {
        400 return this.set(webdriver.Capability.UNEXPECTED_ALERT_BEHAVIOR, behavior);
        401};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/webdriver/command.js.src.html b/docs/api/javascript/source/lib/webdriver/command.js.src.html index a22ad8d5caaf3..34c531d7a8e18 100644 --- a/docs/api/javascript/source/lib/webdriver/command.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/command.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/events.js.src.html b/docs/api/javascript/source/lib/webdriver/events.js.src.html index c60d9c5f3cafe..adc622f27773e 100644 --- a/docs/api/javascript/source/lib/webdriver/events.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/events.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/firefoxdomexecutor.js.src.html b/docs/api/javascript/source/lib/webdriver/firefoxdomexecutor.js.src.html index 069f4dd27366f..3fb0708452d02 100644 --- a/docs/api/javascript/source/lib/webdriver/firefoxdomexecutor.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/firefoxdomexecutor.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/http/corsclient.js.src.html b/docs/api/javascript/source/lib/webdriver/http/corsclient.js.src.html index f33da44277eca..cb2a9287d7742 100644 --- a/docs/api/javascript/source/lib/webdriver/http/corsclient.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/http/corsclient.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/http/http.js.src.html b/docs/api/javascript/source/lib/webdriver/http/http.js.src.html index 291e8c329fa8d..222284721863e 100644 --- a/docs/api/javascript/source/lib/webdriver/http/http.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/http/http.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/http/xhrclient.js.src.html b/docs/api/javascript/source/lib/webdriver/http/xhrclient.js.src.html index d810afe048d49..a71f98f70d737 100644 --- a/docs/api/javascript/source/lib/webdriver/http/xhrclient.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/http/xhrclient.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/key.js.src.html b/docs/api/javascript/source/lib/webdriver/key.js.src.html index 4cb50acd00d53..d494624c86ced 100644 --- a/docs/api/javascript/source/lib/webdriver/key.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/key.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/locators.js.src.html b/docs/api/javascript/source/lib/webdriver/locators.js.src.html index 6587c120df3ca..28134d49780b1 100644 --- a/docs/api/javascript/source/lib/webdriver/locators.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/locators.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/logging.js.src.html b/docs/api/javascript/source/lib/webdriver/logging.js.src.html index b9153c0407401..fa077a9055a12 100644 --- a/docs/api/javascript/source/lib/webdriver/logging.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/logging.js.src.html @@ -1 +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 +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 * Logging levels.
        24 * @enum {{value: number, name: string}}
        25 */
        26webdriver.logging.Level = {
        27 ALL: {value: Number.MIN_VALUE, name: 'ALL'},
        28 DEBUG: {value: 700, name: 'DEBUG'},
        29 INFO: {value: 800, name: 'INFO'},
        30 WARNING: {value: 900, name: 'WARNING'},
        31 SEVERE: {value: 1000, name: 'SEVERE'},
        32 OFF: {value: Number.MAX_VALUE, name: 'OFF'}
        33};
        34
        35
        36/**
        37 * Converts a level name or value to a {@link webdriver.logging.Level} value.
        38 * If the name/value is not recognized, {@link webdriver.logging.Level.ALL}
        39 * will be returned.
        40 * @param {(number|string)} nameOrValue The log level name, or value, to
        41 * convert .
        42 * @return {!webdriver.logging.Level} The converted level.
        43 */
        44webdriver.logging.getLevel = function(nameOrValue) {
        45 var predicate = goog.isString(nameOrValue) ?
        46 function(val) { return val.name === nameOrValue; } :
        47 function(val) { return val.value === nameOrValue; };
        48
        49 return goog.object.findValue(webdriver.logging.Level, predicate) ||
        50 webdriver.logging.Level.ALL;
        51};
        52
        53
        54/**
        55 * Common log types.
        56 * @enum {string}
        57 */
        58webdriver.logging.Type = {
        59 /** Logs originating from the browser. */
        60 BROWSER: 'browser',
        61 /** Logs from a WebDriver client. */
        62 CLIENT: 'client',
        63 /** Logs from a WebDriver implementation. */
        64 DRIVER: 'driver',
        65 /** Logs related to performance. */
        66 PERFORMANCE: 'performance',
        67 /** Logs from the remote server. */
        68 SERVER: 'server'
        69};
        70
        71
        72/**
        73 * Describes the log preferences for a WebDriver session.
        74 * @constructor
        75 */
        76webdriver.logging.Preferences = function() {
        77 /** @private {!Object.<string, webdriver.logging.Level>} */
        78 this.prefs_ = {};
        79};
        80
        81
        82/**
        83 * Sets the desired logging level for a particular log type.
        84 * @param {(string|webdriver.logging.Type)} type The log type.
        85 * @param {!webdriver.logging.Level} level The desired log level.
        86 */
        87webdriver.logging.Preferences.prototype.setLevel = function(type, level) {
        88 this.prefs_[type] = level;
        89};
        90
        91
        92/**
        93 * Converts this instance to its JSON representation.
        94 * @return {!Object.<string, string>} The JSON representation of this set of
        95 * preferences.
        96 */
        97webdriver.logging.Preferences.prototype.toJSON = function() {
        98 var obj = {};
        99 for (var type in this.prefs_) {
        100 if (this.prefs_.hasOwnProperty(type)) {
        101 obj[type] = this.prefs_[type].name;
        102 }
        103 }
        104 return obj;
        105};
        106
        107
        108/**
        109 * A single log entry.
        110 * @param {(!webdriver.logging.Level|string)} level The entry level.
        111 * @param {string} message The log message.
        112 * @param {number=} opt_timestamp The time this entry was generated, in
        113 * milliseconds since 0:00:00, January 1, 1970 UTC. If omitted, the
        114 * current time will be used.
        115 * @param {string=} opt_type The log type, if known.
        116 * @constructor
        117 */
        118webdriver.logging.Entry = function(level, message, opt_timestamp, opt_type) {
        119
        120 /** @type {!webdriver.logging.Level} */
        121 this.level =
        122 goog.isString(level) ? webdriver.logging.getLevel(level) : level;
        123
        124 /** @type {string} */
        125 this.message = message;
        126
        127 /** @type {number} */
        128 this.timestamp = goog.isNumber(opt_timestamp) ? opt_timestamp : goog.now();
        129
        130 /** @type {string} */
        131 this.type = opt_type || '';
        132};
        133
        134
        135/**
        136 * @return {{level: string, message: string, timestamp: number,
        137 * type: string}} The JSON representation of this entry.
        138 */
        139webdriver.logging.Entry.prototype.toJSON = function() {
        140 return {
        141 'level': this.level.name,
        142 'message': this.message,
        143 'timestamp': this.timestamp,
        144 'type': this.type
        145 };
        146};
        147
        148
        149/**
        150 * Converts a {@link goog.debug.LogRecord} into a
        151 * {@link webdriver.logging.Entry}.
        152 * @param {!goog.debug.LogRecord} logRecord The record to convert.
        153 * @param {string=} opt_type The log type.
        154 * @return {!webdriver.logging.Entry} The converted entry.
        155 */
        156webdriver.logging.Entry.fromClosureLogRecord = function(logRecord, opt_type) {
        157 var closureLevel = logRecord.getLevel();
        158 var level = webdriver.logging.Level.SEVERE;
        159
        160 if (closureLevel.value <= webdriver.logging.Level.DEBUG.value) {
        161 level = webdriver.logging.Level.DEBUG;
        162 } else if (closureLevel.value <= webdriver.logging.Level.INFO.value) {
        163 level = webdriver.logging.Level.INFO;
        164 } else if (closureLevel.value <= webdriver.logging.Level.WARNING.value) {
        165 level = webdriver.logging.Level.WARNING;
        166 }
        167
        168 return new webdriver.logging.Entry(
        169 level,
        170 '[' + logRecord.getLoggerName() + '] ' + logRecord.getMessage(),
        171 logRecord.getMillis(),
        172 opt_type);
        173};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/webdriver/process.js.src.html b/docs/api/javascript/source/lib/webdriver/process.js.src.html index e0d858c2dc905..3d535667fd692 100644 --- a/docs/api/javascript/source/lib/webdriver/process.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/process.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/promise.js.src.html b/docs/api/javascript/source/lib/webdriver/promise.js.src.html index bc4471660588b..c596651b0ea99 100644 --- a/docs/api/javascript/source/lib/webdriver/promise.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/promise.js.src.html @@ -1 +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, callback);
        188};
        189
        190
        191
        192/**
        193 * Represents a value that will be resolved at some point in the future. This
        194 * class represents the protected "producer" half of a Promise - each Deferred
        195 * has a {@code promise} property that may be returned to consumers for
        196 * registering callbacks, reserving the ability to resolve the deferred to the
        197 * producer.
        198 *
        199 * <p>If this Deferred is rejected and there are no listeners registered before
        200 * the next turn of the event loop, the rejection will be passed to the
        201 * {@link webdriver.promise.ControlFlow} as an unhandled failure.
        202 *
        203 * <p>If this Deferred is cancelled, the cancellation reason will be forward to
        204 * the Deferred's canceller function (if provided). The canceller may return a
        205 * truth-y value to override the reason provided for rejection.
        206 *
        207 * @param {Function=} opt_canceller Function to call when cancelling the
        208 * computation of this instance's value.
        209 * @param {webdriver.promise.ControlFlow=} opt_flow The control flow
        210 * this instance was created under. This should only be provided during
        211 * unit tests.
        212 * @constructor
        213 * @extends {webdriver.promise.Promise.<T>}
        214 * @template T
        215 */
        216webdriver.promise.Deferred = function(opt_canceller, opt_flow) {
        217 /* NOTE: This class's implementation diverges from the prototypical style
        218 * used in the rest of the atoms library. This was done intentionally to
        219 * protect the internal Deferred state from consumers, as outlined by
        220 * http://wiki.commonjs.org/wiki/Promises
        221 */
        222 goog.base(this);
        223
        224 var flow = opt_flow || webdriver.promise.controlFlow();
        225
        226 /**
        227 * The listeners registered with this Deferred. Each element in the list will
        228 * be a 3-tuple of the callback function, errback function, and the
        229 * corresponding deferred object.
        230 * @type {!Array.<!webdriver.promise.Deferred.Listener_>}
        231 */
        232 var listeners = [];
        233
        234 /**
        235 * Whether this Deferred's resolution was ever handled by a listener.
        236 * If the Deferred is rejected and its value is not handled by a listener
        237 * before the next turn of the event loop, the error will be passed to the
        238 * global error handler.
        239 * @type {boolean}
        240 */
        241 var handled = false;
        242
        243 /**
        244 * Key for the timeout used to delay reproting an unhandled rejection to the
        245 * parent {@link webdriver.promise.ControlFlow}.
        246 * @type {?number}
        247 */
        248 var pendingRejectionKey = null;
        249
        250 /**
        251 * This Deferred's current state.
        252 * @type {!webdriver.promise.Deferred.State_}
        253 */
        254 var state = webdriver.promise.Deferred.State_.PENDING;
        255
        256 /**
        257 * This Deferred's resolved value; set when the state transitions from
        258 * {@code webdriver.promise.Deferred.State_.PENDING}.
        259 * @type {*}
        260 */
        261 var value;
        262
        263 /** @return {boolean} Whether this promise's value is still pending. */
        264 function isPending() {
        265 return state == webdriver.promise.Deferred.State_.PENDING;
        266 }
        267
        268 /**
        269 * Removes all of the listeners previously registered on this deferred.
        270 * @throws {Error} If this deferred has already been resolved.
        271 */
        272 function removeAll() {
        273 listeners = [];
        274 }
        275
        276 /**
        277 * Resolves this deferred. If the new value is a promise, this function will
        278 * wait for it to be resolved before notifying the registered listeners.
        279 * @param {!webdriver.promise.Deferred.State_} newState The deferred's new
        280 * state.
        281 * @param {*} newValue The deferred's new value.
        282 */
        283 function resolve(newState, newValue) {
        284 if (webdriver.promise.Deferred.State_.PENDING !== state) {
        285 return;
        286 }
        287
        288 state = webdriver.promise.Deferred.State_.BLOCKED;
        289
        290 if (webdriver.promise.isPromise(newValue) && newValue !== self) {
        291 var onFulfill = goog.partial(notifyAll, newState);
        292 var onReject = goog.partial(
        293 notifyAll, webdriver.promise.Deferred.State_.REJECTED);
        294 if (newValue instanceof webdriver.promise.Deferred) {
        295 newValue.then(onFulfill, onReject);
        296 } else {
        297 webdriver.promise.asap(newValue, onFulfill, onReject);
        298 }
        299
        300 } else {
        301 notifyAll(newState, newValue);
        302 }
        303 }
        304
        305 /**
        306 * Notifies all of the listeners registered with this Deferred that its state
        307 * has changed.
        308 * @param {!webdriver.promise.Deferred.State_} newState The deferred's new
        309 * state.
        310 * @param {*} newValue The deferred's new value.
        311 */
        312 function notifyAll(newState, newValue) {
        313 if (newState === webdriver.promise.Deferred.State_.REJECTED &&
        314 // We cannot check instanceof Error since the object may have been
        315 // created in a different JS context.
        316 goog.isObject(newValue) && goog.isString(newValue.message)) {
        317 newValue = flow.annotateError(/** @type {!Error} */(newValue));
        318 }
        319
        320 state = newState;
        321 value = newValue;
        322 while (listeners.length) {
        323 notify(listeners.shift());
        324 }
        325
        326 if (!handled && state == webdriver.promise.Deferred.State_.REJECTED) {
        327 pendingRejectionKey = propagateError(value);
        328 }
        329 }
        330
        331 /**
        332 * Propagates an unhandled rejection to the parent ControlFlow in a
        333 * future turn of the JavaScript event loop.
        334 * @param {*} error The error value to report.
        335 * @return {number} The key for the registered timeout.
        336 */
        337 function propagateError(error) {
        338 flow.pendingRejections_ += 1;
        339 return flow.timer.setTimeout(function() {
        340 flow.pendingRejections_ -= 1;
        341 flow.abortFrame_(error);
        342 }, 0);
        343 }
        344
        345 /**
        346 * Notifies a single listener of this Deferred's change in state.
        347 * @param {!webdriver.promise.Deferred.Listener_} listener The listener to
        348 * notify.
        349 */
        350 function notify(listener) {
        351 var func = state == webdriver.promise.Deferred.State_.RESOLVED ?
        352 listener.callback : listener.errback;
        353 if (func) {
        354 flow.runInNewFrame_(goog.partial(func, value),
        355 listener.fulfill, listener.reject);
        356 } else if (state == webdriver.promise.Deferred.State_.REJECTED) {
        357 listener.reject(value);
        358 } else {
        359 listener.fulfill(value);
        360 }
        361 }
        362
        363 /**
        364 * The consumer promise for this instance. Provides protected access to the
        365 * callback registering functions.
        366 * @type {!webdriver.promise.Promise.<T>}
        367 */
        368 var promise = new webdriver.promise.Promise();
        369
        370 /**
        371 * Registers a callback on this Deferred.
        372 *
        373 * @param {?(function(T): (R|webdriver.promise.Promise.<R>))=} opt_callback .
        374 * @param {?(function(*): (R|webdriver.promise.Promise.<R>))=} opt_errback .
        375 * @return {!webdriver.promise.Promise.<R>} A new promise representing the
        376 * result of the callback.
        377 * @template R
        378 * @see webdriver.promise.Promise#then
        379 */
        380 function then(opt_callback, opt_errback) {
        381 // Avoid unnecessary allocations if we weren't given any callback functions.
        382 if (!opt_callback && !opt_errback) {
        383 return promise;
        384 }
        385
        386 // The moment a listener is registered, we consider this deferred to be
        387 // handled; the callback must handle any rejection errors.
        388 handled = true;
        389 if (pendingRejectionKey) {
        390 flow.pendingRejections_ -= 1;
        391 flow.timer.clearTimeout(pendingRejectionKey);
        392 }
        393
        394 var deferred = new webdriver.promise.Deferred(cancel, flow);
        395 var listener = {
        396 callback: opt_callback,
        397 errback: opt_errback,
        398 fulfill: deferred.fulfill,
        399 reject: deferred.reject
        400 };
        401
        402 if (state == webdriver.promise.Deferred.State_.PENDING ||
        403 state == webdriver.promise.Deferred.State_.BLOCKED) {
        404 listeners.push(listener);
        405 } else {
        406 notify(listener);
        407 }
        408
        409 return deferred.promise;
        410 }
        411
        412 var self = this;
        413
        414 /**
        415 * Resolves this promise with the given value. If the value is itself a
        416 * promise and not a reference to this deferred, this instance will wait for
        417 * it before resolving.
        418 * @param {T=} opt_value The fulfilled value.
        419 */
        420 function fulfill(opt_value) {
        421 resolve(webdriver.promise.Deferred.State_.RESOLVED, opt_value);
        422 }
        423
        424 /**
        425 * Rejects this promise. If the error is itself a promise, this instance will
        426 * be chained to it and be rejected with the error's resolved value.
        427 * @param {*=} opt_error The rejection reason, typically either a
        428 * {@code Error} or a {@code string}.
        429 */
        430 function reject(opt_error) {
        431 resolve(webdriver.promise.Deferred.State_.REJECTED, opt_error);
        432 }
        433
        434 /**
        435 * Attempts to cancel the computation of this instance's value. This attempt
        436 * will silently fail if this instance has already resolved.
        437 * @param {*=} opt_reason The reason for cancelling this promise.
        438 */
        439 function cancel(opt_reason) {
        440 if (!isPending()) {
        441 return;
        442 }
        443
        444 if (opt_canceller) {
        445 opt_reason = opt_canceller(opt_reason) || opt_reason;
        446 }
        447
        448 reject(opt_reason);
        449 }
        450
        451 this.promise = promise;
        452 this.promise.then = this.then = then;
        453 this.promise.cancel = this.cancel = cancel;
        454 this.promise.isPending = this.isPending = isPending;
        455 this.fulfill = fulfill;
        456 this.reject = this.errback = reject;
        457
        458 // Only expose this function to our internal classes.
        459 // TODO: find a cleaner way of handling this.
        460 if (this instanceof webdriver.promise.Task_) {
        461 this.removeAll = removeAll;
        462 }
        463
        464 // Export symbols necessary for the contract on this object to work in
        465 // compiled mode.
        466 goog.exportProperty(this, 'then', this.then);
        467 goog.exportProperty(this, 'cancel', cancel);
        468 goog.exportProperty(this, 'fulfill', fulfill);
        469 goog.exportProperty(this, 'reject', reject);
        470 goog.exportProperty(this, 'isPending', isPending);
        471 goog.exportProperty(this, 'promise', this.promise);
        472 goog.exportProperty(this.promise, 'then', this.then);
        473 goog.exportProperty(this.promise, 'cancel', cancel);
        474 goog.exportProperty(this.promise, 'isPending', isPending);
        475};
        476goog.inherits(webdriver.promise.Deferred, webdriver.promise.Promise);
        477
        478
        479/**
        480 * Type definition for a listener registered on a Deferred object.
        481 * @typedef {{callback:(Function|undefined),
        482 * errback:(Function|undefined),
        483 * fulfill: function(*), reject: function(*)}}
        484 * @private
        485 */
        486webdriver.promise.Deferred.Listener_;
        487
        488
        489/**
        490 * The three states a {@link webdriver.promise.Deferred} object may be in.
        491 * @enum {number}
        492 * @private
        493 */
        494webdriver.promise.Deferred.State_ = {
        495 REJECTED: -1,
        496 PENDING: 0,
        497 BLOCKED: 1,
        498 RESOLVED: 2
        499};
        500
        501
        502/**
        503 * Tests if a value is an Error-like object. This is more than an straight
        504 * instanceof check since the value may originate from another context.
        505 * @param {*} value The value to test.
        506 * @return {boolean} Whether the value is an error.
        507 * @private
        508 */
        509webdriver.promise.isError_ = function(value) {
        510 return value instanceof Error ||
        511 goog.isObject(value) &&
        512 (Object.prototype.toString.call(value) === '[object Error]' ||
        513 // A special test for goog.testing.JsUnitException.
        514 value.isJsUnitException);
        515
        516};
        517
        518
        519/**
        520 * Determines whether a {@code value} should be treated as a promise.
        521 * Any object whose "then" property is a function will be considered a promise.
        522 *
        523 * @param {*} value The value to test.
        524 * @return {boolean} Whether the value is a promise.
        525 */
        526webdriver.promise.isPromise = function(value) {
        527 return !!value && goog.isObject(value) &&
        528 // Use array notation so the Closure compiler does not obfuscate away our
        529 // contract.
        530 goog.isFunction(value['then']);
        531};
        532
        533
        534/**
        535 * Creates a promise that will be resolved at a set time in the future.
        536 * @param {number} ms The amount of time, in milliseconds, to wait before
        537 * resolving the promise.
        538 * @return {!webdriver.promise.Promise} The promise.
        539 */
        540webdriver.promise.delayed = function(ms) {
        541 var timer = webdriver.promise.controlFlow().timer;
        542 var key;
        543 var deferred = new webdriver.promise.Deferred(function() {
        544 timer.clearTimeout(key);
        545 });
        546 key = timer.setTimeout(deferred.fulfill, ms);
        547 return deferred.promise;
        548};
        549
        550
        551/**
        552 * Creates a new deferred object.
        553 * @param {Function=} opt_canceller Function to call when cancelling the
        554 * computation of this instance's value.
        555 * @return {!webdriver.promise.Deferred.<T>} The new deferred object.
        556 * @template T
        557 */
        558webdriver.promise.defer = function(opt_canceller) {
        559 return new webdriver.promise.Deferred(opt_canceller);
        560};
        561
        562
        563/**
        564 * Creates a promise that has been resolved with the given value.
        565 * @param {T=} opt_value The resolved value.
        566 * @return {!webdriver.promise.Promise.<T>} The resolved promise.
        567 * @template T
        568 */
        569webdriver.promise.fulfilled = function(opt_value) {
        570 if (opt_value instanceof webdriver.promise.Promise) {
        571 return opt_value;
        572 }
        573 var deferred = new webdriver.promise.Deferred();
        574 deferred.fulfill(opt_value);
        575 return deferred.promise;
        576};
        577
        578
        579/**
        580 * Creates a promise that has been rejected with the given reason.
        581 * @param {*=} opt_reason The rejection reason; may be any value, but is
        582 * usually an Error or a string.
        583 * @return {!webdriver.promise.Promise.<T>} The rejected promise.
        584 * @template T
        585 */
        586webdriver.promise.rejected = function(opt_reason) {
        587 var deferred = new webdriver.promise.Deferred();
        588 deferred.reject(opt_reason);
        589 return deferred.promise;
        590};
        591
        592
        593/**
        594 * Wraps a function that is assumed to be a node-style callback as its final
        595 * argument. This callback takes two arguments: an error value (which will be
        596 * null if the call succeeded), and the success value as the second argument.
        597 * If the call fails, the returned promise will be rejected, otherwise it will
        598 * be resolved with the result.
        599 * @param {!Function} fn The function to wrap.
        600 * @return {!webdriver.promise.Promise} A promise that will be resolved with the
        601 * result of the provided function's callback.
        602 */
        603webdriver.promise.checkedNodeCall = function(fn) {
        604 var deferred = new webdriver.promise.Deferred(function() {
        605 throw Error('This Deferred may not be cancelled');
        606 });
        607 try {
        608 fn(function(error, value) {
        609 error ? deferred.reject(error) : deferred.fulfill(value);
        610 });
        611 } catch (ex) {
        612 deferred.reject(ex);
        613 }
        614 return deferred.promise;
        615};
        616
        617
        618/**
        619 * Registers an observer on a promised {@code value}, returning a new promise
        620 * that will be resolved when the value is. If {@code value} is not a promise,
        621 * then the return promise will be immediately resolved.
        622 * @param {*} value The value to observe.
        623 * @param {Function=} opt_callback The function to call when the value is
        624 * resolved successfully.
        625 * @param {Function=} opt_errback The function to call when the value is
        626 * rejected.
        627 * @return {!webdriver.promise.Promise} A new promise.
        628 */
        629webdriver.promise.when = function(value, opt_callback, opt_errback) {
        630 if (value instanceof webdriver.promise.Promise) {
        631 return value.then(opt_callback, opt_errback);
        632 }
        633
        634 var deferred = new webdriver.promise.Deferred();
        635
        636 webdriver.promise.asap(value, deferred.fulfill, deferred.reject);
        637
        638 return deferred.then(opt_callback, opt_errback);
        639};
        640
        641
        642/**
        643 * Invokes the appropriate callback function as soon as a promised
        644 * {@code value} is resolved. This function is similar to
        645 * {@link webdriver.promise.when}, except it does not return a new promise.
        646 * @param {*} value The value to observe.
        647 * @param {Function} callback The function to call when the value is
        648 * resolved successfully.
        649 * @param {Function=} opt_errback The function to call when the value is
        650 * rejected.
        651 */
        652webdriver.promise.asap = function(value, callback, opt_errback) {
        653 if (webdriver.promise.isPromise(value)) {
        654 value.then(callback, opt_errback);
        655
        656 // Maybe a Dojo-like deferred object?
        657 } else if (!!value && goog.isObject(value) &&
        658 goog.isFunction(value.addCallbacks)) {
        659 value.addCallbacks(callback, opt_errback);
        660
        661 // A raw value, return a resolved promise.
        662 } else if (callback) {
        663 callback(value);
        664 }
        665};
        666
        667
        668/**
        669 * Given an array of promises, will return a promise that will be fulfilled
        670 * with the fulfillment values of the input array's values. If any of the
        671 * input array's promises are rejected, the returned promise will be rejected
        672 * with the same reason.
        673 *
        674 * @param {!Array.<(T|!webdriver.promise.Promise.<T>)>} arr An array of
        675 * promises to wait on.
        676 * @return {!webdriver.promise.Promise.<!Array.<T>>} A promise that is
        677 * fulfilled with an array containing the fulfilled values of the
        678 * input array, or rejected with the same reason as the first
        679 * rejected value.
        680 * @template T
        681 */
        682webdriver.promise.all = function(arr) {
        683 var n = arr.length;
        684 if (!n) {
        685 return webdriver.promise.fulfilled([]);
        686 }
        687
        688 var toFulfill = n;
        689 var result = webdriver.promise.defer();
        690 var values = [];
        691
        692 var onFulfill = function(index, value) {
        693 values[index] = value;
        694 toFulfill--;
        695 if (toFulfill == 0) {
        696 result.fulfill(values);
        697 }
        698 };
        699
        700 for (var i = 0; i < n; ++i) {
        701 webdriver.promise.asap(
        702 arr[i], goog.partial(onFulfill, i), result.reject);
        703 }
        704
        705 return result.promise;
        706};
        707
        708
        709/**
        710 * Calls a function for each element in an array and inserts the result into a
        711 * new array, which is used as the fulfillment value of the promise returned
        712 * by this function.
        713 *
        714 * <p>If the return value of the mapping function is a promise, this function
        715 * will wait for it to be fulfilled before inserting it into the new array.
        716 *
        717 * <p>If the mapping function throws or returns a rejected promise, the
        718 * promise returned by this function will be rejected with the same reason.
        719 * Only the first failure will be reported; all subsequent errors will be
        720 * silently ignored.
        721 *
        722 * @param {!(Array.<TYPE>|webdriver.promise.Promise.<!Array.<TYPE>>)} arr The
        723 * array to iterator over, or a promise that will resolve to said array.
        724 * @param {function(this: SELF, TYPE, number, !Array.<TYPE>): ?} fn The
        725 * function to call for each element in the array. This function should
        726 * expect three arguments (the element, the index, and the array itself.
        727 * @param {SELF=} opt_self The object to be used as the value of 'this' within
        728 * {@code fn}.
        729 * @template TYPE, SELF
        730 */
        731webdriver.promise.map = function(arr, fn, opt_self) {
        732 return webdriver.promise.when(arr, function(arr) {
        733 var result = goog.array.map(arr, fn, opt_self);
        734 return webdriver.promise.all(result);
        735 });
        736};
        737
        738
        739/**
        740 * Calls a function for each element in an array, and if the function returns
        741 * true adds the element to a new array.
        742 *
        743 * <p>If the return value of the filter function is a promise, this function
        744 * will wait for it to be fulfilled before determining whether to insert the
        745 * element into the new array.
        746 *
        747 * <p>If the filter function throws or returns a rejected promise, the promise
        748 * returned by this function will be rejected with the same reason. Only the
        749 * first failure will be reported; all subsequent errors will be silently
        750 * ignored.
        751 *
        752 * @param {!(Array.<TYPE>|webdriver.promise.Promise.<!Array.<TYPE>>)} arr The
        753 * array to iterator over, or a promise that will resolve to said array.
        754 * @param {function(this: SELF, TYPE, number, !Array.<TYPE>): (
        755 * boolean|webdriver.promise.Promise.<boolean>)} fn The function
        756 * to call for each element in the array.
        757 * @param {SELF=} opt_self The object to be used as the value of 'this' within
        758 * {@code fn}.
        759 * @template TYPE, SELF
        760 */
        761webdriver.promise.filter = function(arr, fn, opt_self) {
        762 return webdriver.promise.when(arr, function(arr) {
        763 var originalValues = goog.array.clone(arr);
        764 return webdriver.promise.map(arr, fn, opt_self).then(function(include) {
        765 return goog.array.filter(originalValues, function(value, index) {
        766 return include[index];
        767 });
        768 });
        769 });
        770};
        771
        772
        773/**
        774 * Returns a promise that will be resolved with the input value in a
        775 * fully-resolved state. If the value is an array, each element will be fully
        776 * resolved. Likewise, if the value is an object, all keys will be fully
        777 * resolved. In both cases, all nested arrays and objects will also be
        778 * fully resolved. All fields are resolved in place; the returned promise will
        779 * resolve on {@code value} and not a copy.
        780 *
        781 * Warning: This function makes no checks against objects that contain
        782 * cyclical references:
        783 * <pre><code>
        784 * var value = {};
        785 * value['self'] = value;
        786 * webdriver.promise.fullyResolved(value); // Stack overflow.
        787 * </code></pre>
        788 *
        789 * @param {*} value The value to fully resolve.
        790 * @return {!webdriver.promise.Promise} A promise for a fully resolved version
        791 * of the input value.
        792 */
        793webdriver.promise.fullyResolved = function(value) {
        794 if (webdriver.promise.isPromise(value)) {
        795 return webdriver.promise.when(value, webdriver.promise.fullyResolveValue_);
        796 }
        797 return webdriver.promise.fullyResolveValue_(value);
        798};
        799
        800
        801/**
        802 * @param {*} value The value to fully resolve. If a promise, assumed to
        803 * already be resolved.
        804 * @return {!webdriver.promise.Promise} A promise for a fully resolved version
        805 * of the input value.
        806 * @private
        807 */
        808webdriver.promise.fullyResolveValue_ = function(value) {
        809 switch (goog.typeOf(value)) {
        810 case 'array':
        811 return webdriver.promise.fullyResolveKeys_(
        812 /** @type {!Array} */ (value));
        813
        814 case 'object':
        815 if (webdriver.promise.isPromise(value)) {
        816 // We get here when the original input value is a promise that
        817 // resolves to itself. When the user provides us with such a promise,
        818 // trust that it counts as a "fully resolved" value and return it.
        819 // Of course, since it's already a promise, we can just return it
        820 // to the user instead of wrapping it in another promise.
        821 return /** @type {!webdriver.promise.Promise} */ (value);
        822 }
        823
        824 if (goog.isNumber(value.nodeType) &&
        825 goog.isObject(value.ownerDocument) &&
        826 goog.isNumber(value.ownerDocument.nodeType)) {
        827 // DOM node; return early to avoid infinite recursion. Should we
        828 // only support objects with a certain level of nesting?
        829 return webdriver.promise.fulfilled(value);
        830 }
        831
        832 return webdriver.promise.fullyResolveKeys_(
        833 /** @type {!Object} */ (value));
        834
        835 default: // boolean, function, null, number, string, undefined
        836 return webdriver.promise.fulfilled(value);
        837 }
        838};
        839
        840
        841/**
        842 * @param {!(Array|Object)} obj the object to resolve.
        843 * @return {!webdriver.promise.Promise} A promise that will be resolved with the
        844 * input object once all of its values have been fully resolved.
        845 * @private
        846 */
        847webdriver.promise.fullyResolveKeys_ = function(obj) {
        848 var isArray = goog.isArray(obj);
        849 var numKeys = isArray ? obj.length : goog.object.getCount(obj);
        850 if (!numKeys) {
        851 return webdriver.promise.fulfilled(obj);
        852 }
        853
        854 var numResolved = 0;
        855 var deferred = new webdriver.promise.Deferred();
        856
        857 // In pre-IE9, goog.array.forEach will not iterate properly over arrays
        858 // containing undefined values because "index in array" returns false
        859 // when array[index] === undefined (even for x = [undefined, 1]). To get
        860 // around this, we need to use our own forEach implementation.
        861 // DO NOT REMOVE THIS UNTIL WE NO LONGER SUPPORT IE8. This cannot be
        862 // reproduced in IE9 by changing the browser/document modes, it requires an
        863 // actual pre-IE9 browser. Yay, IE!
        864 var forEachKey = !isArray ? goog.object.forEach : function(arr, fn) {
        865 var n = arr.length;
        866 for (var i = 0; i < n; ++i) {
        867 fn.call(null, arr[i], i, arr);
        868 }
        869 };
        870
        871 forEachKey(obj, function(partialValue, key) {
        872 var type = goog.typeOf(partialValue);
        873 if (type != 'array' && type != 'object') {
        874 maybeResolveValue();
        875 return;
        876 }
        877
        878 webdriver.promise.fullyResolved(partialValue).then(
        879 function(resolvedValue) {
        880 obj[key] = resolvedValue;
        881 maybeResolveValue();
        882 },
        883 deferred.reject);
        884 });
        885
        886 return deferred.promise;
        887
        888 function maybeResolveValue() {
        889 if (++numResolved == numKeys) {
        890 deferred.fulfill(obj);
        891 }
        892 }
        893};
        894
        895
        896//////////////////////////////////////////////////////////////////////////////
        897//
        898// webdriver.promise.ControlFlow
        899//
        900//////////////////////////////////////////////////////////////////////////////
        901
        902
        903
        904/**
        905 * Handles the execution of scheduled tasks, each of which may be an
        906 * asynchronous operation. The control flow will ensure tasks are executed in
        907 * the ordered scheduled, starting each task only once those before it have
        908 * completed.
        909 *
        910 * <p>Each task scheduled within this flow may return a
        911 * {@link webdriver.promise.Promise} to indicate it is an asynchronous
        912 * operation. The ControlFlow will wait for such promises to be resolved before
        913 * marking the task as completed.
        914 *
        915 * <p>Tasks and each callback registered on a {@link webdriver.promise.Deferred}
        916 * will be run in their own ControlFlow frame. Any tasks scheduled within a
        917 * frame will have priority over previously scheduled tasks. Furthermore, if
        918 * any of the tasks in the frame fails, the remainder of the tasks in that frame
        919 * will be discarded and the failure will be propagated to the user through the
        920 * callback/task's promised result.
        921 *
        922 * <p>Each time a ControlFlow empties its task queue, it will fire an
        923 * {@link webdriver.promise.ControlFlow.EventType.IDLE} event. Conversely,
        924 * whenever the flow terminates due to an unhandled error, it will remove all
        925 * remaining tasks in its queue and fire an
        926 * {@link webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION} event. If
        927 * there are no listeners registered with the flow, the error will be
        928 * rethrown to the global error handler.
        929 *
        930 * @param {webdriver.promise.ControlFlow.Timer=} opt_timer The timer object
        931 * to use. Should only be set for testing.
        932 * @constructor
        933 * @extends {webdriver.EventEmitter}
        934 */
        935webdriver.promise.ControlFlow = function(opt_timer) {
        936 webdriver.EventEmitter.call(this);
        937
        938 /**
        939 * The timer used by this instance.
        940 * @type {webdriver.promise.ControlFlow.Timer}
        941 */
        942 this.timer = opt_timer || webdriver.promise.ControlFlow.defaultTimer;
        943
        944 /**
        945 * A list of recent tasks. Each time a new task is started, or a frame is
        946 * completed, the previously recorded task is removed from this list. If
        947 * there are multiple tasks, task N+1 is considered a sub-task of task
        948 * N.
        949 * @private {!Array.<!webdriver.promise.Task_>}
        950 */
        951 this.history_ = [];
        952};
        953goog.inherits(webdriver.promise.ControlFlow, webdriver.EventEmitter);
        954
        955
        956/**
        957 * @typedef {{clearInterval: function(number),
        958 * clearTimeout: function(number),
        959 * setInterval: function(!Function, number): number,
        960 * setTimeout: function(!Function, number): number}}
        961 */
        962webdriver.promise.ControlFlow.Timer;
        963
        964
        965/**
        966 * The default timer object, which uses the global timer functions.
        967 * @type {webdriver.promise.ControlFlow.Timer}
        968 */
        969webdriver.promise.ControlFlow.defaultTimer = (function() {
        970 // The default timer functions may be defined as free variables for the
        971 // current context, so do not reference them using "window" or
        972 // "goog.global". Also, we must invoke them in a closure, and not using
        973 // bind(), so we do not get "TypeError: Illegal invocation" (WebKit) or
        974 // "Invalid calling object" (IE) errors.
        975 return {
        976 clearInterval: wrap(clearInterval),
        977 clearTimeout: wrap(clearTimeout),
        978 setInterval: wrap(setInterval),
        979 setTimeout: wrap(setTimeout)
        980 };
        981
        982 function wrap(fn) {
        983 return function() {
        984 // Cannot use .call() or .apply() since we do not know which variable
        985 // the function is bound to, and using the wrong one will generate
        986 // an error.
        987 return fn(arguments[0], arguments[1]);
        988 };
        989 }
        990})();
        991
        992
        993/**
        994 * Events that may be emitted by an {@link webdriver.promise.ControlFlow}.
        995 * @enum {string}
        996 */
        997webdriver.promise.ControlFlow.EventType = {
        998
        999 /** Emitted when all tasks have been successfully executed. */
        1000 IDLE: 'idle',
        1001
        1002 /** Emitted whenever a new task has been scheduled. */
        1003 SCHEDULE_TASK: 'scheduleTask',
        1004
        1005 /**
        1006 * Emitted whenever a control flow aborts due to an unhandled promise
        1007 * rejection. This event will be emitted along with the offending rejection
        1008 * reason. Upon emitting this event, the control flow will empty its task
        1009 * queue and revert to its initial state.
        1010 */
        1011 UNCAUGHT_EXCEPTION: 'uncaughtException'
        1012};
        1013
        1014
        1015/**
        1016 * How often, in milliseconds, the event loop should run.
        1017 * @type {number}
        1018 * @const
        1019 */
        1020webdriver.promise.ControlFlow.EVENT_LOOP_FREQUENCY = 10;
        1021
        1022
        1023/**
        1024 * Tracks the active execution frame for this instance. Lazily initialized
        1025 * when the first task is scheduled.
        1026 * @private {webdriver.promise.Frame_}
        1027 */
        1028webdriver.promise.ControlFlow.prototype.activeFrame_ = null;
        1029
        1030
        1031/**
        1032 * A reference to the frame in which new tasks should be scheduled. If
        1033 * {@code null}, tasks will be scheduled within the active frame. When forcing
        1034 * a function to run in the context of a new frame, this pointer is used to
        1035 * ensure tasks are scheduled within the newly created frame, even though it
        1036 * won't be active yet.
        1037 * @private {webdriver.promise.Frame_}
        1038 * @see {#runInNewFrame_}
        1039 */
        1040webdriver.promise.ControlFlow.prototype.schedulingFrame_ = null;
        1041
        1042
        1043/**
        1044 * Timeout ID set when the flow is about to shutdown without any errors
        1045 * being detected. Upon shutting down, the flow will emit an
        1046 * {@link webdriver.promise.ControlFlow.EventType.IDLE} event. Idle events
        1047 * always follow a brief timeout in order to catch latent errors from the last
        1048 * completed task. If this task had a callback registered, but no errback, and
        1049 * the task fails, the unhandled failure would not be reported by the promise
        1050 * system until the next turn of the event loop:
        1051 *
        1052 * // Schedule 1 task that fails.
        1053 * var result = webriver.promise.controlFlow().schedule('example',
        1054 * function() { return webdriver.promise.rejected('failed'); });
        1055 * // Set a callback on the result. This delays reporting the unhandled
        1056 * // failure for 1 turn of the event loop.
        1057 * result.then(goog.nullFunction);
        1058 *
        1059 * @private {?number}
        1060 */
        1061webdriver.promise.ControlFlow.prototype.shutdownId_ = null;
        1062
        1063
        1064/**
        1065 * Interval ID for this instance's event loop.
        1066 * @private {?number}
        1067 */
        1068webdriver.promise.ControlFlow.prototype.eventLoopId_ = null;
        1069
        1070
        1071/**
        1072 * The number of "pending" promise rejections.
        1073 *
        1074 * <p>Each time a promise is rejected and is not handled by a listener, it will
        1075 * schedule a 0-based timeout to check if it is still unrejected in the next
        1076 * turn of the JS-event loop. This allows listeners to attach to, and handle,
        1077 * the rejected promise at any point in same turn of the event loop that the
        1078 * promise was rejected.
        1079 *
        1080 * <p>When this flow's own event loop triggers, it will not run if there
        1081 * are any outstanding promise rejections. This allows unhandled promises to
        1082 * be reported before a new task is started, ensuring the error is reported to
        1083 * the current task queue.
        1084 *
        1085 * @private {number}
        1086 */
        1087webdriver.promise.ControlFlow.prototype.pendingRejections_ = 0;
        1088
        1089
        1090/**
        1091 * The number of aborted frames since the last time a task was executed or a
        1092 * frame completed successfully.
        1093 * @private {number}
        1094 */
        1095webdriver.promise.ControlFlow.prototype.numAbortedFrames_ = 0;
        1096
        1097
        1098/**
        1099 * Resets this instance, clearing its queue and removing all event listeners.
        1100 */
        1101webdriver.promise.ControlFlow.prototype.reset = function() {
        1102 this.activeFrame_ = null;
        1103 this.clearHistory();
        1104 this.removeAllListeners();
        1105 this.cancelShutdown_();
        1106 this.cancelEventLoop_();
        1107};
        1108
        1109
        1110/**
        1111 * Returns a summary of the recent task activity for this instance. This
        1112 * includes the most recently completed task, as well as any parent tasks. In
        1113 * the returned summary, the task at index N is considered a sub-task of the
        1114 * task at index N+1.
        1115 * @return {!Array.<string>} A summary of this instance's recent task
        1116 * activity.
        1117 */
        1118webdriver.promise.ControlFlow.prototype.getHistory = function() {
        1119 var pendingTasks = [];
        1120 var currentFrame = this.activeFrame_;
        1121 while (currentFrame) {
        1122 var task = currentFrame.getPendingTask();
        1123 if (task) {
        1124 pendingTasks.push(task);
        1125 }
        1126 // A frame's parent node will always be another frame.
        1127 currentFrame =
        1128 /** @type {webdriver.promise.Frame_} */ (currentFrame.getParent());
        1129 }
        1130
        1131 var fullHistory = goog.array.concat(this.history_, pendingTasks);
        1132 return goog.array.map(fullHistory, function(task) {
        1133 return task.toString();
        1134 });
        1135};
        1136
        1137
        1138/** Clears this instance's task history. */
        1139webdriver.promise.ControlFlow.prototype.clearHistory = function() {
        1140 this.history_ = [];
        1141};
        1142
        1143
        1144/**
        1145 * Removes a completed task from this instance's history record. If any
        1146 * tasks remain from aborted frames, those will be removed as well.
        1147 * @private
        1148 */
        1149webdriver.promise.ControlFlow.prototype.trimHistory_ = function() {
        1150 if (this.numAbortedFrames_) {
        1151 goog.array.splice(this.history_,
        1152 this.history_.length - this.numAbortedFrames_,
        1153 this.numAbortedFrames_);
        1154 this.numAbortedFrames_ = 0;
        1155 }
        1156 this.history_.pop();
        1157};
        1158
        1159
        1160/**
        1161 * Property used to track whether an error has been annotated by
        1162 * {@link webdriver.promise.ControlFlow#annotateError}.
        1163 * @private {string}
        1164 * @const
        1165 */
        1166webdriver.promise.ControlFlow.ANNOTATION_PROPERTY_ =
        1167 'webdriver_promise_error_';
        1168
        1169
        1170/**
        1171 * Appends a summary of this instance's recent task history to the given
        1172 * error's stack trace. This function will also ensure the error's stack trace
        1173 * is in canonical form.
        1174 * @param {!(Error|goog.testing.JsUnitException)} e The error to annotate.
        1175 * @return {!(Error|goog.testing.JsUnitException)} The annotated error.
        1176 */
        1177webdriver.promise.ControlFlow.prototype.annotateError = function(e) {
        1178 if (!!e[webdriver.promise.ControlFlow.ANNOTATION_PROPERTY_]) {
        1179 return e;
        1180 }
        1181
        1182 var history = this.getHistory();
        1183 if (history.length) {
        1184 e = webdriver.stacktrace.format(e);
        1185
        1186 /** @type {!Error} */(e).stack += [
        1187 '\n==== async task ====\n',
        1188 history.join('\n==== async task ====\n')
        1189 ].join('');
        1190
        1191 e[webdriver.promise.ControlFlow.ANNOTATION_PROPERTY_] = true;
        1192 }
        1193
        1194 return e;
        1195};
        1196
        1197
        1198/**
        1199 * @return {string} The scheduled tasks still pending with this instance.
        1200 */
        1201webdriver.promise.ControlFlow.prototype.getSchedule = function() {
        1202 return this.activeFrame_ ? this.activeFrame_.getRoot().toString() : '[]';
        1203};
        1204
        1205
        1206/**
        1207 * Schedules a task for execution. If there is nothing currently in the
        1208 * queue, the task will be executed in the next turn of the event loop.
        1209 *
        1210 * @param {function(): (T|webdriver.promise.Promise.<T>)} fn The function to
        1211 * call to start the task. If the function returns a
        1212 * {@link webdriver.promise.Promise}, this instance will wait for it to be
        1213 * resolved before starting the next task.
        1214 * @param {string=} opt_description A description of the task.
        1215 * @return {!webdriver.promise.Promise.<T>} A promise that will be resolved
        1216 * with the result of the action.
        1217 * @template T
        1218 */
        1219webdriver.promise.ControlFlow.prototype.execute = function(
        1220 fn, opt_description) {
        1221 this.cancelShutdown_();
        1222
        1223 if (!this.activeFrame_) {
        1224 this.activeFrame_ = new webdriver.promise.Frame_(this);
        1225 }
        1226
        1227 // Trim an extra frame off the generated stack trace for the call to this
        1228 // function.
        1229 var snapshot = new webdriver.stacktrace.Snapshot(1);
        1230 var task = new webdriver.promise.Task_(
        1231 this, fn, opt_description || '', snapshot);
        1232 var scheduleIn = this.schedulingFrame_ || this.activeFrame_;
        1233 scheduleIn.addChild(task);
        1234
        1235 this.emit(webdriver.promise.ControlFlow.EventType.SCHEDULE_TASK, opt_description);
        1236
        1237 this.scheduleEventLoopStart_();
        1238 return task.promise;
        1239};
        1240
        1241
        1242/**
        1243 * Inserts a {@code setTimeout} into the command queue. This is equivalent to
        1244 * a thread sleep in a synchronous programming language.
        1245 *
        1246 * @param {number} ms The timeout delay, in milliseconds.
        1247 * @param {string=} opt_description A description to accompany the timeout.
        1248 * @return {!webdriver.promise.Promise} A promise that will be resolved with
        1249 * the result of the action.
        1250 */
        1251webdriver.promise.ControlFlow.prototype.timeout = function(
        1252 ms, opt_description) {
        1253 return this.execute(function() {
        1254 return webdriver.promise.delayed(ms);
        1255 }, opt_description);
        1256};
        1257
        1258
        1259/**
        1260 * Schedules a task that shall wait for a condition to hold. Each condition
        1261 * function may return any value, but it will always be evaluated as a boolean.
        1262 *
        1263 * <p>Condition functions may schedule sub-tasks with this instance, however,
        1264 * their execution time will be factored into whether a wait has timed out.
        1265 *
        1266 * <p>In the event a condition returns a Promise, the polling loop will wait for
        1267 * it to be resolved before evaluating whether the condition has been satisfied.
        1268 * The resolution time for a promise is factored into whether a wait has timed
        1269 * out.
        1270 *
        1271 * <p>If the condition function throws, or returns a rejected promise, the
        1272 * wait task will fail.
        1273 *
        1274 * @param {!Function} condition The condition function to poll.
        1275 * @param {number} timeout How long to wait, in milliseconds, for the condition
        1276 * to hold before timing out.
        1277 * @param {string=} opt_message An optional error message to include if the
        1278 * wait times out; defaults to the empty string.
        1279 * @return {!webdriver.promise.Promise} A promise that will be resolved when the
        1280 * condition has been satisified. The promise shall be rejected if the wait
        1281 * times out waiting for the condition.
        1282 */
        1283webdriver.promise.ControlFlow.prototype.wait = function(
        1284 condition, timeout, opt_message) {
        1285 var sleep = Math.min(timeout, 100);
        1286 var self = this;
        1287
        1288 return this.execute(function() {
        1289 var startTime = goog.now();
        1290 var waitResult = new webdriver.promise.Deferred();
        1291 var waitFrame = self.activeFrame_;
        1292 waitFrame.isWaiting = true;
        1293 pollCondition();
        1294 return waitResult.promise;
        1295
        1296 function pollCondition() {
        1297 self.runInNewFrame_(condition, function(value) {
        1298 var elapsed = goog.now() - startTime;
        1299 if (!!value) {
        1300 waitFrame.isWaiting = false;
        1301 waitResult.fulfill(value);
        1302 } else if (elapsed >= timeout) {
        1303 waitResult.reject(new Error((opt_message ? opt_message + '\n' : '') +
        1304 'Wait timed out after ' + elapsed + 'ms'));
        1305 } else {
        1306 self.timer.setTimeout(pollCondition, sleep);
        1307 }
        1308 }, waitResult.reject, true);
        1309 }
        1310 }, opt_message);
        1311};
        1312
        1313
        1314/**
        1315 * Schedules a task that will wait for another promise to resolve. The resolved
        1316 * promise's value will be returned as the task result.
        1317 * @param {!webdriver.promise.Promise} promise The promise to wait on.
        1318 * @return {!webdriver.promise.Promise} A promise that will resolve when the
        1319 * task has completed.
        1320 */
        1321webdriver.promise.ControlFlow.prototype.await = function(promise) {
        1322 return this.execute(function() {
        1323 return promise;
        1324 });
        1325};
        1326
        1327
        1328/**
        1329 * Schedules the interval for this instance's event loop, if necessary.
        1330 * @private
        1331 */
        1332webdriver.promise.ControlFlow.prototype.scheduleEventLoopStart_ = function() {
        1333 if (!this.eventLoopId_) {
        1334 this.eventLoopId_ = this.timer.setInterval(
        1335 goog.bind(this.runEventLoop_, this),
        1336 webdriver.promise.ControlFlow.EVENT_LOOP_FREQUENCY);
        1337 }
        1338};
        1339
        1340
        1341/**
        1342 * Cancels the event loop, if necessary.
        1343 * @private
        1344 */
        1345webdriver.promise.ControlFlow.prototype.cancelEventLoop_ = function() {
        1346 if (this.eventLoopId_) {
        1347 this.timer.clearInterval(this.eventLoopId_);
        1348 this.eventLoopId_ = null;
        1349 }
        1350};
        1351
        1352
        1353/**
        1354 * Executes the next task for the current frame. If the current frame has no
        1355 * more tasks, the frame's result will be resolved, returning control to the
        1356 * frame's creator. This will terminate the flow if the completed frame was at
        1357 * the top of the stack.
        1358 * @private
        1359 */
        1360webdriver.promise.ControlFlow.prototype.runEventLoop_ = function() {
        1361 // If we get here and there are pending promise rejections, then those
        1362 // promises are queued up to run as soon as this (JS) event loop terminates.
        1363 // Short-circuit our loop to give those promises a chance to run. Otherwise,
        1364 // we might start a new task only to have it fail because of one of these
        1365 // pending rejections.
        1366 if (this.pendingRejections_) {
        1367 return;
        1368 }
        1369
        1370 // If the flow aborts due to an unhandled exception after we've scheduled
        1371 // another turn of the execution loop, we can end up in here with no tasks
        1372 // left. This is OK, just quietly return.
        1373 if (!this.activeFrame_) {
        1374 this.commenceShutdown_();
        1375 return;
        1376 }
        1377
        1378 var task;
        1379 if (this.activeFrame_.getPendingTask() || !(task = this.getNextTask_())) {
        1380 // Either the current frame is blocked on a pending task, or we don't have
        1381 // a task to finish because we've completed a frame. When completing a
        1382 // frame, we must abort the event loop to allow the frame's promise's
        1383 // callbacks to execute.
        1384 return;
        1385 }
        1386
        1387 var activeFrame = this.activeFrame_;
        1388 activeFrame.setPendingTask(task);
        1389 var markTaskComplete = goog.bind(function() {
        1390 this.history_.push(/** @type {!webdriver.promise.Task_} */ (task));
        1391 activeFrame.setPendingTask(null);
        1392 }, this);
        1393
        1394 this.trimHistory_();
        1395 var self = this;
        1396 this.runInNewFrame_(task.execute, function(result) {
        1397 markTaskComplete();
        1398 task.fulfill(result);
        1399 }, function(error) {
        1400 markTaskComplete();
        1401
        1402 if (!webdriver.promise.isError_(error) &&
        1403 !webdriver.promise.isPromise(error)) {
        1404 error = Error(error);
        1405 }
        1406
        1407 task.reject(self.annotateError(/** @type {!Error} */ (error)));
        1408 }, true);
        1409};
        1410
        1411
        1412/**
        1413 * @return {webdriver.promise.Task_} The next task to execute, or
        1414 * {@code null} if a frame was resolved.
        1415 * @private
        1416 */
        1417webdriver.promise.ControlFlow.prototype.getNextTask_ = function() {
        1418 var firstChild = this.activeFrame_.getFirstChild();
        1419 if (!firstChild) {
        1420 if (!this.activeFrame_.isWaiting) {
        1421 this.resolveFrame_(this.activeFrame_);
        1422 }
        1423 return null;
        1424 }
        1425
        1426 if (firstChild instanceof webdriver.promise.Frame_) {
        1427 this.activeFrame_ = firstChild;
        1428 return this.getNextTask_();
        1429 }
        1430
        1431 firstChild.getParent().removeChild(firstChild);
        1432 return firstChild;
        1433};
        1434
        1435
        1436/**
        1437 * @param {!webdriver.promise.Frame_} frame The frame to resolve.
        1438 * @private
        1439 */
        1440webdriver.promise.ControlFlow.prototype.resolveFrame_ = function(frame) {
        1441 if (this.activeFrame_ === frame) {
        1442 // Frame parent is always another frame, but the compiler is not smart
        1443 // enough to recognize this.
        1444 this.activeFrame_ =
        1445 /** @type {webdriver.promise.Frame_} */ (frame.getParent());
        1446 }
        1447
        1448 if (frame.getParent()) {
        1449 frame.getParent().removeChild(frame);
        1450 }
        1451 this.trimHistory_();
        1452 frame.fulfill();
        1453
        1454 if (!this.activeFrame_) {
        1455 this.commenceShutdown_();
        1456 }
        1457};
        1458
        1459
        1460/**
        1461 * Aborts the current frame. The frame, and all of the tasks scheduled within it
        1462 * will be discarded. If this instance does not have an active frame, it will
        1463 * immediately terminate all execution.
        1464 * @param {*} error The reason the frame is being aborted; typically either
        1465 * an Error or string.
        1466 * @private
        1467 */
        1468webdriver.promise.ControlFlow.prototype.abortFrame_ = function(error) {
        1469 // Annotate the error value if it is Error-like.
        1470 if (webdriver.promise.isError_(error)) {
        1471 this.annotateError(/** @type {!Error} */ (error));
        1472 }
        1473 this.numAbortedFrames_++;
        1474
        1475 if (!this.activeFrame_) {
        1476 this.abortNow_(error);
        1477 return;
        1478 }
        1479
        1480 // Frame parent is always another frame, but the compiler is not smart
        1481 // enough to recognize this.
        1482 var parent = /** @type {webdriver.promise.Frame_} */ (
        1483 this.activeFrame_.getParent());
        1484 if (parent) {
        1485 parent.removeChild(this.activeFrame_);
        1486 }
        1487
        1488 var frame = this.activeFrame_;
        1489 this.activeFrame_ = parent;
        1490 frame.reject(error);
        1491};
        1492
        1493
        1494/**
        1495 * Executes a function in a new frame. If the function does not schedule any new
        1496 * tasks, the frame will be discarded and the function's result returned
        1497 * immediately. Otherwise, a promise will be returned. This promise will be
        1498 * resolved with the function's result once all of the tasks scheduled within
        1499 * the function have been completed. If the function's frame is aborted, the
        1500 * returned promise will be rejected.
        1501 *
        1502 * @param {!Function} fn The function to execute.
        1503 * @param {function(*)} callback The function to call with a successful result.
        1504 * @param {function(*)} errback The function to call if there is an error.
        1505 * @param {boolean=} opt_activate Whether the active frame should be updated to
        1506 * the newly created frame so tasks are treated as sub-tasks.
        1507 * @private
        1508 */
        1509webdriver.promise.ControlFlow.prototype.runInNewFrame_ = function(
        1510 fn, callback, errback, opt_activate) {
        1511 var newFrame = new webdriver.promise.Frame_(this),
        1512 self = this,
        1513 oldFrame = this.activeFrame_;
        1514
        1515 try {
        1516 if (!this.activeFrame_) {
        1517 this.activeFrame_ = newFrame;
        1518 } else {
        1519 this.activeFrame_.addChild(newFrame);
        1520 }
        1521
        1522 // Activate the new frame to force tasks to be treated as sub-tasks of
        1523 // the parent frame.
        1524 if (opt_activate) {
        1525 this.activeFrame_ = newFrame;
        1526 }
        1527
        1528 try {
        1529 this.schedulingFrame_ = newFrame;
        1530 webdriver.promise.pushFlow_(this);
        1531 var result = fn();
        1532 } finally {
        1533 webdriver.promise.popFlow_();
        1534 this.schedulingFrame_ = null;
        1535 }
        1536 newFrame.lockFrame();
        1537
        1538 // If there was nothing scheduled in the new frame we can discard the
        1539 // frame and return immediately.
        1540 if (!newFrame.children_.length) {
        1541 removeNewFrame();
        1542 webdriver.promise.asap(result, callback, errback);
        1543 return;
        1544 }
        1545
        1546 newFrame.then(function() {
        1547 webdriver.promise.asap(result, callback, errback);
        1548 }, function(e) {
        1549 if (result instanceof webdriver.promise.Promise && result.isPending()) {
        1550 result.cancel(e);
        1551 e = result;
        1552 }
        1553 errback(e);
        1554 });
        1555 } catch (ex) {
        1556 removeNewFrame(new webdriver.promise.CanceledTaskError_(ex));
        1557 errback(ex);
        1558 }
        1559
        1560 /**
        1561 * @param {webdriver.promise.CanceledTaskError_=} opt_err If provided, the
        1562 * error that triggered the removal of this frame.
        1563 */
        1564 function removeNewFrame(opt_err) {
        1565 var parent = newFrame.getParent();
        1566 if (parent) {
        1567 parent.removeChild(newFrame);
        1568 }
        1569
        1570 if (opt_err) {
        1571 newFrame.cancelRemainingTasks(opt_err);
        1572 }
        1573 self.activeFrame_ = oldFrame;
        1574 }
        1575};
        1576
        1577
        1578/**
        1579 * Commences the shutdown sequence for this instance. After one turn of the
        1580 * event loop, this object will emit the
        1581 * {@link webdriver.promise.ControlFlow.EventType.IDLE} event to signal
        1582 * listeners that it has completed. During this wait, if another task is
        1583 * scheduled, the shutdown will be aborted.
        1584 * @private
        1585 */
        1586webdriver.promise.ControlFlow.prototype.commenceShutdown_ = function() {
        1587 if (!this.shutdownId_) {
        1588 // Go ahead and stop the event loop now. If we're in here, then there are
        1589 // no more frames with tasks to execute. If we waited to cancel the event
        1590 // loop in our timeout below, the event loop could trigger *before* the
        1591 // timeout, generating an error from there being no frames.
        1592 // If #execute is called before the timeout below fires, it will cancel
        1593 // the timeout and restart the event loop.
        1594 this.cancelEventLoop_();
        1595
        1596 var self = this;
        1597 self.shutdownId_ = self.timer.setTimeout(function() {
        1598 self.shutdownId_ = null;
        1599 self.emit(webdriver.promise.ControlFlow.EventType.IDLE);
        1600 }, 0);
        1601 }
        1602};
        1603
        1604
        1605/**
        1606 * Cancels the shutdown sequence if it is currently scheduled.
        1607 * @private
        1608 */
        1609webdriver.promise.ControlFlow.prototype.cancelShutdown_ = function() {
        1610 if (this.shutdownId_) {
        1611 this.timer.clearTimeout(this.shutdownId_);
        1612 this.shutdownId_ = null;
        1613 }
        1614};
        1615
        1616
        1617/**
        1618 * Aborts this flow, abandoning all remaining tasks. If there are
        1619 * listeners registered, an {@code UNCAUGHT_EXCEPTION} will be emitted with the
        1620 * offending {@code error}, otherwise, the {@code error} will be rethrown to the
        1621 * global error handler.
        1622 * @param {*} error Object describing the error that caused the flow to
        1623 * abort; usually either an Error or string value.
        1624 * @private
        1625 */
        1626webdriver.promise.ControlFlow.prototype.abortNow_ = function(error) {
        1627 this.activeFrame_ = null;
        1628 this.cancelShutdown_();
        1629 this.cancelEventLoop_();
        1630
        1631 var listeners = this.listeners(
        1632 webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
        1633 if (!listeners.length) {
        1634 this.timer.setTimeout(function() {
        1635 throw error;
        1636 }, 0);
        1637 } else {
        1638 this.emit(webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
        1639 error);
        1640 }
        1641};
        1642
        1643
        1644
        1645/**
        1646 * A single node in an {@link webdriver.promise.ControlFlow}'s task tree.
        1647 * @param {!webdriver.promise.ControlFlow} flow The flow this instance belongs
        1648 * to.
        1649 * @constructor
        1650 * @extends {webdriver.promise.Deferred}
        1651 * @private
        1652 */
        1653webdriver.promise.Node_ = function(flow) {
        1654 webdriver.promise.Deferred.call(this, null, flow);
        1655};
        1656goog.inherits(webdriver.promise.Node_, webdriver.promise.Deferred);
        1657
        1658
        1659/**
        1660 * This node's parent.
        1661 * @private {webdriver.promise.Node_}
        1662 */
        1663webdriver.promise.Node_.prototype.parent_ = null;
        1664
        1665
        1666/** @return {webdriver.promise.Node_} This node's parent. */
        1667webdriver.promise.Node_.prototype.getParent = function() {
        1668 return this.parent_;
        1669};
        1670
        1671
        1672/**
        1673 * @param {webdriver.promise.Node_} parent This node's new parent.
        1674 */
        1675webdriver.promise.Node_.prototype.setParent = function(parent) {
        1676 this.parent_ = parent;
        1677};
        1678
        1679
        1680/**
        1681 * @return {!webdriver.promise.Node_} The root of this node's tree.
        1682 */
        1683webdriver.promise.Node_.prototype.getRoot = function() {
        1684 var root = this;
        1685 while (root.parent_) {
        1686 root = root.parent_;
        1687 }
        1688 return root;
        1689};
        1690
        1691
        1692
        1693/**
        1694 * An execution frame within a {@link webdriver.promise.ControlFlow}. Each
        1695 * frame represents the execution context for either a
        1696 * {@link webdriver.promise.Task_} or a callback on a
        1697 * {@link webdriver.promise.Deferred}.
        1698 *
        1699 * <p>Each frame may contain sub-frames. If child N is a sub-frame, then the
        1700 * items queued within it are given priority over child N+1.
        1701 *
        1702 * @param {!webdriver.promise.ControlFlow} flow The flow this instance belongs
        1703 * to.
        1704 * @constructor
        1705 * @extends {webdriver.promise.Node_}
        1706 * @private
        1707 */
        1708webdriver.promise.Frame_ = function(flow) {
        1709 webdriver.promise.Node_.call(this, flow);
        1710
        1711 var reject = goog.bind(this.reject, this);
        1712 var cancelRemainingTasks = goog.bind(this.cancelRemainingTasks, this);
        1713
        1714 /** @override */
        1715 this.reject = function(e) {
        1716 cancelRemainingTasks(new webdriver.promise.CanceledTaskError_(e));
        1717 reject(e);
        1718 };
        1719
        1720 /**
        1721 * @private {!Array.<!(webdriver.promise.Frame_|webdriver.promise.Task_)>}
        1722 */
        1723 this.children_ = [];
        1724};
        1725goog.inherits(webdriver.promise.Frame_, webdriver.promise.Node_);
        1726
        1727
        1728/**
        1729 * The task currently being executed within this frame.
        1730 * @private {webdriver.promise.Task_}
        1731 */
        1732webdriver.promise.Frame_.prototype.pendingTask_ = null;
        1733
        1734
        1735/**
        1736 * Whether this frame is active. A frame is considered active once one of its
        1737 * descendants has been removed for execution.
        1738 *
        1739 * Adding a sub-frame as a child to an active frame is an indication that
        1740 * a callback to a {@link webdriver.promise.Deferred} is being invoked and any
        1741 * tasks scheduled within it should have priority over previously scheduled
        1742 * tasks:
        1743 * <code><pre>
        1744 * var flow = webdriver.promise.controlFlow();
        1745 * flow.execute('start here', goog.nullFunction).then(function() {
        1746 * flow.execute('this should execute 2nd', goog.nullFunction);
        1747 * });
        1748 * flow.execute('this should execute last', goog.nullFunction);
        1749 * </pre></code>
        1750 *
        1751 * @private {boolean}
        1752 */
        1753webdriver.promise.Frame_.prototype.isActive_ = false;
        1754
        1755
        1756/**
        1757 * Whether this frame is currently locked. A locked frame represents a callback
        1758 * or task function which has run to completion and scheduled all of its tasks.
        1759 *
        1760 * <p>Once a frame becomes {@link #isActive_ active}, any new frames which are
        1761 * added represent callbacks on a {@link webdriver.promise.Deferred}, whose
        1762 * tasks must be given priority over previously scheduled tasks.
        1763 *
        1764 * @private {boolean}
        1765 */
        1766webdriver.promise.Frame_.prototype.isLocked_ = false;
        1767
        1768
        1769/**
        1770 * A reference to the last node inserted in this frame.
        1771 * @private {webdriver.promise.Node_}
        1772 */
        1773webdriver.promise.Frame_.prototype.lastInsertedChild_ = null;
        1774
        1775
        1776/**
        1777 * Marks all of the tasks that are descendants of this frame in the execution
        1778 * tree as cancelled. This is necessary for callbacks scheduled asynchronous.
        1779 * For example:
        1780 *
        1781 * var someResult;
        1782 * webdriver.promise.createFlow(function(flow) {
        1783 * someResult = flow.execute(function() {});
        1784 * throw Error();
        1785 * }).addErrback(function(err) {
        1786 * console.log('flow failed: ' + err);
        1787 * someResult.then(function() {
        1788 * console.log('task succeeded!');
        1789 * }, function(err) {
        1790 * console.log('task failed! ' + err);
        1791 * });
        1792 * });
        1793 * // flow failed: Error: boom
        1794 * // task failed! CanceledTaskError: Task discarded due to a previous
        1795 * // task failure: Error: boom
        1796 *
        1797 * @param {!webdriver.promise.CanceledTaskError_} error The cancellation
        1798 * error.
        1799 */
        1800webdriver.promise.Frame_.prototype.cancelRemainingTasks = function(error) {
        1801 goog.array.forEach(this.children_, function(child) {
        1802 if (child instanceof webdriver.promise.Frame_) {
        1803 child.cancelRemainingTasks(error);
        1804 } else {
        1805 // None of the previously registered listeners should be notified that
        1806 // the task is being canceled, however, we need at least one errback
        1807 // to prevent the cancellation from bubbling up.
        1808 child.removeAll();
        1809 child.thenCatch(goog.nullFunction);
        1810 child.cancel(error);
        1811 }
        1812 });
        1813};
        1814
        1815
        1816/**
        1817 * @return {webdriver.promise.Task_} The task currently executing
        1818 * within this frame, if any.
        1819 */
        1820webdriver.promise.Frame_.prototype.getPendingTask = function() {
        1821 return this.pendingTask_;
        1822};
        1823
        1824
        1825/**
        1826 * @param {webdriver.promise.Task_} task The task currently
        1827 * executing within this frame, if any.
        1828 */
        1829webdriver.promise.Frame_.prototype.setPendingTask = function(task) {
        1830 this.pendingTask_ = task;
        1831};
        1832
        1833
        1834/** Locks this frame. */
        1835webdriver.promise.Frame_.prototype.lockFrame = function() {
        1836 this.isLocked_ = true;
        1837};
        1838
        1839
        1840/**
        1841 * Adds a new node to this frame.
        1842 * @param {!(webdriver.promise.Frame_|webdriver.promise.Task_)} node
        1843 * The node to insert.
        1844 */
        1845webdriver.promise.Frame_.prototype.addChild = function(node) {
        1846 if (this.lastInsertedChild_ &&
        1847 this.lastInsertedChild_ instanceof webdriver.promise.Frame_ &&
        1848 !this.lastInsertedChild_.isLocked_) {
        1849 this.lastInsertedChild_.addChild(node);
        1850 return;
        1851 }
        1852
        1853 node.setParent(this);
        1854
        1855 if (this.isActive_ && node instanceof webdriver.promise.Frame_) {
        1856 var index = 0;
        1857 if (this.lastInsertedChild_ instanceof
        1858 webdriver.promise.Frame_) {
        1859 index = goog.array.indexOf(this.children_, this.lastInsertedChild_) + 1;
        1860 }
        1861 goog.array.insertAt(this.children_, node, index);
        1862 this.lastInsertedChild_ = node;
        1863 return;
        1864 }
        1865
        1866 this.lastInsertedChild_ = node;
        1867 this.children_.push(node);
        1868};
        1869
        1870
        1871/**
        1872 * @return {(webdriver.promise.Frame_|webdriver.promise.Task_)} This frame's
        1873 * fist child.
        1874 */
        1875webdriver.promise.Frame_.prototype.getFirstChild = function() {
        1876 this.isActive_ = true;
        1877 this.lastInsertedChild_ = null;
        1878 return this.children_[0];
        1879};
        1880
        1881
        1882/**
        1883 * Removes a child from this frame.
        1884 * @param {!(webdriver.promise.Frame_|webdriver.promise.Task_)} child
        1885 * The child to remove.
        1886 */
        1887webdriver.promise.Frame_.prototype.removeChild = function(child) {
        1888 var index = goog.array.indexOf(this.children_, child);
        1889 child.setParent(null);
        1890 goog.array.removeAt(this.children_, index);
        1891 if (this.lastInsertedChild_ === child) {
        1892 this.lastInsertedChild_ = null;
        1893 }
        1894};
        1895
        1896
        1897/** @override */
        1898webdriver.promise.Frame_.prototype.toString = function() {
        1899 return '[' + goog.array.map(this.children_, function(child) {
        1900 return child.toString();
        1901 }).join(', ') + ']';
        1902};
        1903
        1904
        1905
        1906/**
        1907 * A task to be executed by a {@link webdriver.promise.ControlFlow}.
        1908 *
        1909 * @param {!webdriver.promise.ControlFlow} flow The flow this instances belongs
        1910 * to.
        1911 * @param {!Function} fn The function to call when the task executes. If it
        1912 * returns a {@code webdriver.promise.Promise}, the flow will wait
        1913 * for it to be resolved before starting the next task.
        1914 * @param {string} description A description of the task for debugging.
        1915 * @param {!webdriver.stacktrace.Snapshot} snapshot A snapshot of the stack
        1916 * when this task was scheduled.
        1917 * @constructor
        1918 * @extends {webdriver.promise.Node_}
        1919 * @private
        1920 */
        1921webdriver.promise.Task_ = function(flow, fn, description, snapshot) {
        1922 webdriver.promise.Node_.call(this, flow);
        1923
        1924 /**
        1925 * Executes this task.
        1926 * @type {!Function}
        1927 */
        1928 this.execute = fn;
        1929
        1930 /** @private {string} */
        1931 this.description_ = description;
        1932
        1933 /** @private {!webdriver.stacktrace.Snapshot} */
        1934 this.snapshot_ = snapshot;
        1935};
        1936goog.inherits(webdriver.promise.Task_, webdriver.promise.Node_);
        1937
        1938
        1939/** @return {string} This task's description. */
        1940webdriver.promise.Task_.prototype.getDescription = function() {
        1941 return this.description_;
        1942};
        1943
        1944
        1945/** @override */
        1946webdriver.promise.Task_.prototype.toString = function() {
        1947 var stack = this.snapshot_.getStacktrace();
        1948 var ret = this.description_;
        1949 if (stack.length) {
        1950 if (this.description_) {
        1951 ret += '\n';
        1952 }
        1953 ret += stack.join('\n');
        1954 }
        1955 return ret;
        1956};
        1957
        1958
        1959
        1960/**
        1961 * Special error used to signal when a task is canceled because a previous
        1962 * task in the same frame failed.
        1963 * @param {*} err The error that caused the task cancellation.
        1964 * @constructor
        1965 * @extends {goog.debug.Error}
        1966 * @private
        1967 */
        1968webdriver.promise.CanceledTaskError_ = function(err) {
        1969 goog.base(this, 'Task discarded due to a previous task failure: ' + err);
        1970};
        1971goog.inherits(webdriver.promise.CanceledTaskError_, goog.debug.Error);
        1972
        1973
        1974/** @override */
        1975webdriver.promise.CanceledTaskError_.prototype.name = 'CanceledTaskError';
        1976
        1977
        1978
        1979/**
        1980 * The default flow to use if no others are active.
        1981 * @private {!webdriver.promise.ControlFlow}
        1982 */
        1983webdriver.promise.defaultFlow_ = new webdriver.promise.ControlFlow();
        1984
        1985
        1986/**
        1987 * A stack of active control flows, with the top of the stack used to schedule
        1988 * commands. When there are multiple flows on the stack, the flow at index N
        1989 * represents a callback triggered within a task owned by the flow at index
        1990 * N-1.
        1991 * @private {!Array.<!webdriver.promise.ControlFlow>}
        1992 */
        1993webdriver.promise.activeFlows_ = [];
        1994
        1995
        1996/**
        1997 * Changes the default flow to use when no others are active.
        1998 * @param {!webdriver.promise.ControlFlow} flow The new default flow.
        1999 * @throws {Error} If the default flow is not currently active.
        2000 */
        2001webdriver.promise.setDefaultFlow = function(flow) {
        2002 if (webdriver.promise.activeFlows_.length) {
        2003 throw Error('You may only change the default flow while it is active');
        2004 }
        2005 webdriver.promise.defaultFlow_ = flow;
        2006};
        2007
        2008
        2009/**
        2010 * @return {!webdriver.promise.ControlFlow} The currently active control flow.
        2011 */
        2012webdriver.promise.controlFlow = function() {
        2013 return /** @type {!webdriver.promise.ControlFlow} */ (
        2014 goog.array.peek(webdriver.promise.activeFlows_) ||
        2015 webdriver.promise.defaultFlow_);
        2016};
        2017
        2018
        2019/**
        2020 * @param {!webdriver.promise.ControlFlow} flow The new flow.
        2021 * @private
        2022 */
        2023webdriver.promise.pushFlow_ = function(flow) {
        2024 webdriver.promise.activeFlows_.push(flow);
        2025};
        2026
        2027
        2028/** @private */
        2029webdriver.promise.popFlow_ = function() {
        2030 webdriver.promise.activeFlows_.pop();
        2031};
        2032
        2033
        2034/**
        2035 * Creates a new control flow. The provided callback will be invoked as the
        2036 * first task within the new flow, with the flow as its sole argument. Returns
        2037 * a promise that resolves to the callback result.
        2038 * @param {function(!webdriver.promise.ControlFlow)} callback The entry point
        2039 * to the newly created flow.
        2040 * @return {!webdriver.promise.Promise} A promise that resolves to the callback
        2041 * result.
        2042 */
        2043webdriver.promise.createFlow = function(callback) {
        2044 var flow = new webdriver.promise.ControlFlow(
        2045 webdriver.promise.defaultFlow_.timer);
        2046 return flow.execute(function() {
        2047 return callback(flow);
        2048 });
        2049};
        \ No newline at end of file +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');
        54goog.provide('webdriver.promise.Thenable');
        55
        56goog.require('goog.array');
        57goog.require('goog.debug.Error');
        58goog.require('goog.object');
        59goog.require('webdriver.EventEmitter');
        60goog.require('webdriver.stacktrace.Snapshot');
        61
        62
        63
        64/**
        65 * Thenable is a promise-like object with a {@code then} method which may be
        66 * used to schedule callbacks on a promised value.
        67 *
        68 * @interface
        69 * @template T
        70 */
        71webdriver.promise.Thenable = function() {};
        72
        73
        74/**
        75 * Cancels the computation of this promise's value, rejecting the promise in the
        76 * process. This method is a no-op if the promise has alreayd been resolved.
        77 *
        78 * @param {*=} opt_reason The reason this promise is being cancelled. If not an
        79 * {@code Error}, one will be created using the value's string
        80 * representation.
        81 */
        82webdriver.promise.Thenable.prototype.cancel = function(opt_reason) {};
        83
        84
        85/** @return {boolean} Whether this promise's value is still being computed. */
        86webdriver.promise.Thenable.prototype.isPending = function() {};
        87
        88
        89/**
        90 * Registers listeners for when this instance is resolved.
        91 *
        92 * @param {?(function(T): (R|webdriver.promise.Promise.<R>))=} opt_callback The
        93 * function to call if this promise is successfully resolved. The function
        94 * should expect a single argument: the promise's resolved value.
        95 * @param {?(function(*): (R|webdriver.promise.Promise.<R>))=} opt_errback The
        96 * function to call if this promise is rejected. The function should expect
        97 * a single argument: the rejection reason.
        98 * @return {!webdriver.promise.Promise.<R>} A new promise which will be
        99 * resolved with the result of the invoked callback.
        100 * @template R
        101 */
        102webdriver.promise.Thenable.prototype.then = function(
        103 opt_callback, opt_errback) {};
        104
        105
        106/**
        107 * Registers a listener for when this promise is rejected. This is synonymous
        108 * with the {@code catch} clause in a synchronous API:
        109 * <pre><code>
        110 * // Synchronous API:
        111 * try {
        112 * doSynchronousWork();
        113 * } catch (ex) {
        114 * console.error(ex);
        115 * }
        116 *
        117 * // Asynchronous promise API:
        118 * doAsynchronousWork().thenCatch(function(ex) {
        119 * console.error(ex);
        120 * });
        121 * </code></pre>
        122 *
        123 * @param {function(*): (R|webdriver.promise.Promise.<R>)} errback The function
        124 * to call if this promise is rejected. The function should expect a single
        125 * argument: the rejection reason.
        126 * @return {!webdriver.promise.Promise.<R>} A new promise which will be
        127 * resolved with the result of the invoked callback.
        128 * @template R
        129 */
        130webdriver.promise.Thenable.prototype.thenCatch = function(errback) {};
        131
        132
        133/**
        134 * Registers a listener to invoke when this promise is resolved, regardless
        135 * of whether the promise's value was successfully computed. This function
        136 * is synonymous with the {@code finally} clause in a synchronous API:
        137 * <pre><code>
        138 * // Synchronous API:
        139 * try {
        140 * doSynchronousWork();
        141 * } finally {
        142 * cleanUp();
        143 * }
        144 *
        145 * // Asynchronous promise API:
        146 * doAsynchronousWork().thenFinally(cleanUp);
        147 * </code></pre>
        148 *
        149 * <b>Note:</b> similar to the {@code finally} clause, if the registered
        150 * callback returns a rejected promise or throws an error, it will silently
        151 * replace the rejection error (if any) from this promise:
        152 * <pre><code>
        153 * try {
        154 * throw Error('one');
        155 * } finally {
        156 * throw Error('two'); // Hides Error: one
        157 * }
        158 *
        159 * webdriver.promise.rejected(Error('one'))
        160 * .thenFinally(function() {
        161 * throw Error('two'); // Hides Error: one
        162 * });
        163 * </code></pre>
        164 *
        165 *
        166 * @param {function(): (R|webdriver.promise.Promise.<R>)} callback The function
        167 * to call when this promise is resolved.
        168 * @return {!webdriver.promise.Promise.<R>} A promise that will be fulfilled
        169 * with the callback result.
        170 * @template R
        171 */
        172webdriver.promise.Thenable.prototype.thenFinally = function(callback) {};
        173
        174
        175/**
        176 * Property used to flag constructor's as implementing the Thenable interface
        177 * for runtime type checking.
        178 * @private {string}
        179 * @const
        180 */
        181webdriver.promise.Thenable.IMPLEMENTED_BY_PROP_ = '$webdriver_Thenable';
        182
        183
        184/**
        185 * Adds a property to a class prototype to allow runtime checks of whether
        186 * instances of that class implement the Thenable interface. This function will
        187 * also ensure the prototype's {@code then} function is exported from compiled
        188 * code.
        189 * @param {function(new: webdriver.promise.Thenable, ...[?])} ctor The
        190 * constructor whose prototype to modify.
        191 */
        192webdriver.promise.Thenable.addImplementation = function(ctor) {
        193 // Based on goog.promise.Thenable.isImplementation.
        194 ctor.prototype['then'] = ctor.prototype.then;
        195 try {
        196 // Old IE7 does not support defineProperty; IE8 only supports it for
        197 // DOM elements.
        198 Object.defineProperty(
        199 ctor.prototype,
        200 webdriver.promise.Thenable.IMPLEMENTED_BY_PROP_,
        201 {'value': true, 'enumerable': false});
        202 } catch (ex) {
        203 ctor.prototype[webdriver.promise.Thenable.IMPLEMENTED_BY_PROP_] = true;
        204 }
        205};
        206
        207
        208/**
        209 * Checks if an object has been tagged for implementing the Thenable interface
        210 * as defined by {@link webdriver.promise.Thenable.addImplementation}.
        211 * @param {*} object The object to test.
        212 * @return {boolean} Whether the object is an implementation of the Thenable
        213 * interface.
        214 */
        215webdriver.promise.Thenable.isImplementation = function(object) {
        216 // Based on goog.promise.Thenable.isImplementation.
        217 if (!object) {
        218 return false;
        219 }
        220 try {
        221 return !!object[webdriver.promise.Thenable.IMPLEMENTED_BY_PROP_];
        222 } catch (e) {
        223 return false; // Property access seems to be forbidden.
        224 }
        225};
        226
        227
        228
        229/**
        230 * Represents the eventual value of a completed operation. Each promise may be
        231 * in one of three states: pending, resolved, or rejected. Each promise starts
        232 * in the pending state and may make a single transition to either a
        233 * fulfilled or rejected state, at which point the promise is considered
        234 * resolved.
        235 *
        236 * @constructor
        237 * @implements {webdriver.promise.Thenable.<T>}
        238 * @template T
        239 * @see http://promises-aplus.github.io/promises-spec/
        240 */
        241webdriver.promise.Promise = function() {};
        242webdriver.promise.Thenable.addImplementation(webdriver.promise.Promise);
        243
        244
        245/** @override */
        246webdriver.promise.Promise.prototype.cancel = function(reason) {
        247 throw new TypeError('Unimplemented function: "cancel"');
        248};
        249
        250
        251/** @override */
        252webdriver.promise.Promise.prototype.isPending = function() {
        253 throw new TypeError('Unimplemented function: "isPending"');
        254};
        255
        256
        257/** @override */
        258webdriver.promise.Promise.prototype.then = function(
        259 opt_callback, opt_errback) {
        260 throw new TypeError('Unimplemented function: "then"');
        261};
        262
        263
        264/** @override */
        265webdriver.promise.Promise.prototype.thenCatch = function(errback) {
        266 return this.then(null, errback);
        267};
        268
        269
        270/** @override */
        271webdriver.promise.Promise.prototype.thenFinally = function(callback) {
        272 return this.then(callback, function(err) {
        273 var value = callback();
        274 if (webdriver.promise.isPromise(value)) {
        275 return value.then(function() {
        276 throw err;
        277 });
        278 }
        279 throw err;
        280 });
        281};
        282
        283
        284
        285/**
        286 * Represents a value that will be resolved at some point in the future. This
        287 * class represents the protected "producer" half of a Promise - each Deferred
        288 * has a {@code promise} property that may be returned to consumers for
        289 * registering callbacks, reserving the ability to resolve the deferred to the
        290 * producer.
        291 *
        292 * <p>If this Deferred is rejected and there are no listeners registered before
        293 * the next turn of the event loop, the rejection will be passed to the
        294 * {@link webdriver.promise.ControlFlow} as an unhandled failure.
        295 *
        296 * <p>If this Deferred is cancelled, the cancellation reason will be forward to
        297 * the Deferred's canceller function (if provided). The canceller may return a
        298 * truth-y value to override the reason provided for rejection.
        299 *
        300 * @param {Function=} opt_canceller Function to call when cancelling the
        301 * computation of this instance's value.
        302 * @param {webdriver.promise.ControlFlow=} opt_flow The control flow
        303 * this instance was created under. This should only be provided during
        304 * unit tests.
        305 * @constructor
        306 * @extends {webdriver.promise.Promise.<T>}
        307 * @template T
        308 */
        309webdriver.promise.Deferred = function(opt_canceller, opt_flow) {
        310 /* NOTE: This class's implementation diverges from the prototypical style
        311 * used in the rest of the atoms library. This was done intentionally to
        312 * protect the internal Deferred state from consumers, as outlined by
        313 * http://wiki.commonjs.org/wiki/Promises
        314 */
        315 goog.base(this);
        316
        317 var flow = opt_flow || webdriver.promise.controlFlow();
        318
        319 /**
        320 * The listeners registered with this Deferred. Each element in the list will
        321 * be a 3-tuple of the callback function, errback function, and the
        322 * corresponding deferred object.
        323 * @type {!Array.<!webdriver.promise.Deferred.Listener_>}
        324 */
        325 var listeners = [];
        326
        327 /**
        328 * Whether this Deferred's resolution was ever handled by a listener.
        329 * If the Deferred is rejected and its value is not handled by a listener
        330 * before the next turn of the event loop, the error will be passed to the
        331 * global error handler.
        332 * @type {boolean}
        333 */
        334 var handled = false;
        335
        336 /**
        337 * Key for the timeout used to delay reproting an unhandled rejection to the
        338 * parent {@link webdriver.promise.ControlFlow}.
        339 * @type {?number}
        340 */
        341 var pendingRejectionKey = null;
        342
        343 /**
        344 * This Deferred's current state.
        345 * @type {!webdriver.promise.Deferred.State_}
        346 */
        347 var state = webdriver.promise.Deferred.State_.PENDING;
        348
        349 /**
        350 * This Deferred's resolved value; set when the state transitions from
        351 * {@code webdriver.promise.Deferred.State_.PENDING}.
        352 * @type {*}
        353 */
        354 var value;
        355
        356 /** @return {boolean} Whether this promise's value is still pending. */
        357 function isPending() {
        358 return state == webdriver.promise.Deferred.State_.PENDING;
        359 }
        360
        361 /**
        362 * Removes all of the listeners previously registered on this deferred.
        363 * @throws {Error} If this deferred has already been resolved.
        364 */
        365 function removeAll() {
        366 listeners = [];
        367 }
        368
        369 /**
        370 * Resolves this deferred. If the new value is a promise, this function will
        371 * wait for it to be resolved before notifying the registered listeners.
        372 * @param {!webdriver.promise.Deferred.State_} newState The deferred's new
        373 * state.
        374 * @param {*} newValue The deferred's new value.
        375 */
        376 function resolve(newState, newValue) {
        377 if (webdriver.promise.Deferred.State_.PENDING !== state) {
        378 return;
        379 }
        380
        381 if (newValue === self) {
        382 // See promise a+, 2.3.1
        383 // http://promises-aplus.github.io/promises-spec/#point-48
        384 throw TypeError('A promise may not resolve to itself');
        385 }
        386
        387 state = webdriver.promise.Deferred.State_.BLOCKED;
        388
        389 if (webdriver.promise.isPromise(newValue)) {
        390 var onFulfill = goog.partial(notifyAll, newState);
        391 var onReject = goog.partial(
        392 notifyAll, webdriver.promise.Deferred.State_.REJECTED);
        393 if (newValue instanceof webdriver.promise.Deferred) {
        394 newValue.then(onFulfill, onReject);
        395 } else {
        396 webdriver.promise.asap(newValue, onFulfill, onReject);
        397 }
        398
        399 } else {
        400 notifyAll(newState, newValue);
        401 }
        402 }
        403
        404 /**
        405 * Notifies all of the listeners registered with this Deferred that its state
        406 * has changed.
        407 * @param {!webdriver.promise.Deferred.State_} newState The deferred's new
        408 * state.
        409 * @param {*} newValue The deferred's new value.
        410 */
        411 function notifyAll(newState, newValue) {
        412 if (newState === webdriver.promise.Deferred.State_.REJECTED &&
        413 // We cannot check instanceof Error since the object may have been
        414 // created in a different JS context.
        415 goog.isObject(newValue) && goog.isString(newValue.message)) {
        416 newValue = flow.annotateError(/** @type {!Error} */(newValue));
        417 }
        418
        419 state = newState;
        420 value = newValue;
        421 while (listeners.length) {
        422 notify(listeners.shift());
        423 }
        424
        425 if (!handled && state == webdriver.promise.Deferred.State_.REJECTED) {
        426 flow.pendingRejections_ += 1;
        427 pendingRejectionKey = flow.timer.setTimeout(function() {
        428 pendingRejectionKey = null;
        429 flow.pendingRejections_ -= 1;
        430 flow.abortFrame_(value);
        431 }, 0);
        432 }
        433 }
        434
        435 /**
        436 * Notifies a single listener of this Deferred's change in state.
        437 * @param {!webdriver.promise.Deferred.Listener_} listener The listener to
        438 * notify.
        439 */
        440 function notify(listener) {
        441 var func = state == webdriver.promise.Deferred.State_.RESOLVED ?
        442 listener.callback : listener.errback;
        443 if (func) {
        444 flow.runInNewFrame_(goog.partial(func, value),
        445 listener.fulfill, listener.reject);
        446 } else if (state == webdriver.promise.Deferred.State_.REJECTED) {
        447 listener.reject(value);
        448 } else {
        449 listener.fulfill(value);
        450 }
        451 }
        452
        453 /**
        454 * The consumer promise for this instance. Provides protected access to the
        455 * callback registering functions.
        456 * @type {!webdriver.promise.Promise.<T>}
        457 */
        458 var promise = new webdriver.promise.Promise();
        459
        460 /**
        461 * Registers a callback on this Deferred.
        462 *
        463 * @param {?(function(T): (R|webdriver.promise.Promise.<R>))=} opt_callback .
        464 * @param {?(function(*): (R|webdriver.promise.Promise.<R>))=} opt_errback .
        465 * @return {!webdriver.promise.Promise.<R>} A new promise representing the
        466 * result of the callback.
        467 * @template R
        468 * @see webdriver.promise.Promise#then
        469 */
        470 function then(opt_callback, opt_errback) {
        471 // Avoid unnecessary allocations if we weren't given any callback functions.
        472 if (!opt_callback && !opt_errback) {
        473 return promise;
        474 }
        475
        476 // The moment a listener is registered, we consider this deferred to be
        477 // handled; the callback must handle any rejection errors.
        478 handled = true;
        479 if (pendingRejectionKey !== null) {
        480 flow.pendingRejections_ -= 1;
        481 flow.timer.clearTimeout(pendingRejectionKey);
        482 pendingRejectionKey = null;
        483 }
        484
        485 var deferred = new webdriver.promise.Deferred(cancel, flow);
        486 var listener = {
        487 callback: opt_callback,
        488 errback: opt_errback,
        489 fulfill: deferred.fulfill,
        490 reject: deferred.reject
        491 };
        492
        493 if (state == webdriver.promise.Deferred.State_.PENDING ||
        494 state == webdriver.promise.Deferred.State_.BLOCKED) {
        495 listeners.push(listener);
        496 } else {
        497 notify(listener);
        498 }
        499
        500 return deferred.promise;
        501 }
        502
        503 var self = this;
        504
        505 /**
        506 * Resolves this promise with the given value. If the value is itself a
        507 * promise and not a reference to this deferred, this instance will wait for
        508 * it before resolving.
        509 * @param {T=} opt_value The fulfilled value.
        510 */
        511 function fulfill(opt_value) {
        512 resolve(webdriver.promise.Deferred.State_.RESOLVED, opt_value);
        513 }
        514
        515 /**
        516 * Rejects this promise. If the error is itself a promise, this instance will
        517 * be chained to it and be rejected with the error's resolved value.
        518 * @param {*=} opt_error The rejection reason, typically either a
        519 * {@code Error} or a {@code string}.
        520 */
        521 function reject(opt_error) {
        522 resolve(webdriver.promise.Deferred.State_.REJECTED, opt_error);
        523 }
        524
        525 /**
        526 * Attempts to cancel the computation of this instance's value. This attempt
        527 * will silently fail if this instance has already resolved.
        528 * @param {*=} opt_reason The reason for cancelling this promise.
        529 */
        530 function cancel(opt_reason) {
        531 if (!isPending()) {
        532 return;
        533 }
        534
        535 if (opt_canceller) {
        536 opt_reason = opt_canceller(opt_reason) || opt_reason;
        537 }
        538
        539 reject(opt_reason);
        540 }
        541
        542 this.promise = promise;
        543 this.promise.then = this.then = then;
        544 this.promise.cancel = this.cancel = cancel;
        545 this.promise.isPending = this.isPending = isPending;
        546 this.fulfill = fulfill;
        547 this.reject = this.errback = reject;
        548
        549 // Only expose this function to our internal classes.
        550 // TODO: find a cleaner way of handling this.
        551 if (this instanceof webdriver.promise.Task_) {
        552 this.removeAll = removeAll;
        553 }
        554
        555 // Export symbols necessary for the contract on this object to work in
        556 // compiled mode.
        557 goog.exportProperty(this, 'then', this.then);
        558 goog.exportProperty(this, 'cancel', cancel);
        559 goog.exportProperty(this, 'fulfill', fulfill);
        560 goog.exportProperty(this, 'reject', reject);
        561 goog.exportProperty(this, 'isPending', isPending);
        562 goog.exportProperty(this, 'promise', this.promise);
        563 goog.exportProperty(this.promise, 'then', this.then);
        564 goog.exportProperty(this.promise, 'cancel', cancel);
        565 goog.exportProperty(this.promise, 'isPending', isPending);
        566};
        567goog.inherits(webdriver.promise.Deferred, webdriver.promise.Promise);
        568
        569
        570/**
        571 * Type definition for a listener registered on a Deferred object.
        572 * @typedef {{callback:(Function|undefined),
        573 * errback:(Function|undefined),
        574 * fulfill: function(*), reject: function(*)}}
        575 * @private
        576 */
        577webdriver.promise.Deferred.Listener_;
        578
        579
        580/**
        581 * The three states a {@link webdriver.promise.Deferred} object may be in.
        582 * @enum {number}
        583 * @private
        584 */
        585webdriver.promise.Deferred.State_ = {
        586 REJECTED: -1,
        587 PENDING: 0,
        588 BLOCKED: 1,
        589 RESOLVED: 2
        590};
        591
        592
        593/**
        594 * Tests if a value is an Error-like object. This is more than an straight
        595 * instanceof check since the value may originate from another context.
        596 * @param {*} value The value to test.
        597 * @return {boolean} Whether the value is an error.
        598 * @private
        599 */
        600webdriver.promise.isError_ = function(value) {
        601 return value instanceof Error ||
        602 goog.isObject(value) &&
        603 (Object.prototype.toString.call(value) === '[object Error]' ||
        604 // A special test for goog.testing.JsUnitException.
        605 value.isJsUnitException);
        606
        607};
        608
        609
        610/**
        611 * Determines whether a {@code value} should be treated as a promise.
        612 * Any object whose "then" property is a function will be considered a promise.
        613 *
        614 * @param {*} value The value to test.
        615 * @return {boolean} Whether the value is a promise.
        616 */
        617webdriver.promise.isPromise = function(value) {
        618 return !!value && goog.isObject(value) &&
        619 // Use array notation so the Closure compiler does not obfuscate away our
        620 // contract.
        621 goog.isFunction(value['then']);
        622};
        623
        624
        625/**
        626 * Creates a promise that will be resolved at a set time in the future.
        627 * @param {number} ms The amount of time, in milliseconds, to wait before
        628 * resolving the promise.
        629 * @return {!webdriver.promise.Promise} The promise.
        630 */
        631webdriver.promise.delayed = function(ms) {
        632 var timer = webdriver.promise.controlFlow().timer;
        633 var key;
        634 var deferred = new webdriver.promise.Deferred(function() {
        635 timer.clearTimeout(key);
        636 });
        637 key = timer.setTimeout(deferred.fulfill, ms);
        638 return deferred.promise;
        639};
        640
        641
        642/**
        643 * Creates a new deferred object.
        644 * @param {Function=} opt_canceller Function to call when cancelling the
        645 * computation of this instance's value.
        646 * @return {!webdriver.promise.Deferred.<T>} The new deferred object.
        647 * @template T
        648 */
        649webdriver.promise.defer = function(opt_canceller) {
        650 return new webdriver.promise.Deferred(opt_canceller);
        651};
        652
        653
        654/**
        655 * Creates a promise that has been resolved with the given value.
        656 * @param {T=} opt_value The resolved value.
        657 * @return {!webdriver.promise.Promise.<T>} The resolved promise.
        658 * @template T
        659 */
        660webdriver.promise.fulfilled = function(opt_value) {
        661 if (opt_value instanceof webdriver.promise.Promise) {
        662 return opt_value;
        663 }
        664 var deferred = new webdriver.promise.Deferred();
        665 deferred.fulfill(opt_value);
        666 return deferred.promise;
        667};
        668
        669
        670/**
        671 * Creates a promise that has been rejected with the given reason.
        672 * @param {*=} opt_reason The rejection reason; may be any value, but is
        673 * usually an Error or a string.
        674 * @return {!webdriver.promise.Promise.<T>} The rejected promise.
        675 * @template T
        676 */
        677webdriver.promise.rejected = function(opt_reason) {
        678 var deferred = new webdriver.promise.Deferred();
        679 deferred.reject(opt_reason);
        680 return deferred.promise;
        681};
        682
        683
        684/**
        685 * Wraps a function that is assumed to be a node-style callback as its final
        686 * argument. This callback takes two arguments: an error value (which will be
        687 * null if the call succeeded), and the success value as the second argument.
        688 * If the call fails, the returned promise will be rejected, otherwise it will
        689 * be resolved with the result.
        690 * @param {!Function} fn The function to wrap.
        691 * @param {...?} var_args The arguments to apply to the function, excluding the
        692 * final callback.
        693 * @return {!webdriver.promise.Promise} A promise that will be resolved with the
        694 * result of the provided function's callback.
        695 */
        696webdriver.promise.checkedNodeCall = function(fn, var_args) {
        697 var deferred = new webdriver.promise.Deferred(function() {
        698 throw Error('This Deferred may not be cancelled');
        699 });
        700 try {
        701 var args = goog.array.slice(arguments, 1);
        702 args.push(function(error, value) {
        703 error ? deferred.reject(error) : deferred.fulfill(value);
        704 });
        705 fn.apply(null, args);
        706 } catch (ex) {
        707 deferred.reject(ex);
        708 }
        709 return deferred.promise;
        710};
        711
        712
        713/**
        714 * Registers an observer on a promised {@code value}, returning a new promise
        715 * that will be resolved when the value is. If {@code value} is not a promise,
        716 * then the return promise will be immediately resolved.
        717 * @param {*} value The value to observe.
        718 * @param {Function=} opt_callback The function to call when the value is
        719 * resolved successfully.
        720 * @param {Function=} opt_errback The function to call when the value is
        721 * rejected.
        722 * @return {!webdriver.promise.Promise} A new promise.
        723 */
        724webdriver.promise.when = function(value, opt_callback, opt_errback) {
        725 if (webdriver.promise.Thenable.isImplementation(value)) {
        726 return value.then(opt_callback, opt_errback);
        727 }
        728
        729 var deferred = new webdriver.promise.Deferred();
        730
        731 webdriver.promise.asap(value, deferred.fulfill, deferred.reject);
        732
        733 return deferred.then(opt_callback, opt_errback);
        734};
        735
        736
        737/**
        738 * Invokes the appropriate callback function as soon as a promised
        739 * {@code value} is resolved. This function is similar to
        740 * {@link webdriver.promise.when}, except it does not return a new promise.
        741 * @param {*} value The value to observe.
        742 * @param {Function} callback The function to call when the value is
        743 * resolved successfully.
        744 * @param {Function=} opt_errback The function to call when the value is
        745 * rejected.
        746 */
        747webdriver.promise.asap = function(value, callback, opt_errback) {
        748 if (webdriver.promise.isPromise(value)) {
        749 value.then(callback, opt_errback);
        750
        751 // Maybe a Dojo-like deferred object?
        752 } else if (!!value && goog.isObject(value) &&
        753 goog.isFunction(value.addCallbacks)) {
        754 value.addCallbacks(callback, opt_errback);
        755
        756 // A raw value, return a resolved promise.
        757 } else if (callback) {
        758 callback(value);
        759 }
        760};
        761
        762
        763/**
        764 * Given an array of promises, will return a promise that will be fulfilled
        765 * with the fulfillment values of the input array's values. If any of the
        766 * input array's promises are rejected, the returned promise will be rejected
        767 * with the same reason.
        768 *
        769 * @param {!Array.<(T|!webdriver.promise.Promise.<T>)>} arr An array of
        770 * promises to wait on.
        771 * @return {!webdriver.promise.Promise.<!Array.<T>>} A promise that is
        772 * fulfilled with an array containing the fulfilled values of the
        773 * input array, or rejected with the same reason as the first
        774 * rejected value.
        775 * @template T
        776 */
        777webdriver.promise.all = function(arr) {
        778 var n = arr.length;
        779 if (!n) {
        780 return webdriver.promise.fulfilled([]);
        781 }
        782
        783 var toFulfill = n;
        784 var result = webdriver.promise.defer();
        785 var values = [];
        786
        787 var onFulfill = function(index, value) {
        788 values[index] = value;
        789 toFulfill--;
        790 if (toFulfill == 0) {
        791 result.fulfill(values);
        792 }
        793 };
        794
        795 for (var i = 0; i < n; ++i) {
        796 webdriver.promise.asap(
        797 arr[i], goog.partial(onFulfill, i), result.reject);
        798 }
        799
        800 return result.promise;
        801};
        802
        803
        804/**
        805 * Calls a function for each element in an array and inserts the result into a
        806 * new array, which is used as the fulfillment value of the promise returned
        807 * by this function.
        808 *
        809 * <p>If the return value of the mapping function is a promise, this function
        810 * will wait for it to be fulfilled before inserting it into the new array.
        811 *
        812 * <p>If the mapping function throws or returns a rejected promise, the
        813 * promise returned by this function will be rejected with the same reason.
        814 * Only the first failure will be reported; all subsequent errors will be
        815 * silently ignored.
        816 *
        817 * @param {!(Array.<TYPE>|webdriver.promise.Promise.<!Array.<TYPE>>)} arr The
        818 * array to iterator over, or a promise that will resolve to said array.
        819 * @param {function(this: SELF, TYPE, number, !Array.<TYPE>): ?} fn The
        820 * function to call for each element in the array. This function should
        821 * expect three arguments (the element, the index, and the array itself.
        822 * @param {SELF=} opt_self The object to be used as the value of 'this' within
        823 * {@code fn}.
        824 * @template TYPE, SELF
        825 */
        826webdriver.promise.map = function(arr, fn, opt_self) {
        827 return webdriver.promise.when(arr, function(arr) {
        828 var result = goog.array.map(arr, fn, opt_self);
        829 return webdriver.promise.all(result);
        830 });
        831};
        832
        833
        834/**
        835 * Calls a function for each element in an array, and if the function returns
        836 * true adds the element to a new array.
        837 *
        838 * <p>If the return value of the filter function is a promise, this function
        839 * will wait for it to be fulfilled before determining whether to insert the
        840 * element into the new array.
        841 *
        842 * <p>If the filter function throws or returns a rejected promise, the promise
        843 * returned by this function will be rejected with the same reason. Only the
        844 * first failure will be reported; all subsequent errors will be silently
        845 * ignored.
        846 *
        847 * @param {!(Array.<TYPE>|webdriver.promise.Promise.<!Array.<TYPE>>)} arr The
        848 * array to iterator over, or a promise that will resolve to said array.
        849 * @param {function(this: SELF, TYPE, number, !Array.<TYPE>): (
        850 * boolean|webdriver.promise.Promise.<boolean>)} fn The function
        851 * to call for each element in the array.
        852 * @param {SELF=} opt_self The object to be used as the value of 'this' within
        853 * {@code fn}.
        854 * @template TYPE, SELF
        855 */
        856webdriver.promise.filter = function(arr, fn, opt_self) {
        857 return webdriver.promise.when(arr, function(arr) {
        858 var originalValues = goog.array.clone(arr);
        859 return webdriver.promise.map(arr, fn, opt_self).then(function(include) {
        860 return goog.array.filter(originalValues, function(value, index) {
        861 return include[index];
        862 });
        863 });
        864 });
        865};
        866
        867
        868/**
        869 * Returns a promise that will be resolved with the input value in a
        870 * fully-resolved state. If the value is an array, each element will be fully
        871 * resolved. Likewise, if the value is an object, all keys will be fully
        872 * resolved. In both cases, all nested arrays and objects will also be
        873 * fully resolved. All fields are resolved in place; the returned promise will
        874 * resolve on {@code value} and not a copy.
        875 *
        876 * Warning: This function makes no checks against objects that contain
        877 * cyclical references:
        878 * <pre><code>
        879 * var value = {};
        880 * value['self'] = value;
        881 * webdriver.promise.fullyResolved(value); // Stack overflow.
        882 * </code></pre>
        883 *
        884 * @param {*} value The value to fully resolve.
        885 * @return {!webdriver.promise.Promise} A promise for a fully resolved version
        886 * of the input value.
        887 */
        888webdriver.promise.fullyResolved = function(value) {
        889 if (webdriver.promise.isPromise(value)) {
        890 return webdriver.promise.when(value, webdriver.promise.fullyResolveValue_);
        891 }
        892 return webdriver.promise.fullyResolveValue_(value);
        893};
        894
        895
        896/**
        897 * @param {*} value The value to fully resolve. If a promise, assumed to
        898 * already be resolved.
        899 * @return {!webdriver.promise.Promise} A promise for a fully resolved version
        900 * of the input value.
        901 * @private
        902 */
        903webdriver.promise.fullyResolveValue_ = function(value) {
        904 switch (goog.typeOf(value)) {
        905 case 'array':
        906 return webdriver.promise.fullyResolveKeys_(
        907 /** @type {!Array} */ (value));
        908
        909 case 'object':
        910 if (webdriver.promise.isPromise(value)) {
        911 // We get here when the original input value is a promise that
        912 // resolves to itself. When the user provides us with such a promise,
        913 // trust that it counts as a "fully resolved" value and return it.
        914 // Of course, since it's already a promise, we can just return it
        915 // to the user instead of wrapping it in another promise.
        916 return /** @type {!webdriver.promise.Promise} */ (value);
        917 }
        918
        919 if (goog.isNumber(value.nodeType) &&
        920 goog.isObject(value.ownerDocument) &&
        921 goog.isNumber(value.ownerDocument.nodeType)) {
        922 // DOM node; return early to avoid infinite recursion. Should we
        923 // only support objects with a certain level of nesting?
        924 return webdriver.promise.fulfilled(value);
        925 }
        926
        927 return webdriver.promise.fullyResolveKeys_(
        928 /** @type {!Object} */ (value));
        929
        930 default: // boolean, function, null, number, string, undefined
        931 return webdriver.promise.fulfilled(value);
        932 }
        933};
        934
        935
        936/**
        937 * @param {!(Array|Object)} obj the object to resolve.
        938 * @return {!webdriver.promise.Promise} A promise that will be resolved with the
        939 * input object once all of its values have been fully resolved.
        940 * @private
        941 */
        942webdriver.promise.fullyResolveKeys_ = function(obj) {
        943 var isArray = goog.isArray(obj);
        944 var numKeys = isArray ? obj.length : goog.object.getCount(obj);
        945 if (!numKeys) {
        946 return webdriver.promise.fulfilled(obj);
        947 }
        948
        949 var numResolved = 0;
        950 var deferred = new webdriver.promise.Deferred();
        951
        952 // In pre-IE9, goog.array.forEach will not iterate properly over arrays
        953 // containing undefined values because "index in array" returns false
        954 // when array[index] === undefined (even for x = [undefined, 1]). To get
        955 // around this, we need to use our own forEach implementation.
        956 // DO NOT REMOVE THIS UNTIL WE NO LONGER SUPPORT IE8. This cannot be
        957 // reproduced in IE9 by changing the browser/document modes, it requires an
        958 // actual pre-IE9 browser. Yay, IE!
        959 var forEachKey = !isArray ? goog.object.forEach : function(arr, fn) {
        960 var n = arr.length;
        961 for (var i = 0; i < n; ++i) {
        962 fn.call(null, arr[i], i, arr);
        963 }
        964 };
        965
        966 forEachKey(obj, function(partialValue, key) {
        967 var type = goog.typeOf(partialValue);
        968 if (type != 'array' && type != 'object') {
        969 maybeResolveValue();
        970 return;
        971 }
        972
        973 webdriver.promise.fullyResolved(partialValue).then(
        974 function(resolvedValue) {
        975 obj[key] = resolvedValue;
        976 maybeResolveValue();
        977 },
        978 deferred.reject);
        979 });
        980
        981 return deferred.promise;
        982
        983 function maybeResolveValue() {
        984 if (++numResolved == numKeys) {
        985 deferred.fulfill(obj);
        986 }
        987 }
        988};
        989
        990
        991//////////////////////////////////////////////////////////////////////////////
        992//
        993// webdriver.promise.ControlFlow
        994//
        995//////////////////////////////////////////////////////////////////////////////
        996
        997
        998
        999/**
        1000 * Handles the execution of scheduled tasks, each of which may be an
        1001 * asynchronous operation. The control flow will ensure tasks are executed in
        1002 * the ordered scheduled, starting each task only once those before it have
        1003 * completed.
        1004 *
        1005 * <p>Each task scheduled within this flow may return a
        1006 * {@link webdriver.promise.Promise} to indicate it is an asynchronous
        1007 * operation. The ControlFlow will wait for such promises to be resolved before
        1008 * marking the task as completed.
        1009 *
        1010 * <p>Tasks and each callback registered on a {@link webdriver.promise.Deferred}
        1011 * will be run in their own ControlFlow frame. Any tasks scheduled within a
        1012 * frame will have priority over previously scheduled tasks. Furthermore, if
        1013 * any of the tasks in the frame fails, the remainder of the tasks in that frame
        1014 * will be discarded and the failure will be propagated to the user through the
        1015 * callback/task's promised result.
        1016 *
        1017 * <p>Each time a ControlFlow empties its task queue, it will fire an
        1018 * {@link webdriver.promise.ControlFlow.EventType.IDLE} event. Conversely,
        1019 * whenever the flow terminates due to an unhandled error, it will remove all
        1020 * remaining tasks in its queue and fire an
        1021 * {@link webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION} event. If
        1022 * there are no listeners registered with the flow, the error will be
        1023 * rethrown to the global error handler.
        1024 *
        1025 * @param {webdriver.promise.ControlFlow.Timer=} opt_timer The timer object
        1026 * to use. Should only be set for testing.
        1027 * @constructor
        1028 * @extends {webdriver.EventEmitter}
        1029 */
        1030webdriver.promise.ControlFlow = function(opt_timer) {
        1031 webdriver.EventEmitter.call(this);
        1032
        1033 /**
        1034 * The timer used by this instance.
        1035 * @type {webdriver.promise.ControlFlow.Timer}
        1036 */
        1037 this.timer = opt_timer || webdriver.promise.ControlFlow.defaultTimer;
        1038
        1039 /**
        1040 * A list of recent tasks. Each time a new task is started, or a frame is
        1041 * completed, the previously recorded task is removed from this list. If
        1042 * there are multiple tasks, task N+1 is considered a sub-task of task
        1043 * N.
        1044 * @private {!Array.<!webdriver.promise.Task_>}
        1045 */
        1046 this.history_ = [];
        1047};
        1048goog.inherits(webdriver.promise.ControlFlow, webdriver.EventEmitter);
        1049
        1050
        1051/**
        1052 * @typedef {{clearInterval: function(number),
        1053 * clearTimeout: function(number),
        1054 * setInterval: function(!Function, number): number,
        1055 * setTimeout: function(!Function, number): number}}
        1056 */
        1057webdriver.promise.ControlFlow.Timer;
        1058
        1059
        1060/**
        1061 * The default timer object, which uses the global timer functions.
        1062 * @type {webdriver.promise.ControlFlow.Timer}
        1063 */
        1064webdriver.promise.ControlFlow.defaultTimer = (function() {
        1065 // The default timer functions may be defined as free variables for the
        1066 // current context, so do not reference them using "window" or
        1067 // "goog.global". Also, we must invoke them in a closure, and not using
        1068 // bind(), so we do not get "TypeError: Illegal invocation" (WebKit) or
        1069 // "Invalid calling object" (IE) errors.
        1070 return {
        1071 clearInterval: wrap(clearInterval),
        1072 clearTimeout: wrap(clearTimeout),
        1073 setInterval: wrap(setInterval),
        1074 setTimeout: wrap(setTimeout)
        1075 };
        1076
        1077 function wrap(fn) {
        1078 return function() {
        1079 // Cannot use .call() or .apply() since we do not know which variable
        1080 // the function is bound to, and using the wrong one will generate
        1081 // an error.
        1082 return fn(arguments[0], arguments[1]);
        1083 };
        1084 }
        1085})();
        1086
        1087
        1088/**
        1089 * Events that may be emitted by an {@link webdriver.promise.ControlFlow}.
        1090 * @enum {string}
        1091 */
        1092webdriver.promise.ControlFlow.EventType = {
        1093
        1094 /** Emitted when all tasks have been successfully executed. */
        1095 IDLE: 'idle',
        1096
        1097 /** Emitted when a ControlFlow has been reset. */
        1098 RESET: 'reset',
        1099
        1100 /** Emitted whenever a new task has been scheduled. */
        1101 SCHEDULE_TASK: 'scheduleTask',
        1102
        1103 /**
        1104 * Emitted whenever a control flow aborts due to an unhandled promise
        1105 * rejection. This event will be emitted along with the offending rejection
        1106 * reason. Upon emitting this event, the control flow will empty its task
        1107 * queue and revert to its initial state.
        1108 */
        1109 UNCAUGHT_EXCEPTION: 'uncaughtException'
        1110};
        1111
        1112
        1113/**
        1114 * How often, in milliseconds, the event loop should run.
        1115 * @type {number}
        1116 * @const
        1117 */
        1118webdriver.promise.ControlFlow.EVENT_LOOP_FREQUENCY = 10;
        1119
        1120
        1121/**
        1122 * Tracks the active execution frame for this instance. Lazily initialized
        1123 * when the first task is scheduled.
        1124 * @private {webdriver.promise.Frame_}
        1125 */
        1126webdriver.promise.ControlFlow.prototype.activeFrame_ = null;
        1127
        1128
        1129/**
        1130 * A reference to the frame in which new tasks should be scheduled. If
        1131 * {@code null}, tasks will be scheduled within the active frame. When forcing
        1132 * a function to run in the context of a new frame, this pointer is used to
        1133 * ensure tasks are scheduled within the newly created frame, even though it
        1134 * won't be active yet.
        1135 * @private {webdriver.promise.Frame_}
        1136 * @see {#runInNewFrame_}
        1137 */
        1138webdriver.promise.ControlFlow.prototype.schedulingFrame_ = null;
        1139
        1140
        1141/**
        1142 * Timeout ID set when the flow is about to shutdown without any errors
        1143 * being detected. Upon shutting down, the flow will emit an
        1144 * {@link webdriver.promise.ControlFlow.EventType.IDLE} event. Idle events
        1145 * always follow a brief timeout in order to catch latent errors from the last
        1146 * completed task. If this task had a callback registered, but no errback, and
        1147 * the task fails, the unhandled failure would not be reported by the promise
        1148 * system until the next turn of the event loop:
        1149 *
        1150 * // Schedule 1 task that fails.
        1151 * var result = webriver.promise.controlFlow().schedule('example',
        1152 * function() { return webdriver.promise.rejected('failed'); });
        1153 * // Set a callback on the result. This delays reporting the unhandled
        1154 * // failure for 1 turn of the event loop.
        1155 * result.then(goog.nullFunction);
        1156 *
        1157 * @private {?number}
        1158 */
        1159webdriver.promise.ControlFlow.prototype.shutdownId_ = null;
        1160
        1161
        1162/**
        1163 * Interval ID for this instance's event loop.
        1164 * @private {?number}
        1165 */
        1166webdriver.promise.ControlFlow.prototype.eventLoopId_ = null;
        1167
        1168
        1169/**
        1170 * The number of "pending" promise rejections.
        1171 *
        1172 * <p>Each time a promise is rejected and is not handled by a listener, it will
        1173 * schedule a 0-based timeout to check if it is still unrejected in the next
        1174 * turn of the JS-event loop. This allows listeners to attach to, and handle,
        1175 * the rejected promise at any point in same turn of the event loop that the
        1176 * promise was rejected.
        1177 *
        1178 * <p>When this flow's own event loop triggers, it will not run if there
        1179 * are any outstanding promise rejections. This allows unhandled promises to
        1180 * be reported before a new task is started, ensuring the error is reported to
        1181 * the current task queue.
        1182 *
        1183 * @private {number}
        1184 */
        1185webdriver.promise.ControlFlow.prototype.pendingRejections_ = 0;
        1186
        1187
        1188/**
        1189 * The number of aborted frames since the last time a task was executed or a
        1190 * frame completed successfully.
        1191 * @private {number}
        1192 */
        1193webdriver.promise.ControlFlow.prototype.numAbortedFrames_ = 0;
        1194
        1195
        1196/**
        1197 * Resets this instance, clearing its queue and removing all event listeners.
        1198 */
        1199webdriver.promise.ControlFlow.prototype.reset = function() {
        1200 this.activeFrame_ = null;
        1201 this.clearHistory();
        1202 this.emit(webdriver.promise.ControlFlow.EventType.RESET);
        1203 this.removeAllListeners();
        1204 this.cancelShutdown_();
        1205 this.cancelEventLoop_();
        1206};
        1207
        1208
        1209/**
        1210 * Returns a summary of the recent task activity for this instance. This
        1211 * includes the most recently completed task, as well as any parent tasks. In
        1212 * the returned summary, the task at index N is considered a sub-task of the
        1213 * task at index N+1.
        1214 * @return {!Array.<string>} A summary of this instance's recent task
        1215 * activity.
        1216 */
        1217webdriver.promise.ControlFlow.prototype.getHistory = function() {
        1218 var pendingTasks = [];
        1219 var currentFrame = this.activeFrame_;
        1220 while (currentFrame) {
        1221 var task = currentFrame.getPendingTask();
        1222 if (task) {
        1223 pendingTasks.push(task);
        1224 }
        1225 // A frame's parent node will always be another frame.
        1226 currentFrame =
        1227 /** @type {webdriver.promise.Frame_} */ (currentFrame.getParent());
        1228 }
        1229
        1230 var fullHistory = goog.array.concat(this.history_, pendingTasks);
        1231 return goog.array.map(fullHistory, function(task) {
        1232 return task.toString();
        1233 });
        1234};
        1235
        1236
        1237/** Clears this instance's task history. */
        1238webdriver.promise.ControlFlow.prototype.clearHistory = function() {
        1239 this.history_ = [];
        1240};
        1241
        1242
        1243/**
        1244 * Removes a completed task from this instance's history record. If any
        1245 * tasks remain from aborted frames, those will be removed as well.
        1246 * @private
        1247 */
        1248webdriver.promise.ControlFlow.prototype.trimHistory_ = function() {
        1249 if (this.numAbortedFrames_) {
        1250 goog.array.splice(this.history_,
        1251 this.history_.length - this.numAbortedFrames_,
        1252 this.numAbortedFrames_);
        1253 this.numAbortedFrames_ = 0;
        1254 }
        1255 this.history_.pop();
        1256};
        1257
        1258
        1259/**
        1260 * Property used to track whether an error has been annotated by
        1261 * {@link webdriver.promise.ControlFlow#annotateError}.
        1262 * @private {string}
        1263 * @const
        1264 */
        1265webdriver.promise.ControlFlow.ANNOTATION_PROPERTY_ =
        1266 'webdriver_promise_error_';
        1267
        1268
        1269/**
        1270 * Appends a summary of this instance's recent task history to the given
        1271 * error's stack trace. This function will also ensure the error's stack trace
        1272 * is in canonical form.
        1273 * @param {!(Error|goog.testing.JsUnitException)} e The error to annotate.
        1274 * @return {!(Error|goog.testing.JsUnitException)} The annotated error.
        1275 */
        1276webdriver.promise.ControlFlow.prototype.annotateError = function(e) {
        1277 if (!!e[webdriver.promise.ControlFlow.ANNOTATION_PROPERTY_]) {
        1278 return e;
        1279 }
        1280
        1281 var history = this.getHistory();
        1282 if (history.length) {
        1283 e = webdriver.stacktrace.format(e);
        1284
        1285 /** @type {!Error} */(e).stack += [
        1286 '\n==== async task ====\n',
        1287 history.join('\n==== async task ====\n')
        1288 ].join('');
        1289
        1290 e[webdriver.promise.ControlFlow.ANNOTATION_PROPERTY_] = true;
        1291 }
        1292
        1293 return e;
        1294};
        1295
        1296
        1297/**
        1298 * @return {string} The scheduled tasks still pending with this instance.
        1299 */
        1300webdriver.promise.ControlFlow.prototype.getSchedule = function() {
        1301 return this.activeFrame_ ? this.activeFrame_.getRoot().toString() : '[]';
        1302};
        1303
        1304
        1305/**
        1306 * Schedules a task for execution. If there is nothing currently in the
        1307 * queue, the task will be executed in the next turn of the event loop. If
        1308 * the task function is a generator, the task will be executed using
        1309 * {@link webdriver.promise.consume}.
        1310 *
        1311 * @param {function(): (T|webdriver.promise.Promise.<T>)} fn The function to
        1312 * call to start the task. If the function returns a
        1313 * {@link webdriver.promise.Promise}, this instance will wait for it to be
        1314 * resolved before starting the next task.
        1315 * @param {string=} opt_description A description of the task.
        1316 * @return {!webdriver.promise.Promise.<T>} A promise that will be resolved
        1317 * with the result of the action.
        1318 * @template T
        1319 */
        1320webdriver.promise.ControlFlow.prototype.execute = function(
        1321 fn, opt_description) {
        1322 if (webdriver.promise.isGenerator(fn)) {
        1323 fn = goog.partial(webdriver.promise.consume, fn);
        1324 }
        1325
        1326 this.cancelShutdown_();
        1327
        1328 if (!this.activeFrame_) {
        1329 this.activeFrame_ = new webdriver.promise.Frame_(this);
        1330 }
        1331
        1332 // Trim an extra frame off the generated stack trace for the call to this
        1333 // function.
        1334 var snapshot = new webdriver.stacktrace.Snapshot(1);
        1335 var task = new webdriver.promise.Task_(
        1336 this, fn, opt_description || '', snapshot);
        1337 var scheduleIn = this.schedulingFrame_ || this.activeFrame_;
        1338 scheduleIn.addChild(task);
        1339
        1340 this.emit(webdriver.promise.ControlFlow.EventType.SCHEDULE_TASK, opt_description);
        1341
        1342 this.scheduleEventLoopStart_();
        1343 return task.promise;
        1344};
        1345
        1346
        1347/**
        1348 * Inserts a {@code setTimeout} into the command queue. This is equivalent to
        1349 * a thread sleep in a synchronous programming language.
        1350 *
        1351 * @param {number} ms The timeout delay, in milliseconds.
        1352 * @param {string=} opt_description A description to accompany the timeout.
        1353 * @return {!webdriver.promise.Promise} A promise that will be resolved with
        1354 * the result of the action.
        1355 */
        1356webdriver.promise.ControlFlow.prototype.timeout = function(
        1357 ms, opt_description) {
        1358 return this.execute(function() {
        1359 return webdriver.promise.delayed(ms);
        1360 }, opt_description);
        1361};
        1362
        1363
        1364/**
        1365 * Schedules a task that shall wait for a condition to hold. Each condition
        1366 * function may return any value, but it will always be evaluated as a boolean.
        1367 *
        1368 * <p>Condition functions may schedule sub-tasks with this instance, however,
        1369 * their execution time will be factored into whether a wait has timed out.
        1370 *
        1371 * <p>In the event a condition returns a Promise, the polling loop will wait for
        1372 * it to be resolved before evaluating whether the condition has been satisfied.
        1373 * The resolution time for a promise is factored into whether a wait has timed
        1374 * out.
        1375 *
        1376 * <p>If the condition function throws, or returns a rejected promise, the
        1377 * wait task will fail.
        1378 *
        1379 * @param {!Function} condition The condition function to poll.
        1380 * @param {number} timeout How long to wait, in milliseconds, for the condition
        1381 * to hold before timing out.
        1382 * @param {string=} opt_message An optional error message to include if the
        1383 * wait times out; defaults to the empty string.
        1384 * @return {!webdriver.promise.Promise} A promise that will be resolved when the
        1385 * condition has been satisified. The promise shall be rejected if the wait
        1386 * times out waiting for the condition.
        1387 */
        1388webdriver.promise.ControlFlow.prototype.wait = function(
        1389 condition, timeout, opt_message) {
        1390 var sleep = Math.min(timeout, 100);
        1391 var self = this;
        1392
        1393 if (webdriver.promise.isGenerator(condition)) {
        1394 condition = goog.partial(webdriver.promise.consume, condition);
        1395 }
        1396
        1397 return this.execute(function() {
        1398 var startTime = goog.now();
        1399 var waitResult = new webdriver.promise.Deferred();
        1400 var waitFrame = self.activeFrame_;
        1401 waitFrame.isWaiting = true;
        1402 pollCondition();
        1403 return waitResult.promise;
        1404
        1405 function pollCondition() {
        1406 self.runInNewFrame_(condition, function(value) {
        1407 var elapsed = goog.now() - startTime;
        1408 if (!!value) {
        1409 waitFrame.isWaiting = false;
        1410 waitResult.fulfill(value);
        1411 } else if (elapsed >= timeout) {
        1412 waitResult.reject(new Error((opt_message ? opt_message + '\n' : '') +
        1413 'Wait timed out after ' + elapsed + 'ms'));
        1414 } else {
        1415 self.timer.setTimeout(pollCondition, sleep);
        1416 }
        1417 }, waitResult.reject, true);
        1418 }
        1419 }, opt_message);
        1420};
        1421
        1422
        1423/**
        1424 * Schedules a task that will wait for another promise to resolve. The resolved
        1425 * promise's value will be returned as the task result.
        1426 * @param {!webdriver.promise.Promise} promise The promise to wait on.
        1427 * @return {!webdriver.promise.Promise} A promise that will resolve when the
        1428 * task has completed.
        1429 */
        1430webdriver.promise.ControlFlow.prototype.await = function(promise) {
        1431 return this.execute(function() {
        1432 return promise;
        1433 });
        1434};
        1435
        1436
        1437/**
        1438 * Schedules the interval for this instance's event loop, if necessary.
        1439 * @private
        1440 */
        1441webdriver.promise.ControlFlow.prototype.scheduleEventLoopStart_ = function() {
        1442 if (!this.eventLoopId_) {
        1443 this.eventLoopId_ = this.timer.setInterval(
        1444 goog.bind(this.runEventLoop_, this),
        1445 webdriver.promise.ControlFlow.EVENT_LOOP_FREQUENCY);
        1446 }
        1447};
        1448
        1449
        1450/**
        1451 * Cancels the event loop, if necessary.
        1452 * @private
        1453 */
        1454webdriver.promise.ControlFlow.prototype.cancelEventLoop_ = function() {
        1455 if (this.eventLoopId_) {
        1456 this.timer.clearInterval(this.eventLoopId_);
        1457 this.eventLoopId_ = null;
        1458 }
        1459};
        1460
        1461
        1462/**
        1463 * Executes the next task for the current frame. If the current frame has no
        1464 * more tasks, the frame's result will be resolved, returning control to the
        1465 * frame's creator. This will terminate the flow if the completed frame was at
        1466 * the top of the stack.
        1467 * @private
        1468 */
        1469webdriver.promise.ControlFlow.prototype.runEventLoop_ = function() {
        1470 // If we get here and there are pending promise rejections, then those
        1471 // promises are queued up to run as soon as this (JS) event loop terminates.
        1472 // Short-circuit our loop to give those promises a chance to run. Otherwise,
        1473 // we might start a new task only to have it fail because of one of these
        1474 // pending rejections.
        1475 if (this.pendingRejections_) {
        1476 return;
        1477 }
        1478
        1479 // If the flow aborts due to an unhandled exception after we've scheduled
        1480 // another turn of the execution loop, we can end up in here with no tasks
        1481 // left. This is OK, just quietly return.
        1482 if (!this.activeFrame_) {
        1483 this.commenceShutdown_();
        1484 return;
        1485 }
        1486
        1487 var task;
        1488 if (this.activeFrame_.getPendingTask() || !(task = this.getNextTask_())) {
        1489 // Either the current frame is blocked on a pending task, or we don't have
        1490 // a task to finish because we've completed a frame. When completing a
        1491 // frame, we must abort the event loop to allow the frame's promise's
        1492 // callbacks to execute.
        1493 return;
        1494 }
        1495
        1496 var activeFrame = this.activeFrame_;
        1497 activeFrame.setPendingTask(task);
        1498 var markTaskComplete = goog.bind(function() {
        1499 this.history_.push(/** @type {!webdriver.promise.Task_} */ (task));
        1500 activeFrame.setPendingTask(null);
        1501 }, this);
        1502
        1503 this.trimHistory_();
        1504 var self = this;
        1505 this.runInNewFrame_(task.execute, function(result) {
        1506 markTaskComplete();
        1507 task.fulfill(result);
        1508 }, function(error) {
        1509 markTaskComplete();
        1510
        1511 if (!webdriver.promise.isError_(error) &&
        1512 !webdriver.promise.isPromise(error)) {
        1513 error = Error(error);
        1514 }
        1515
        1516 task.reject(self.annotateError(/** @type {!Error} */ (error)));
        1517 }, true);
        1518};
        1519
        1520
        1521/**
        1522 * @return {webdriver.promise.Task_} The next task to execute, or
        1523 * {@code null} if a frame was resolved.
        1524 * @private
        1525 */
        1526webdriver.promise.ControlFlow.prototype.getNextTask_ = function() {
        1527 var firstChild = this.activeFrame_.getFirstChild();
        1528 if (!firstChild) {
        1529 if (!this.activeFrame_.isWaiting) {
        1530 this.resolveFrame_(this.activeFrame_);
        1531 }
        1532 return null;
        1533 }
        1534
        1535 if (firstChild instanceof webdriver.promise.Frame_) {
        1536 this.activeFrame_ = firstChild;
        1537 return this.getNextTask_();
        1538 }
        1539
        1540 firstChild.getParent().removeChild(firstChild);
        1541 return firstChild;
        1542};
        1543
        1544
        1545/**
        1546 * @param {!webdriver.promise.Frame_} frame The frame to resolve.
        1547 * @private
        1548 */
        1549webdriver.promise.ControlFlow.prototype.resolveFrame_ = function(frame) {
        1550 if (this.activeFrame_ === frame) {
        1551 // Frame parent is always another frame, but the compiler is not smart
        1552 // enough to recognize this.
        1553 this.activeFrame_ =
        1554 /** @type {webdriver.promise.Frame_} */ (frame.getParent());
        1555 }
        1556
        1557 if (frame.getParent()) {
        1558 frame.getParent().removeChild(frame);
        1559 }
        1560 this.trimHistory_();
        1561 frame.fulfill();
        1562
        1563 if (!this.activeFrame_) {
        1564 this.commenceShutdown_();
        1565 }
        1566};
        1567
        1568
        1569/**
        1570 * Aborts the current frame. The frame, and all of the tasks scheduled within it
        1571 * will be discarded. If this instance does not have an active frame, it will
        1572 * immediately terminate all execution.
        1573 * @param {*} error The reason the frame is being aborted; typically either
        1574 * an Error or string.
        1575 * @private
        1576 */
        1577webdriver.promise.ControlFlow.prototype.abortFrame_ = function(error) {
        1578 // Annotate the error value if it is Error-like.
        1579 if (webdriver.promise.isError_(error)) {
        1580 this.annotateError(/** @type {!Error} */ (error));
        1581 }
        1582 this.numAbortedFrames_++;
        1583
        1584 if (!this.activeFrame_) {
        1585 this.abortNow_(error);
        1586 return;
        1587 }
        1588
        1589 // Frame parent is always another frame, but the compiler is not smart
        1590 // enough to recognize this.
        1591 var parent = /** @type {webdriver.promise.Frame_} */ (
        1592 this.activeFrame_.getParent());
        1593 if (parent) {
        1594 parent.removeChild(this.activeFrame_);
        1595 }
        1596
        1597 var frame = this.activeFrame_;
        1598 this.activeFrame_ = parent;
        1599 frame.reject(error);
        1600};
        1601
        1602
        1603/**
        1604 * Executes a function in a new frame. If the function does not schedule any new
        1605 * tasks, the frame will be discarded and the function's result returned
        1606 * immediately. Otherwise, a promise will be returned. This promise will be
        1607 * resolved with the function's result once all of the tasks scheduled within
        1608 * the function have been completed. If the function's frame is aborted, the
        1609 * returned promise will be rejected.
        1610 *
        1611 * @param {!Function} fn The function to execute.
        1612 * @param {function(*)} callback The function to call with a successful result.
        1613 * @param {function(*)} errback The function to call if there is an error.
        1614 * @param {boolean=} opt_activate Whether the active frame should be updated to
        1615 * the newly created frame so tasks are treated as sub-tasks.
        1616 * @private
        1617 */
        1618webdriver.promise.ControlFlow.prototype.runInNewFrame_ = function(
        1619 fn, callback, errback, opt_activate) {
        1620 var newFrame = new webdriver.promise.Frame_(this),
        1621 self = this,
        1622 oldFrame = this.activeFrame_;
        1623
        1624 try {
        1625 if (!this.activeFrame_) {
        1626 this.activeFrame_ = newFrame;
        1627 } else {
        1628 this.activeFrame_.addChild(newFrame);
        1629 }
        1630
        1631 // Activate the new frame to force tasks to be treated as sub-tasks of
        1632 // the parent frame.
        1633 if (opt_activate) {
        1634 this.activeFrame_ = newFrame;
        1635 }
        1636
        1637 try {
        1638 this.schedulingFrame_ = newFrame;
        1639 webdriver.promise.pushFlow_(this);
        1640 var result = fn();
        1641 } finally {
        1642 webdriver.promise.popFlow_();
        1643 this.schedulingFrame_ = null;
        1644 }
        1645 newFrame.lockFrame();
        1646
        1647 // If there was nothing scheduled in the new frame we can discard the
        1648 // frame and return immediately.
        1649 if (!newFrame.children_.length) {
        1650 removeNewFrame();
        1651 webdriver.promise.asap(result, callback, errback);
        1652 return;
        1653 }
        1654
        1655 newFrame.then(function() {
        1656 webdriver.promise.asap(result, callback, errback);
        1657 }, function(e) {
        1658 if (webdriver.promise.Thenable.isImplementation(result) &&
        1659 result.isPending()) {
        1660 result.cancel(e);
        1661 e = result;
        1662 }
        1663 errback(e);
        1664 });
        1665 } catch (ex) {
        1666 removeNewFrame(new webdriver.promise.CanceledTaskError_(ex));
        1667 errback(ex);
        1668 }
        1669
        1670 /**
        1671 * @param {webdriver.promise.CanceledTaskError_=} opt_err If provided, the
        1672 * error that triggered the removal of this frame.
        1673 */
        1674 function removeNewFrame(opt_err) {
        1675 var parent = newFrame.getParent();
        1676 if (parent) {
        1677 parent.removeChild(newFrame);
        1678 }
        1679
        1680 if (opt_err) {
        1681 newFrame.cancelRemainingTasks(opt_err);
        1682 }
        1683 self.activeFrame_ = oldFrame;
        1684 }
        1685};
        1686
        1687
        1688/**
        1689 * Commences the shutdown sequence for this instance. After one turn of the
        1690 * event loop, this object will emit the
        1691 * {@link webdriver.promise.ControlFlow.EventType.IDLE} event to signal
        1692 * listeners that it has completed. During this wait, if another task is
        1693 * scheduled, the shutdown will be aborted.
        1694 * @private
        1695 */
        1696webdriver.promise.ControlFlow.prototype.commenceShutdown_ = function() {
        1697 if (!this.shutdownId_) {
        1698 // Go ahead and stop the event loop now. If we're in here, then there are
        1699 // no more frames with tasks to execute. If we waited to cancel the event
        1700 // loop in our timeout below, the event loop could trigger *before* the
        1701 // timeout, generating an error from there being no frames.
        1702 // If #execute is called before the timeout below fires, it will cancel
        1703 // the timeout and restart the event loop.
        1704 this.cancelEventLoop_();
        1705
        1706 var self = this;
        1707 self.shutdownId_ = self.timer.setTimeout(function() {
        1708 self.shutdownId_ = null;
        1709 self.emit(webdriver.promise.ControlFlow.EventType.IDLE);
        1710 }, 0);
        1711 }
        1712};
        1713
        1714
        1715/**
        1716 * Cancels the shutdown sequence if it is currently scheduled.
        1717 * @private
        1718 */
        1719webdriver.promise.ControlFlow.prototype.cancelShutdown_ = function() {
        1720 if (this.shutdownId_) {
        1721 this.timer.clearTimeout(this.shutdownId_);
        1722 this.shutdownId_ = null;
        1723 }
        1724};
        1725
        1726
        1727/**
        1728 * Aborts this flow, abandoning all remaining tasks. If there are
        1729 * listeners registered, an {@code UNCAUGHT_EXCEPTION} will be emitted with the
        1730 * offending {@code error}, otherwise, the {@code error} will be rethrown to the
        1731 * global error handler.
        1732 * @param {*} error Object describing the error that caused the flow to
        1733 * abort; usually either an Error or string value.
        1734 * @private
        1735 */
        1736webdriver.promise.ControlFlow.prototype.abortNow_ = function(error) {
        1737 this.activeFrame_ = null;
        1738 this.cancelShutdown_();
        1739 this.cancelEventLoop_();
        1740
        1741 var listeners = this.listeners(
        1742 webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
        1743 if (!listeners.length) {
        1744 this.timer.setTimeout(function() {
        1745 throw error;
        1746 }, 0);
        1747 } else {
        1748 this.emit(webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
        1749 error);
        1750 }
        1751};
        1752
        1753
        1754
        1755/**
        1756 * A single node in an {@link webdriver.promise.ControlFlow}'s task tree.
        1757 * @param {!webdriver.promise.ControlFlow} flow The flow this instance belongs
        1758 * to.
        1759 * @constructor
        1760 * @extends {webdriver.promise.Deferred}
        1761 * @private
        1762 */
        1763webdriver.promise.Node_ = function(flow) {
        1764 webdriver.promise.Deferred.call(this, null, flow);
        1765};
        1766goog.inherits(webdriver.promise.Node_, webdriver.promise.Deferred);
        1767
        1768
        1769/**
        1770 * This node's parent.
        1771 * @private {webdriver.promise.Node_}
        1772 */
        1773webdriver.promise.Node_.prototype.parent_ = null;
        1774
        1775
        1776/** @return {webdriver.promise.Node_} This node's parent. */
        1777webdriver.promise.Node_.prototype.getParent = function() {
        1778 return this.parent_;
        1779};
        1780
        1781
        1782/**
        1783 * @param {webdriver.promise.Node_} parent This node's new parent.
        1784 */
        1785webdriver.promise.Node_.prototype.setParent = function(parent) {
        1786 this.parent_ = parent;
        1787};
        1788
        1789
        1790/**
        1791 * @return {!webdriver.promise.Node_} The root of this node's tree.
        1792 */
        1793webdriver.promise.Node_.prototype.getRoot = function() {
        1794 var root = this;
        1795 while (root.parent_) {
        1796 root = root.parent_;
        1797 }
        1798 return root;
        1799};
        1800
        1801
        1802
        1803/**
        1804 * An execution frame within a {@link webdriver.promise.ControlFlow}. Each
        1805 * frame represents the execution context for either a
        1806 * {@link webdriver.promise.Task_} or a callback on a
        1807 * {@link webdriver.promise.Deferred}.
        1808 *
        1809 * <p>Each frame may contain sub-frames. If child N is a sub-frame, then the
        1810 * items queued within it are given priority over child N+1.
        1811 *
        1812 * @param {!webdriver.promise.ControlFlow} flow The flow this instance belongs
        1813 * to.
        1814 * @constructor
        1815 * @extends {webdriver.promise.Node_}
        1816 * @private
        1817 */
        1818webdriver.promise.Frame_ = function(flow) {
        1819 webdriver.promise.Node_.call(this, flow);
        1820
        1821 var reject = goog.bind(this.reject, this);
        1822 var cancelRemainingTasks = goog.bind(this.cancelRemainingTasks, this);
        1823
        1824 /** @override */
        1825 this.reject = function(e) {
        1826 cancelRemainingTasks(new webdriver.promise.CanceledTaskError_(e));
        1827 reject(e);
        1828 };
        1829
        1830 /**
        1831 * @private {!Array.<!(webdriver.promise.Frame_|webdriver.promise.Task_)>}
        1832 */
        1833 this.children_ = [];
        1834};
        1835goog.inherits(webdriver.promise.Frame_, webdriver.promise.Node_);
        1836
        1837
        1838/**
        1839 * The task currently being executed within this frame.
        1840 * @private {webdriver.promise.Task_}
        1841 */
        1842webdriver.promise.Frame_.prototype.pendingTask_ = null;
        1843
        1844
        1845/**
        1846 * Whether this frame is active. A frame is considered active once one of its
        1847 * descendants has been removed for execution.
        1848 *
        1849 * Adding a sub-frame as a child to an active frame is an indication that
        1850 * a callback to a {@link webdriver.promise.Deferred} is being invoked and any
        1851 * tasks scheduled within it should have priority over previously scheduled
        1852 * tasks:
        1853 * <code><pre>
        1854 * var flow = webdriver.promise.controlFlow();
        1855 * flow.execute('start here', goog.nullFunction).then(function() {
        1856 * flow.execute('this should execute 2nd', goog.nullFunction);
        1857 * });
        1858 * flow.execute('this should execute last', goog.nullFunction);
        1859 * </pre></code>
        1860 *
        1861 * @private {boolean}
        1862 */
        1863webdriver.promise.Frame_.prototype.isActive_ = false;
        1864
        1865
        1866/**
        1867 * Whether this frame is currently locked. A locked frame represents a callback
        1868 * or task function which has run to completion and scheduled all of its tasks.
        1869 *
        1870 * <p>Once a frame becomes {@link #isActive_ active}, any new frames which are
        1871 * added represent callbacks on a {@link webdriver.promise.Deferred}, whose
        1872 * tasks must be given priority over previously scheduled tasks.
        1873 *
        1874 * @private {boolean}
        1875 */
        1876webdriver.promise.Frame_.prototype.isLocked_ = false;
        1877
        1878
        1879/**
        1880 * A reference to the last node inserted in this frame.
        1881 * @private {webdriver.promise.Node_}
        1882 */
        1883webdriver.promise.Frame_.prototype.lastInsertedChild_ = null;
        1884
        1885
        1886/**
        1887 * Marks all of the tasks that are descendants of this frame in the execution
        1888 * tree as cancelled. This is necessary for callbacks scheduled asynchronous.
        1889 * For example:
        1890 *
        1891 * var someResult;
        1892 * webdriver.promise.createFlow(function(flow) {
        1893 * someResult = flow.execute(function() {});
        1894 * throw Error();
        1895 * }).addErrback(function(err) {
        1896 * console.log('flow failed: ' + err);
        1897 * someResult.then(function() {
        1898 * console.log('task succeeded!');
        1899 * }, function(err) {
        1900 * console.log('task failed! ' + err);
        1901 * });
        1902 * });
        1903 * // flow failed: Error: boom
        1904 * // task failed! CanceledTaskError: Task discarded due to a previous
        1905 * // task failure: Error: boom
        1906 *
        1907 * @param {!webdriver.promise.CanceledTaskError_} error The cancellation
        1908 * error.
        1909 */
        1910webdriver.promise.Frame_.prototype.cancelRemainingTasks = function(error) {
        1911 goog.array.forEach(this.children_, function(child) {
        1912 if (child instanceof webdriver.promise.Frame_) {
        1913 child.cancelRemainingTasks(error);
        1914 } else {
        1915 // None of the previously registered listeners should be notified that
        1916 // the task is being canceled, however, we need at least one errback
        1917 // to prevent the cancellation from bubbling up.
        1918 child.removeAll();
        1919 child.thenCatch(goog.nullFunction);
        1920 child.cancel(error);
        1921 }
        1922 });
        1923};
        1924
        1925
        1926/**
        1927 * @return {webdriver.promise.Task_} The task currently executing
        1928 * within this frame, if any.
        1929 */
        1930webdriver.promise.Frame_.prototype.getPendingTask = function() {
        1931 return this.pendingTask_;
        1932};
        1933
        1934
        1935/**
        1936 * @param {webdriver.promise.Task_} task The task currently
        1937 * executing within this frame, if any.
        1938 */
        1939webdriver.promise.Frame_.prototype.setPendingTask = function(task) {
        1940 this.pendingTask_ = task;
        1941};
        1942
        1943
        1944/** Locks this frame. */
        1945webdriver.promise.Frame_.prototype.lockFrame = function() {
        1946 this.isLocked_ = true;
        1947};
        1948
        1949
        1950/**
        1951 * Adds a new node to this frame.
        1952 * @param {!(webdriver.promise.Frame_|webdriver.promise.Task_)} node
        1953 * The node to insert.
        1954 */
        1955webdriver.promise.Frame_.prototype.addChild = function(node) {
        1956 if (this.lastInsertedChild_ &&
        1957 this.lastInsertedChild_ instanceof webdriver.promise.Frame_ &&
        1958 !this.lastInsertedChild_.isLocked_) {
        1959 this.lastInsertedChild_.addChild(node);
        1960 return;
        1961 }
        1962
        1963 node.setParent(this);
        1964
        1965 if (this.isActive_ && node instanceof webdriver.promise.Frame_) {
        1966 var index = 0;
        1967 if (this.lastInsertedChild_ instanceof
        1968 webdriver.promise.Frame_) {
        1969 index = goog.array.indexOf(this.children_, this.lastInsertedChild_) + 1;
        1970 }
        1971 goog.array.insertAt(this.children_, node, index);
        1972 this.lastInsertedChild_ = node;
        1973 return;
        1974 }
        1975
        1976 this.lastInsertedChild_ = node;
        1977 this.children_.push(node);
        1978};
        1979
        1980
        1981/**
        1982 * @return {(webdriver.promise.Frame_|webdriver.promise.Task_)} This frame's
        1983 * fist child.
        1984 */
        1985webdriver.promise.Frame_.prototype.getFirstChild = function() {
        1986 this.isActive_ = true;
        1987 this.lastInsertedChild_ = null;
        1988 return this.children_[0];
        1989};
        1990
        1991
        1992/**
        1993 * Removes a child from this frame.
        1994 * @param {!(webdriver.promise.Frame_|webdriver.promise.Task_)} child
        1995 * The child to remove.
        1996 */
        1997webdriver.promise.Frame_.prototype.removeChild = function(child) {
        1998 var index = goog.array.indexOf(this.children_, child);
        1999 child.setParent(null);
        2000 goog.array.removeAt(this.children_, index);
        2001 if (this.lastInsertedChild_ === child) {
        2002 this.lastInsertedChild_ = null;
        2003 }
        2004};
        2005
        2006
        2007/** @override */
        2008webdriver.promise.Frame_.prototype.toString = function() {
        2009 return '[' + goog.array.map(this.children_, function(child) {
        2010 return child.toString();
        2011 }).join(', ') + ']';
        2012};
        2013
        2014
        2015
        2016/**
        2017 * A task to be executed by a {@link webdriver.promise.ControlFlow}.
        2018 *
        2019 * @param {!webdriver.promise.ControlFlow} flow The flow this instances belongs
        2020 * to.
        2021 * @param {!Function} fn The function to call when the task executes. If it
        2022 * returns a {@code webdriver.promise.Promise}, the flow will wait
        2023 * for it to be resolved before starting the next task.
        2024 * @param {string} description A description of the task for debugging.
        2025 * @param {!webdriver.stacktrace.Snapshot} snapshot A snapshot of the stack
        2026 * when this task was scheduled.
        2027 * @constructor
        2028 * @extends {webdriver.promise.Node_}
        2029 * @private
        2030 */
        2031webdriver.promise.Task_ = function(flow, fn, description, snapshot) {
        2032 webdriver.promise.Node_.call(this, flow);
        2033
        2034 /**
        2035 * Executes this task.
        2036 * @type {!Function}
        2037 */
        2038 this.execute = fn;
        2039
        2040 /** @private {string} */
        2041 this.description_ = description;
        2042
        2043 /** @private {!webdriver.stacktrace.Snapshot} */
        2044 this.snapshot_ = snapshot;
        2045};
        2046goog.inherits(webdriver.promise.Task_, webdriver.promise.Node_);
        2047
        2048
        2049/** @return {string} This task's description. */
        2050webdriver.promise.Task_.prototype.getDescription = function() {
        2051 return this.description_;
        2052};
        2053
        2054
        2055/** @override */
        2056webdriver.promise.Task_.prototype.toString = function() {
        2057 var stack = this.snapshot_.getStacktrace();
        2058 var ret = this.description_;
        2059 if (stack.length) {
        2060 if (this.description_) {
        2061 ret += '\n';
        2062 }
        2063 ret += stack.join('\n');
        2064 }
        2065 return ret;
        2066};
        2067
        2068
        2069
        2070/**
        2071 * Special error used to signal when a task is canceled because a previous
        2072 * task in the same frame failed.
        2073 * @param {*} err The error that caused the task cancellation.
        2074 * @constructor
        2075 * @extends {goog.debug.Error}
        2076 * @private
        2077 */
        2078webdriver.promise.CanceledTaskError_ = function(err) {
        2079 goog.base(this, 'Task discarded due to a previous task failure: ' + err);
        2080};
        2081goog.inherits(webdriver.promise.CanceledTaskError_, goog.debug.Error);
        2082
        2083
        2084/** @override */
        2085webdriver.promise.CanceledTaskError_.prototype.name = 'CanceledTaskError';
        2086
        2087
        2088
        2089/**
        2090 * The default flow to use if no others are active.
        2091 * @private {!webdriver.promise.ControlFlow}
        2092 */
        2093webdriver.promise.defaultFlow_ = new webdriver.promise.ControlFlow();
        2094
        2095
        2096/**
        2097 * A stack of active control flows, with the top of the stack used to schedule
        2098 * commands. When there are multiple flows on the stack, the flow at index N
        2099 * represents a callback triggered within a task owned by the flow at index
        2100 * N-1.
        2101 * @private {!Array.<!webdriver.promise.ControlFlow>}
        2102 */
        2103webdriver.promise.activeFlows_ = [];
        2104
        2105
        2106/**
        2107 * Changes the default flow to use when no others are active.
        2108 * @param {!webdriver.promise.ControlFlow} flow The new default flow.
        2109 * @throws {Error} If the default flow is not currently active.
        2110 */
        2111webdriver.promise.setDefaultFlow = function(flow) {
        2112 if (webdriver.promise.activeFlows_.length) {
        2113 throw Error('You may only change the default flow while it is active');
        2114 }
        2115 webdriver.promise.defaultFlow_ = flow;
        2116};
        2117
        2118
        2119/**
        2120 * @return {!webdriver.promise.ControlFlow} The currently active control flow.
        2121 */
        2122webdriver.promise.controlFlow = function() {
        2123 return /** @type {!webdriver.promise.ControlFlow} */ (
        2124 goog.array.peek(webdriver.promise.activeFlows_) ||
        2125 webdriver.promise.defaultFlow_);
        2126};
        2127
        2128
        2129/**
        2130 * @param {!webdriver.promise.ControlFlow} flow The new flow.
        2131 * @private
        2132 */
        2133webdriver.promise.pushFlow_ = function(flow) {
        2134 webdriver.promise.activeFlows_.push(flow);
        2135};
        2136
        2137
        2138/** @private */
        2139webdriver.promise.popFlow_ = function() {
        2140 webdriver.promise.activeFlows_.pop();
        2141};
        2142
        2143
        2144/**
        2145 * Creates a new control flow. The provided callback will be invoked as the
        2146 * first task within the new flow, with the flow as its sole argument. Returns
        2147 * a promise that resolves to the callback result.
        2148 * @param {function(!webdriver.promise.ControlFlow)} callback The entry point
        2149 * to the newly created flow.
        2150 * @return {!webdriver.promise.Promise} A promise that resolves to the callback
        2151 * result.
        2152 */
        2153webdriver.promise.createFlow = function(callback) {
        2154 var flow = new webdriver.promise.ControlFlow(
        2155 webdriver.promise.defaultFlow_.timer);
        2156 return flow.execute(function() {
        2157 return callback(flow);
        2158 });
        2159};
        2160
        2161
        2162/**
        2163 * Tests is a function is a generator.
        2164 * @param {!Function} fn The function to test.
        2165 * @return {boolean} Whether the function is a generator.
        2166 */
        2167webdriver.promise.isGenerator = function(fn) {
        2168 return fn.constructor.name === 'GeneratorFunction';
        2169};
        2170
        2171
        2172/**
        2173 * Consumes a {@code GeneratorFunction}. Each time the generator yields a
        2174 * promise, this function will wait for it to be fulfilled before feeding the
        2175 * fulfilled value back into {@code next}. Likewise, if a yielded promise is
        2176 * rejected, the rejection error will be passed to {@code throw}.
        2177 *
        2178 * <p>Example 1: the Fibonacci Sequence.
        2179 * <pre><code>
        2180 * webdriver.promise.consume(function* fibonacci() {
        2181 * var n1 = 1, n2 = 1;
        2182 * for (var i = 0; i < 4; ++i) {
        2183 * var tmp = yield n1 + n2;
        2184 * n1 = n2;
        2185 * n2 = tmp;
        2186 * }
        2187 * return n1 + n2;
        2188 * }).then(function(result) {
        2189 * console.log(result); // 13
        2190 * });
        2191 * </code></pre>
        2192 *
        2193 * <p>Example 2: a generator that throws.
        2194 * <pre><code>
        2195 * webdriver.promise.consume(function* () {
        2196 * yield webdriver.promise.delayed(250).then(function() {
        2197 * throw Error('boom');
        2198 * });
        2199 * }).thenCatch(function(e) {
        2200 * console.log(e.toString()); // Error: boom
        2201 * });
        2202 * </code></pre>
        2203 *
        2204 * @param {!Function} generatorFn The generator function to execute.
        2205 * @param {Object=} opt_self The object to use as "this" when invoking the
        2206 * initial generator.
        2207 * @param {...*} var_args Any arguments to pass to the initial generator.
        2208 * @return {!webdriver.promise.Promise.<?>} A promise that will resolve to the
        2209 * generator's final result.
        2210 * @throws {TypeError} If the given function is not a generator.
        2211 */
        2212webdriver.promise.consume = function(generatorFn, opt_self, var_args) {
        2213 if (!webdriver.promise.isGenerator(generatorFn)) {
        2214 throw TypeError('Input is not a GeneratorFunction: ' +
        2215 generatorFn.constructor.name);
        2216 }
        2217
        2218 var deferred = webdriver.promise.defer();
        2219 var generator = generatorFn.apply(opt_self, goog.array.slice(arguments, 2));
        2220 callNext();
        2221 return deferred.promise;
        2222
        2223 /** @param {*=} opt_value . */
        2224 function callNext(opt_value) {
        2225 pump(generator.next, opt_value);
        2226 }
        2227
        2228 /** @param {*=} opt_error . */
        2229 function callThrow(opt_error) {
        2230 // Dictionary lookup required because Closure compiler's built-in
        2231 // externs does not include GeneratorFunction.prototype.throw.
        2232 pump(generator['throw'], opt_error);
        2233 }
        2234
        2235 function pump(fn, opt_arg) {
        2236 if (!deferred.isPending()) {
        2237 return; // Defererd was cancelled; silently abort.
        2238 }
        2239
        2240 try {
        2241 var result = fn.call(generator, opt_arg);
        2242 } catch (ex) {
        2243 deferred.reject(ex);
        2244 return;
        2245 }
        2246
        2247 if (result.done) {
        2248 deferred.fulfill(result.value);
        2249 return;
        2250 }
        2251
        2252 webdriver.promise.asap(result.value, callNext, callThrow);
        2253 }
        2254};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/webdriver/session.js.src.html b/docs/api/javascript/source/lib/webdriver/session.js.src.html index bc919704bb7ff..467bd5e5fd494 100644 --- a/docs/api/javascript/source/lib/webdriver/session.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/session.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/stacktrace.js.src.html b/docs/api/javascript/source/lib/webdriver/stacktrace.js.src.html index a36330eb9be2a..031572226815b 100644 --- a/docs/api/javascript/source/lib/webdriver/stacktrace.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/stacktrace.js.src.html @@ -1 +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 +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 creates 2 submatches on the (optional) context and function name,
        430 * matching identifiers like 'foo.Bar.prototype.baz', 'Anonymous function',
        431 * 'eval code', and 'Global code'.
        432 * @private {string}
        433 * @const
        434 */
        435webdriver.stacktrace.CHAKRA_FUNCTION_CALL_PATTERN_ =
        436 '(?:(' + webdriver.stacktrace.IDENTIFIER_PATTERN_ +
        437 '(?:\\.' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + ')*)\\.)?' +
        438 '(' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + '(?:\\s+\\w+)*)';
        439
        440
        441/**
        442 * Regular expression for parsing on stack frame in Chakra (IE).
        443 * @private {!RegExp}
        444 * @const
        445 */
        446webdriver.stacktrace.CHAKRA_STACK_FRAME_REGEXP_ = new RegExp('^ at ' +
        447 webdriver.stacktrace.CHAKRA_FUNCTION_CALL_PATTERN_ +
        448 '\\s*(?:\\((.*)\\))$');
        449
        450
        451/**
        452 * Placeholder for an unparsable frame in a stack trace generated by
        453 * {@link goog.testing.stacktrace}.
        454 * @private {string}
        455 * @const
        456 */
        457webdriver.stacktrace.UNKNOWN_CLOSURE_FRAME_ = '> (unknown)';
        458
        459
        460/**
        461 * Representation of an anonymous frame in a stack trace generated by
        462 * {@link goog.testing.stacktrace}.
        463 * @private {string}
        464 * @const
        465 */
        466webdriver.stacktrace.ANONYMOUS_CLOSURE_FRAME_ = '> anonymous';
        467
        468
        469/**
        470 * Pattern for a function call in a Closure stack trace. Creates three optional
        471 * submatches: the context, function name, and alias.
        472 * @private {string}
        473 * @const
        474 */
        475webdriver.stacktrace.CLOSURE_FUNCTION_CALL_PATTERN_ =
        476 webdriver.stacktrace.QUALIFIED_NAME_PATTERN_ +
        477 '(?:\\(.*\\))?' + // Ignore arguments if present.
        478 webdriver.stacktrace.V8_ALIAS_PATTERN_;
        479
        480
        481/**
        482 * Regular expression for parsing a stack frame generated by Closure's
        483 * {@link goog.testing.stacktrace}.
        484 * @private {!RegExp}
        485 * @const
        486 */
        487webdriver.stacktrace.CLOSURE_STACK_FRAME_REGEXP_ = new RegExp('^> ' +
        488 '(?:' + webdriver.stacktrace.CLOSURE_FUNCTION_CALL_PATTERN_ +
        489 '(?: at )?)?' +
        490 '(?:(.*:\\d+:\\d+)|' + webdriver.stacktrace.URL_PATTERN_ + ')?$');
        491
        492
        493/**
        494 * Parses one stack frame.
        495 * @param {string} frameStr The stack frame as string.
        496 * @return {webdriver.stacktrace.Frame} Stack frame object or null if the
        497 * parsing failed.
        498 * @private
        499 */
        500webdriver.stacktrace.parseStackFrame_ = function(frameStr) {
        501 var m = frameStr.match(webdriver.stacktrace.V8_STACK_FRAME_REGEXP_);
        502 if (m) {
        503 return new webdriver.stacktrace.Frame(
        504 m[1] || m[2], m[3], m[4], m[5] || m[6]);
        505 }
        506
        507 if (frameStr.length >
        508 webdriver.stacktrace.MAX_FIREFOX_FRAMESTRING_LENGTH_) {
        509 return webdriver.stacktrace.parseLongFirefoxFrame_(frameStr);
        510 }
        511
        512 m = frameStr.match(webdriver.stacktrace.FIREFOX_STACK_FRAME_REGEXP_);
        513 if (m) {
        514 return new webdriver.stacktrace.Frame('', m[1], '', m[2]);
        515 }
        516
        517 m = frameStr.match(webdriver.stacktrace.OPERA_STACK_FRAME_REGEXP_);
        518 if (m) {
        519 return new webdriver.stacktrace.Frame(m[2], m[1] || m[3], '', m[4]);
        520 }
        521
        522 m = frameStr.match(webdriver.stacktrace.CHAKRA_STACK_FRAME_REGEXP_);
        523 if (m) {
        524 return new webdriver.stacktrace.Frame(m[1], m[2], '', m[3]);
        525 }
        526
        527 if (frameStr == webdriver.stacktrace.UNKNOWN_CLOSURE_FRAME_ ||
        528 frameStr == webdriver.stacktrace.ANONYMOUS_CLOSURE_FRAME_) {
        529 return webdriver.stacktrace.ANONYMOUS_FRAME_;
        530 }
        531
        532 m = frameStr.match(webdriver.stacktrace.CLOSURE_STACK_FRAME_REGEXP_);
        533 if (m) {
        534 return new webdriver.stacktrace.Frame(m[1], m[2], m[3], m[4] || m[5]);
        535 }
        536
        537 return null;
        538};
        539
        540
        541/**
        542 * Parses a long firefox stack frame.
        543 * @param {string} frameStr The stack frame as string.
        544 * @return {!webdriver.stacktrace.Frame} Stack frame object.
        545 * @private
        546 */
        547webdriver.stacktrace.parseLongFirefoxFrame_ = function(frameStr) {
        548 var firstParen = frameStr.indexOf('(');
        549 var lastAmpersand = frameStr.lastIndexOf('@');
        550 var lastColon = frameStr.lastIndexOf(':');
        551 var functionName = '';
        552 if ((firstParen >= 0) && (firstParen < lastAmpersand)) {
        553 functionName = frameStr.substring(0, firstParen);
        554 }
        555 var loc = '';
        556 if ((lastAmpersand >= 0) && (lastAmpersand + 1 < lastColon)) {
        557 loc = frameStr.substring(lastAmpersand + 1);
        558 }
        559 return new webdriver.stacktrace.Frame('', functionName, '', loc);
        560};
        561
        562
        563/**
        564 * Get an error's stack trace with the error string trimmed.
        565 * V8 prepends the string representation of an error to its stack trace.
        566 * This function trims the string so that the stack trace can be parsed
        567 * consistently with the other JS engines.
        568 * @param {(Error|goog.testing.JsUnitException)} error The error.
        569 * @return {string} The stack trace string.
        570 * @private
        571 */
        572webdriver.stacktrace.getStack_ = function(error) {
        573 if (!error) {
        574 return '';
        575 }
        576 var stack = error.stack || error.stackTrace || '';
        577 var errorStr = error + '\n';
        578 if (goog.string.startsWith(stack, errorStr)) {
        579 stack = stack.substring(errorStr.length);
        580 }
        581 return stack;
        582};
        583
        584
        585/**
        586 * Formats an error's stack trace.
        587 * @param {!(Error|goog.testing.JsUnitException)} error The error to format.
        588 * @return {!(Error|goog.testing.JsUnitException)} The formatted error.
        589 */
        590webdriver.stacktrace.format = function(error) {
        591 var stack = webdriver.stacktrace.getStack_(error);
        592 var frames = webdriver.stacktrace.parse_(stack);
        593
        594 // Older versions of IE simply return [object Error] for toString(), so
        595 // only use that as a last resort.
        596 var errorStr = '';
        597 if (error.message) {
        598 errorStr = (error.name ? error.name + ': ' : '') + error.message;
        599 } else {
        600 errorStr = error.toString();
        601 }
        602
        603 // Ensure the error is in the V8 style with the error's string representation
        604 // prepended to the stack.
        605 error.stack = errorStr + '\n' + frames.join('\n');
        606 return error;
        607};
        608
        609
        610/**
        611 * Parses an Error object's stack trace.
        612 * @param {string} stack The stack trace.
        613 * @return {!Array.<!webdriver.stacktrace.Frame>} Stack frames. The
        614 * unrecognized frames will be nulled out.
        615 * @private
        616 */
        617webdriver.stacktrace.parse_ = function(stack) {
        618 if (!stack) {
        619 return [];
        620 }
        621
        622 var lines = stack.
        623 replace(/\s*$/, '').
        624 split('\n');
        625 var frames = [];
        626 for (var i = 0; i < lines.length; i++) {
        627 var frame = webdriver.stacktrace.parseStackFrame_(lines[i]);
        628 // The first two frames will be:
        629 // webdriver.stacktrace.Snapshot()
        630 // webdriver.stacktrace.get()
        631 // In the case of Opera, sometimes an extra frame is injected in the next
        632 // frame with a reported line number of zero. The next line detects that
        633 // case and skips that frame.
        634 if (!(goog.userAgent.OPERA && i == 2 && frame.getLine() == 0)) {
        635 frames.push(frame || webdriver.stacktrace.ANONYMOUS_FRAME_);
        636 }
        637 }
        638 return frames;
        639};
        640
        641
        642/**
        643 * Gets the native stack trace if available otherwise follows the call chain.
        644 * The generated trace will exclude all frames up to and including the call to
        645 * this function.
        646 * @return {!Array.<!webdriver.stacktrace.Frame>} The frames of the stack trace.
        647 */
        648webdriver.stacktrace.get = function() {
        649 return new webdriver.stacktrace.Snapshot(1).getStacktrace();
        650};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/webdriver/testing/asserts.js.src.html b/docs/api/javascript/source/lib/webdriver/testing/asserts.js.src.html index 5d37bbdaddec9..e1a80e28e20f0 100644 --- a/docs/api/javascript/source/lib/webdriver/testing/asserts.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/testing/asserts.js.src.html @@ -1 +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 +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/docs/api/javascript/source/lib/webdriver/testing/testcase.js.src.html b/docs/api/javascript/source/lib/webdriver/testing/testcase.js.src.html new file mode 100644 index 0000000000000..334dcf7241e23 --- /dev/null +++ b/docs/api/javascript/source/lib/webdriver/testing/testcase.js.src.html @@ -0,0 +1 @@ +testcase.js

        lib/webdriver/testing/testcase.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 special test case that runs each test inside of a
        17 * {@code webdriver.Application}. This allows each phase to schedule
        18 * asynchronous actions that run to completion before the next phase of the
        19 * test.
        20 *
        21 * This file requires the global {@code G_testRunner} to be initialized before
        22 * use. This can be accomplished by also importing
        23 * {@link webdriver.testing.jsunit}. This namespace is not required by default
        24 * to improve interoperability with other namespaces that may initialize
        25 * G_testRunner.
        26 */
        27
        28goog.provide('webdriver.testing.TestCase');
        29
        30goog.require('goog.testing.TestCase');
        31goog.require('webdriver.promise.ControlFlow');
        32/** @suppress {extraRequire} Imported for user convenience. */
        33goog.require('webdriver.testing.asserts');
        34
        35
        36
        37/**
        38 * Constructs a test case that synchronizes each test case with the singleton
        39 * {@code webdriver.promise.ControlFlow}.
        40 *
        41 * @param {!webdriver.testing.Client} client The test client to use for
        42 * reporting test results.
        43 * @param {string=} opt_name The name of the test case, defaults to
        44 * 'Untitled Test Case'.
        45 * @constructor
        46 * @extends {goog.testing.TestCase}
        47 */
        48webdriver.testing.TestCase = function(client, opt_name) {
        49 goog.base(this, opt_name);
        50
        51 /** @private {!webdriver.testing.Client} */
        52 this.client_ = client;
        53};
        54goog.inherits(webdriver.testing.TestCase, goog.testing.TestCase);
        55
        56
        57/**
        58 * Executes the next test inside its own {@code webdriver.Application}.
        59 * @override
        60 */
        61webdriver.testing.TestCase.prototype.cycleTests = function() {
        62 var test = this.next();
        63 if (!test) {
        64 this.finalize();
        65 return;
        66 }
        67
        68 goog.testing.TestCase.currentTestName = test.name;
        69 this.result_.runCount++;
        70 this.log('Running test: ' + test.name);
        71 this.client_.sendTestStartedEvent(test.name);
        72
        73 var self = this;
        74 var hadError = false;
        75 var app = webdriver.promise.controlFlow();
        76
        77 this.runSingleTest_(test, onError).then(function() {
        78 hadError || self.doSuccess(test);
        79 self.timeout(function() {
        80 self.cycleTests();
        81 }, 100);
        82 });
        83
        84 function onError(e) {
        85 hadError = true;
        86 self.doError(test, app.annotateError(e));
        87 // Note: result_ is a @protected field but still uses the trailing
        88 // underscore.
        89 var err = self.result_.errors[self.result_.errors.length - 1];
        90 self.client_.sendErrorEvent(err.toString());
        91 }
        92};
        93
        94
        95/** @override */
        96webdriver.testing.TestCase.prototype.logError = function(name, opt_e) {
        97 var errMsg = null;
        98 var stack = null;
        99 if (opt_e) {
        100 this.log(opt_e);
        101 if (goog.isString(opt_e)) {
        102 errMsg = opt_e;
        103 } else {
        104 // In case someone calls this function directly, make sure we have a
        105 // properly annotated error.
        106 webdriver.promise.controlFlow().annotateError(opt_e);
        107 errMsg = opt_e.toString();
        108 stack = opt_e.stack.substring(errMsg.length + 1);
        109 }
        110 } else {
        111 errMsg = 'An unknown error occurred';
        112 }
        113 var err = new goog.testing.TestCase.Error(name, errMsg, stack);
        114
        115 // Avoid double logging.
        116 if (!opt_e || !opt_e['isJsUnitException'] ||
        117 !opt_e['loggedJsUnitException']) {
        118 this.saveMessage(err.toString());
        119 }
        120
        121 if (opt_e && opt_e['isJsUnitException']) {
        122 opt_e['loggedJsUnitException'] = true;
        123 }
        124
        125 return err;
        126};
        127
        128
        129/**
        130 * Executes a single test, scheduling each phase with the global application.
        131 * Each phase will wait for the application to go idle before moving on to the
        132 * next test phase. This function models the follow basic test flow:
        133 *
        134 * try {
        135 * this.setUp.call(test.scope);
        136 * test.ref.call(test.scope);
        137 * } catch (ex) {
        138 * onError(ex);
        139 * } finally {
        140 * try {
        141 * this.tearDown.call(test.scope);
        142 * } catch (e) {
        143 * onError(e);
        144 * }
        145 * }
        146 *
        147 * @param {!goog.testing.TestCase.Test} test The test to run.
        148 * @param {function(*)} onError The function to call each time an error is
        149 * detected.
        150 * @return {!webdriver.promise.Promise} A promise that will be resolved when the
        151 * test has finished running.
        152 * @private
        153 */
        154webdriver.testing.TestCase.prototype.runSingleTest_ = function(test, onError) {
        155 var flow = webdriver.promise.controlFlow();
        156 flow.clearHistory();
        157
        158 return execute(test.name + '.setUp()', this.setUp)().
        159 then(execute(test.name + '()', test.ref)).
        160 thenCatch(onError).
        161 then(execute(test.name + '.tearDown()', this.tearDown)).
        162 thenCatch(onError);
        163
        164 function execute(description, fn) {
        165 return function() {
        166 return flow.execute(goog.bind(fn, test.scope), description);
        167 }
        168 }
        169};
        \ No newline at end of file diff --git a/docs/api/javascript/source/lib/webdriver/webdriver.js.src.html b/docs/api/javascript/source/lib/webdriver/webdriver.js.src.html index d0419665c50fe..db568a6bf37c2 100644 --- a/docs/api/javascript/source/lib/webdriver/webdriver.js.src.html +++ b/docs/api/javascript/source/lib/webdriver/webdriver.js.src.html @@ -1 +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 +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.AlertPromise');
        21goog.provide('webdriver.UnhandledAlertError');
        22goog.provide('webdriver.WebDriver');
        23goog.provide('webdriver.WebElement');
        24goog.provide('webdriver.WebElementPromise');
        25
        26goog.require('bot.Error');
        27goog.require('bot.ErrorCode');
        28goog.require('bot.response');
        29goog.require('goog.array');
        30goog.require('goog.object');
        31goog.require('webdriver.ActionSequence');
        32goog.require('webdriver.Command');
        33goog.require('webdriver.CommandName');
        34goog.require('webdriver.Key');
        35goog.require('webdriver.Locator');
        36goog.require('webdriver.Session');
        37goog.require('webdriver.logging');
        38goog.require('webdriver.promise');
        39
        40
        41//////////////////////////////////////////////////////////////////////////////
        42//
        43// webdriver.WebDriver
        44//
        45//////////////////////////////////////////////////////////////////////////////
        46
        47
        48
        49/**
        50 * Creates a new WebDriver client, which provides control over a browser.
        51 *
        52 * Every WebDriver command returns a {@code webdriver.promise.Promise} that
        53 * represents the result of that command. Callbacks may be registered on this
        54 * object to manipulate the command result or catch an expected error. Any
        55 * commands scheduled with a callback are considered sub-commands and will
        56 * execute before the next command in the current frame. For example:
        57 * <pre><code>
        58 * var message = [];
        59 * driver.call(message.push, message, 'a').then(function() {
        60 * driver.call(message.push, message, 'b');
        61 * });
        62 * driver.call(message.push, message, 'c');
        63 * driver.call(function() {
        64 * alert('message is abc? ' + (message.join('') == 'abc'));
        65 * });
        66 * </code></pre>
        67 *
        68 * @param {!(webdriver.Session|webdriver.promise.Promise)} session Either a
        69 * known session or a promise that will be resolved to a session.
        70 * @param {!webdriver.CommandExecutor} executor The executor to use when
        71 * sending commands to the browser.
        72 * @param {webdriver.promise.ControlFlow=} opt_flow The flow to
        73 * schedule commands through. Defaults to the active flow object.
        74 * @constructor
        75 */
        76webdriver.WebDriver = function(session, executor, opt_flow) {
        77
        78 /** @private {!(webdriver.Session|webdriver.promise.Promise)} */
        79 this.session_ = session;
        80
        81 /** @private {!webdriver.CommandExecutor} */
        82 this.executor_ = executor;
        83
        84 /** @private {!webdriver.promise.ControlFlow} */
        85 this.flow_ = opt_flow || webdriver.promise.controlFlow();
        86};
        87
        88
        89/**
        90 * Creates a new WebDriver client for an existing session.
        91 * @param {!webdriver.CommandExecutor} executor Command executor to use when
        92 * querying for session details.
        93 * @param {string} sessionId ID of the session to attach to.
        94 * @param {webdriver.promise.ControlFlow=} opt_flow The control flow all driver
        95 * commands should execute under. Defaults to the
        96 * {@link webdriver.promise.controlFlow() currently active} control flow.
        97 * @return {!webdriver.WebDriver} A new client for the specified session.
        98 */
        99webdriver.WebDriver.attachToSession = function(executor, sessionId, opt_flow) {
        100 return webdriver.WebDriver.acquireSession_(executor,
        101 new webdriver.Command(webdriver.CommandName.DESCRIBE_SESSION).
        102 setParameter('sessionId', sessionId),
        103 'WebDriver.attachToSession()',
        104 opt_flow);
        105};
        106
        107
        108/**
        109 * Creates a new WebDriver session.
        110 * @param {!webdriver.CommandExecutor} executor The executor to create the new
        111 * session with.
        112 * @param {!webdriver.Capabilities} desiredCapabilities The desired
        113 * capabilities for the new session.
        114 * @param {webdriver.promise.ControlFlow=} opt_flow The control flow all driver
        115 * commands should execute under, including the initial session creation.
        116 * Defaults to the {@link webdriver.promise.controlFlow() currently active}
        117 * control flow.
        118 * @return {!webdriver.WebDriver} The driver for the newly created session.
        119 */
        120webdriver.WebDriver.createSession = function(
        121 executor, desiredCapabilities, opt_flow) {
        122 return webdriver.WebDriver.acquireSession_(executor,
        123 new webdriver.Command(webdriver.CommandName.NEW_SESSION).
        124 setParameter('desiredCapabilities', desiredCapabilities),
        125 'WebDriver.createSession()',
        126 opt_flow);
        127};
        128
        129
        130/**
        131 * Sends a command to the server that is expected to return the details for a
        132 * {@link webdriver.Session}. This may either be an existing session, or a
        133 * newly created one.
        134 * @param {!webdriver.CommandExecutor} executor Command executor to use when
        135 * querying for session details.
        136 * @param {!webdriver.Command} command The command to send to fetch the session
        137 * details.
        138 * @param {string} description A descriptive debug label for this action.
        139 * @param {webdriver.promise.ControlFlow=} opt_flow The control flow all driver
        140 * commands should execute under. Defaults to the
        141 * {@link webdriver.promise.controlFlow() currently active} control flow.
        142 * @return {!webdriver.WebDriver} A new WebDriver client for the session.
        143 * @private
        144 */
        145webdriver.WebDriver.acquireSession_ = function(
        146 executor, command, description, opt_flow) {
        147 var flow = opt_flow || webdriver.promise.controlFlow();
        148 var session = flow.execute(function() {
        149 return webdriver.WebDriver.executeCommand_(executor, command).
        150 then(function(response) {
        151 bot.response.checkResponse(response);
        152 return new webdriver.Session(response['sessionId'],
        153 response['value']);
        154 });
        155 }, description);
        156 return new webdriver.WebDriver(session, executor, flow);
        157};
        158
        159
        160/**
        161 * Converts an object to its JSON representation in the WebDriver wire protocol.
        162 * When converting values of type object, the following steps will be taken:
        163 * <ol>
        164 * <li>if the object is a WebElement, the return value will be the element's
        165 * server ID</li>
        166 * <li>if the object provides a "toJSON" function, the return value of this
        167 * function will be returned</li>
        168 * <li>otherwise, the value of each key will be recursively converted according
        169 * to the rules above.</li>
        170 * </ol>
        171 *
        172 * @param {*} obj The object to convert.
        173 * @return {!webdriver.promise.Promise.<?>} A promise that will resolve to the
        174 * input value's JSON representation.
        175 * @private
        176 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol
        177 */
        178webdriver.WebDriver.toWireValue_ = function(obj) {
        179 if (webdriver.promise.isPromise(obj)) {
        180 return obj.then(webdriver.WebDriver.toWireValue_);
        181 }
        182 switch (goog.typeOf(obj)) {
        183 case 'array':
        184 return webdriver.promise.all(
        185 goog.array.map(/** @type {!Array} */ (obj),
        186 webdriver.WebDriver.toWireValue_));
        187 case 'object':
        188 if (obj instanceof webdriver.WebElement) {
        189 return obj.getId();
        190 }
        191 if (goog.isFunction(obj.toJSON)) {
        192 return webdriver.promise.fulfilled(obj.toJSON());
        193 }
        194 if (goog.isNumber(obj.nodeType) && goog.isString(obj.nodeName)) {
        195 throw Error([
        196 'Invalid argument type: ', obj.nodeName, '(', obj.nodeType, ')'
        197 ].join(''));
        198 }
        199 return webdriver.promise.fullyResolved(
        200 goog.object.map(/** @type {!Object} */ (obj),
        201 webdriver.WebDriver.toWireValue_));
        202 case 'function':
        203 return webdriver.promise.fulfilled('' + obj);
        204 case 'undefined':
        205 return webdriver.promise.fulfilled(null);
        206 default:
        207 return webdriver.promise.fulfilled(obj);
        208 }
        209};
        210
        211
        212/**
        213 * Converts a value from its JSON representation according to the WebDriver wire
        214 * protocol. Any JSON object containing a
        215 * {@code webdriver.WebElement.ELEMENT_KEY} key will be decoded to a
        216 * {@code webdriver.WebElement} object. All other values will be passed through
        217 * as is.
        218 * @param {!webdriver.WebDriver} driver The driver instance to use as the
        219 * parent of any unwrapped {@code webdriver.WebElement} values.
        220 * @param {*} value The value to convert.
        221 * @return {*} The converted value.
        222 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol
        223 * @private
        224 */
        225webdriver.WebDriver.fromWireValue_ = function(driver, value) {
        226 if (goog.isArray(value)) {
        227 value = goog.array.map(/**@type {goog.array.ArrayLike}*/ (value),
        228 goog.partial(webdriver.WebDriver.fromWireValue_, driver));
        229 } else if (value && goog.isObject(value) && !goog.isFunction(value)) {
        230 if (webdriver.WebElement.ELEMENT_KEY in value) {
        231 value = new webdriver.WebElement(driver, value);
        232 } else {
        233 value = goog.object.map(/**@type {!Object}*/ (value),
        234 goog.partial(webdriver.WebDriver.fromWireValue_, driver));
        235 }
        236 }
        237 return value;
        238};
        239
        240
        241/**
        242 * Translates a command to its wire-protocol representation before passing it
        243 * to the given {@code executor} for execution.
        244 * @param {!webdriver.CommandExecutor} executor The executor to use.
        245 * @param {!webdriver.Command} command The command to execute.
        246 * @return {!webdriver.promise.Promise} A promise that will resolve with the
        247 * command response.
        248 * @private
        249 */
        250webdriver.WebDriver.executeCommand_ = function(executor, command) {
        251 return webdriver.WebDriver.toWireValue_(command.getParameters()).
        252 then(function(parameters) {
        253 command.setParameters(parameters);
        254 return webdriver.promise.checkedNodeCall(
        255 goog.bind(executor.execute, executor, command));
        256 });
        257};
        258
        259
        260/**
        261 * @return {!webdriver.promise.ControlFlow} The control flow used by this
        262 * instance.
        263 */
        264webdriver.WebDriver.prototype.controlFlow = function() {
        265 return this.flow_;
        266};
        267
        268
        269/**
        270 * Schedules a {@code webdriver.Command} to be executed by this driver's
        271 * {@code webdriver.CommandExecutor}.
        272 * @param {!webdriver.Command} command The command to schedule.
        273 * @param {string} description A description of the command for debugging.
        274 * @return {!webdriver.promise.Promise.<T>} A promise that will be resolved
        275 * with the command result.
        276 * @template T
        277 */
        278webdriver.WebDriver.prototype.schedule = function(command, description) {
        279 var self = this;
        280
        281 checkHasNotQuit();
        282 command.setParameter('sessionId', this.session_);
        283
        284 // If any of the command parameters are rejected promises, those
        285 // rejections may be reported as unhandled before the control flow
        286 // attempts to execute the command. To ensure parameters errors
        287 // propagate through the command itself, we resolve all of the
        288 // command parameters now, but suppress any errors until the ControlFlow
        289 // actually executes the command. This addresses scenarios like catching
        290 // an element not found error in:
        291 //
        292 // driver.findElement(By.id('foo')).click().thenCatch(function(e) {
        293 // if (e.code === bot.ErrorCode.NO_SUCH_ELEMENT) {
        294 // // Do something.
        295 // }
        296 // });
        297 var prepCommand = webdriver.WebDriver.toWireValue_(command.getParameters());
        298 prepCommand.thenCatch(goog.nullFunction);
        299
        300 var flow = this.flow_;
        301 var executor = this.executor_;
        302 return flow.execute(function() {
        303 // A call to WebDriver.quit() may have been scheduled in the same event
        304 // loop as this |command|, which would prevent us from detecting that the
        305 // driver has quit above. Therefore, we need to make another quick check.
        306 // We still check above so we can fail as early as possible.
        307 checkHasNotQuit();
        308
        309 // Retrieve resolved command parameters; any previously suppressed errors
        310 // will now propagate up through the control flow as part of the command
        311 // execution.
        312 return prepCommand.then(function(parameters) {
        313 command.setParameters(parameters);
        314 return webdriver.promise.checkedNodeCall(
        315 goog.bind(executor.execute, executor, command));
        316 });
        317 }, description).then(function(response) {
        318 try {
        319 bot.response.checkResponse(response);
        320 } catch (ex) {
        321 var value = response['value'];
        322 if (ex.code === bot.ErrorCode.UNEXPECTED_ALERT_OPEN) {
        323 var text = value && value['alert'] ? value['alert']['text'] : '';
        324 throw new webdriver.UnhandledAlertError(ex.message, text,
        325 new webdriver.Alert(self, text));
        326 }
        327 throw ex;
        328 }
        329 return webdriver.WebDriver.fromWireValue_(self, response['value']);
        330 });
        331
        332 function checkHasNotQuit() {
        333 if (!self.session_) {
        334 throw new Error('This driver instance does not have a valid session ID ' +
        335 '(did you call WebDriver.quit()?) and may no longer be ' +
        336 'used.');
        337 }
        338 }
        339};
        340
        341
        342// ----------------------------------------------------------------------------
        343// Client command functions:
        344// ----------------------------------------------------------------------------
        345
        346
        347/**
        348 * @return {!webdriver.promise.Promise.<!webdriver.Session>} A promise for this
        349 * client's session.
        350 */
        351webdriver.WebDriver.prototype.getSession = function() {
        352 return webdriver.promise.when(this.session_);
        353};
        354
        355
        356/**
        357 * @return {!webdriver.promise.Promise.<!webdriver.Capabilities>} A promise
        358 * that will resolve with the this instance's capabilities.
        359 */
        360webdriver.WebDriver.prototype.getCapabilities = function() {
        361 return webdriver.promise.when(this.session_, function(session) {
        362 return session.getCapabilities();
        363 });
        364};
        365
        366
        367/**
        368 * Schedules a command to quit the current session. After calling quit, this
        369 * instance will be invalidated and may no longer be used to issue commands
        370 * against the browser.
        371 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        372 * when the command has completed.
        373 */
        374webdriver.WebDriver.prototype.quit = function() {
        375 var result = this.schedule(
        376 new webdriver.Command(webdriver.CommandName.QUIT),
        377 'WebDriver.quit()');
        378 // Delete our session ID when the quit command finishes; this will allow us to
        379 // throw an error when attemnpting to use a driver post-quit.
        380 return result.thenFinally(goog.bind(function() {
        381 delete this.session_;
        382 }, this));
        383};
        384
        385
        386/**
        387 * Creates a new action sequence using this driver. The sequence will not be
        388 * scheduled for execution until {@link webdriver.ActionSequence#perform} is
        389 * called. Example:
        390 * <pre><code>
        391 * driver.actions().
        392 * mouseDown(element1).
        393 * mouseMove(element2).
        394 * mouseUp().
        395 * perform();
        396 * </code></pre>
        397 * @return {!webdriver.ActionSequence} A new action sequence for this instance.
        398 */
        399webdriver.WebDriver.prototype.actions = function() {
        400 return new webdriver.ActionSequence(this);
        401};
        402
        403
        404/**
        405 * Schedules a command to execute JavaScript in the context of the currently
        406 * selected frame or window. The script fragment will be executed as the body
        407 * of an anonymous function. If the script is provided as a function object,
        408 * that function will be converted to a string for injection into the target
        409 * window.
        410 *
        411 * Any arguments provided in addition to the script will be included as script
        412 * arguments and may be referenced using the {@code arguments} object.
        413 * Arguments may be a boolean, number, string, or {@code webdriver.WebElement}.
        414 * Arrays and objects may also be used as script arguments as long as each item
        415 * adheres to the types previously mentioned.
        416 *
        417 * The script may refer to any variables accessible from the current window.
        418 * Furthermore, the script will execute in the window's context, thus
        419 * {@code document} may be used to refer to the current document. Any local
        420 * variables will not be available once the script has finished executing,
        421 * though global variables will persist.
        422 *
        423 * If the script has a return value (i.e. if the script contains a return
        424 * statement), then the following steps will be taken for resolving this
        425 * functions return value:
        426 * <ul>
        427 * <li>For a HTML element, the value will resolve to a
        428 * {@code webdriver.WebElement}</li>
        429 * <li>Null and undefined return values will resolve to null</li>
        430 * <li>Booleans, numbers, and strings will resolve as is</li>
        431 * <li>Functions will resolve to their string representation</li>
        432 * <li>For arrays and objects, each member item will be converted according to
        433 * the rules above</li>
        434 * </ul>
        435 *
        436 * @param {!(string|Function)} script The script to execute.
        437 * @param {...*} var_args The arguments to pass to the script.
        438 * @return {!webdriver.promise.Promise.<T>} A promise that will resolve to the
        439 * scripts return value.
        440 * @template T
        441 */
        442webdriver.WebDriver.prototype.executeScript = function(script, var_args) {
        443 if (goog.isFunction(script)) {
        444 script = 'return (' + script + ').apply(null, arguments);';
        445 }
        446 return this.schedule(
        447 new webdriver.Command(webdriver.CommandName.EXECUTE_SCRIPT).
        448 setParameter('script', script).
        449 setParameter('args', goog.array.slice(arguments, 1)),
        450 'WebDriver.executeScript()');
        451};
        452
        453
        454/**
        455 * Schedules a command to execute asynchronous JavaScript in the context of the
        456 * currently selected frame or window. The script fragment will be executed as
        457 * the body of an anonymous function. If the script is provided as a function
        458 * object, that function will be converted to a string for injection into the
        459 * target window.
        460 *
        461 * Any arguments provided in addition to the script will be included as script
        462 * arguments and may be referenced using the {@code arguments} object.
        463 * Arguments may be a boolean, number, string, or {@code webdriver.WebElement}.
        464 * Arrays and objects may also be used as script arguments as long as each item
        465 * adheres to the types previously mentioned.
        466 *
        467 * Unlike executing synchronous JavaScript with
        468 * {@code webdriver.WebDriver.prototype.executeScript}, scripts executed with
        469 * this function must explicitly signal they are finished by invoking the
        470 * provided callback. This callback will always be injected into the
        471 * executed function as the last argument, and thus may be referenced with
        472 * {@code arguments[arguments.length - 1]}. The following steps will be taken
        473 * for resolving this functions return value against the first argument to the
        474 * script's callback function:
        475 * <ul>
        476 * <li>For a HTML element, the value will resolve to a
        477 * {@code webdriver.WebElement}</li>
        478 * <li>Null and undefined return values will resolve to null</li>
        479 * <li>Booleans, numbers, and strings will resolve as is</li>
        480 * <li>Functions will resolve to their string representation</li>
        481 * <li>For arrays and objects, each member item will be converted according to
        482 * the rules above</li>
        483 * </ul>
        484 *
        485 * Example #1: Performing a sleep that is synchronized with the currently
        486 * selected window:
        487 * <code><pre>
        488 * var start = new Date().getTime();
        489 * driver.executeAsyncScript(
        490 * 'window.setTimeout(arguments[arguments.length - 1], 500);').
        491 * then(function() {
        492 * console.log('Elapsed time: ' + (new Date().getTime() - start) + ' ms');
        493 * });
        494 * </pre></code>
        495 *
        496 * Example #2: Synchronizing a test with an AJAX application:
        497 * <code><pre>
        498 * var button = driver.findElement(By.id('compose-button'));
        499 * button.click();
        500 * driver.executeAsyncScript(
        501 * 'var callback = arguments[arguments.length - 1];' +
        502 * 'mailClient.getComposeWindowWidget().onload(callback);');
        503 * driver.switchTo().frame('composeWidget');
        504 * driver.findElement(By.id('to')).sendKeys('dog@example.com');
        505 * </pre></code>
        506 *
        507 * Example #3: Injecting a XMLHttpRequest and waiting for the result. In this
        508 * example, the inject script is specified with a function literal. When using
        509 * this format, the function is converted to a string for injection, so it
        510 * should not reference any symbols not defined in the scope of the page under
        511 * test.
        512 * <code><pre>
        513 * driver.executeAsyncScript(function() {
        514 * var callback = arguments[arguments.length - 1];
        515 * var xhr = new XMLHttpRequest();
        516 * xhr.open("GET", "/resource/data.json", true);
        517 * xhr.onreadystatechange = function() {
        518 * if (xhr.readyState == 4) {
        519 * callback(xhr.responseText);
        520 * }
        521 * }
        522 * xhr.send('');
        523 * }).then(function(str) {
        524 * console.log(JSON.parse(str)['food']);
        525 * });
        526 * </pre></code>
        527 *
        528 * @param {!(string|Function)} script The script to execute.
        529 * @param {...*} var_args The arguments to pass to the script.
        530 * @return {!webdriver.promise.Promise.<T>} A promise that will resolve to the
        531 * scripts return value.
        532 * @template T
        533 */
        534webdriver.WebDriver.prototype.executeAsyncScript = function(script, var_args) {
        535 if (goog.isFunction(script)) {
        536 script = 'return (' + script + ').apply(null, arguments);';
        537 }
        538 return this.schedule(
        539 new webdriver.Command(webdriver.CommandName.EXECUTE_ASYNC_SCRIPT).
        540 setParameter('script', script).
        541 setParameter('args', goog.array.slice(arguments, 1)),
        542 'WebDriver.executeScript()');
        543};
        544
        545
        546/**
        547 * Schedules a command to execute a custom function.
        548 * @param {function(...): (T|webdriver.promise.Promise.<T>)} fn The function to
        549 * execute.
        550 * @param {Object=} opt_scope The object in whose scope to execute the function.
        551 * @param {...*} var_args Any arguments to pass to the function.
        552 * @return {!webdriver.promise.Promise.<T>} A promise that will be resolved'
        553 * with the function's result.
        554 * @template T
        555 */
        556webdriver.WebDriver.prototype.call = function(fn, opt_scope, var_args) {
        557 var args = goog.array.slice(arguments, 2);
        558 var flow = this.flow_;
        559 return flow.execute(function() {
        560 return webdriver.promise.fullyResolved(args).then(function(args) {
        561 if (webdriver.promise.isGenerator(fn)) {
        562 args.unshift(fn, opt_scope);
        563 return webdriver.promise.consume.apply(null, args);
        564 }
        565 return fn.apply(opt_scope, args);
        566 });
        567 }, 'WebDriver.call(' + (fn.name || 'function') + ')');
        568};
        569
        570
        571/**
        572 * Schedules a command to wait for a condition to hold, as defined by some
        573 * user supplied function. If any errors occur while evaluating the wait, they
        574 * will be allowed to propagate.
        575 *
        576 * <p>In the event a condition returns a {@link webdriver.promise.Promise}, the
        577 * polling loop will wait for it to be resolved and use the resolved value for
        578 * evaluating whether the condition has been satisfied. The resolution time for
        579 * a promise is factored into whether a wait has timed out.
        580 *
        581 * @param {function():boolean} fn The function to evaluate as a wait condition.
        582 * @param {number} timeout How long to wait for the condition to be true.
        583 * @param {string=} opt_message An optional message to use if the wait times
        584 * out.
        585 * @return {!webdriver.promise.Promise} A promise that will be resolved when the
        586 * wait condition has been satisfied.
        587 */
        588webdriver.WebDriver.prototype.wait = function(fn, timeout, opt_message) {
        589 return this.flow_.wait(fn, timeout, opt_message);
        590};
        591
        592
        593/**
        594 * Schedules a command to make the driver sleep for the given amount of time.
        595 * @param {number} ms The amount of time, in milliseconds, to sleep.
        596 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        597 * when the sleep has finished.
        598 */
        599webdriver.WebDriver.prototype.sleep = function(ms) {
        600 return this.flow_.timeout(ms, 'WebDriver.sleep(' + ms + ')');
        601};
        602
        603
        604/**
        605 * Schedules a command to retrieve they current window handle.
        606 * @return {!webdriver.promise.Promise.<string>} A promise that will be
        607 * resolved with the current window handle.
        608 */
        609webdriver.WebDriver.prototype.getWindowHandle = function() {
        610 return this.schedule(
        611 new webdriver.Command(webdriver.CommandName.GET_CURRENT_WINDOW_HANDLE),
        612 'WebDriver.getWindowHandle()');
        613};
        614
        615
        616/**
        617 * Schedules a command to retrieve the current list of available window handles.
        618 * @return {!webdriver.promise.Promise.<!Array.<string>>} A promise that will
        619 * be resolved with an array of window handles.
        620 */
        621webdriver.WebDriver.prototype.getAllWindowHandles = function() {
        622 return this.schedule(
        623 new webdriver.Command(webdriver.CommandName.GET_WINDOW_HANDLES),
        624 'WebDriver.getAllWindowHandles()');
        625};
        626
        627
        628/**
        629 * Schedules a command to retrieve the current page's source. The page source
        630 * returned is a representation of the underlying DOM: do not expect it to be
        631 * formatted or escaped in the same way as the response sent from the web
        632 * server.
        633 * @return {!webdriver.promise.Promise.<string>} A promise that will be
        634 * resolved with the current page source.
        635 */
        636webdriver.WebDriver.prototype.getPageSource = function() {
        637 return this.schedule(
        638 new webdriver.Command(webdriver.CommandName.GET_PAGE_SOURCE),
        639 'WebDriver.getAllWindowHandles()');
        640};
        641
        642
        643/**
        644 * Schedules a command to close the current window.
        645 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        646 * when this command has completed.
        647 */
        648webdriver.WebDriver.prototype.close = function() {
        649 return this.schedule(new webdriver.Command(webdriver.CommandName.CLOSE),
        650 'WebDriver.close()');
        651};
        652
        653
        654/**
        655 * Schedules a command to navigate to the given URL.
        656 * @param {string} url The fully qualified URL to open.
        657 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        658 * when the document has finished loading.
        659 */
        660webdriver.WebDriver.prototype.get = function(url) {
        661 return this.navigate().to(url);
        662};
        663
        664
        665/**
        666 * Schedules a command to retrieve the URL of the current page.
        667 * @return {!webdriver.promise.Promise.<string>} A promise that will be
        668 * resolved with the current URL.
        669 */
        670webdriver.WebDriver.prototype.getCurrentUrl = function() {
        671 return this.schedule(
        672 new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL),
        673 'WebDriver.getCurrentUrl()');
        674};
        675
        676
        677/**
        678 * Schedules a command to retrieve the current page's title.
        679 * @return {!webdriver.promise.Promise.<string>} A promise that will be
        680 * resolved with the current page's title.
        681 */
        682webdriver.WebDriver.prototype.getTitle = function() {
        683 return this.schedule(new webdriver.Command(webdriver.CommandName.GET_TITLE),
        684 'WebDriver.getTitle()');
        685};
        686
        687
        688/**
        689 * Schedule a command to find an element on the page. If the element cannot be
        690 * found, a {@link bot.ErrorCode.NO_SUCH_ELEMENT} result will be returned
        691 * by the driver. Unlike other commands, this error cannot be suppressed. In
        692 * other words, scheduling a command to find an element doubles as an assert
        693 * that the element is present on the page. To test whether an element is
        694 * present on the page, use {@link #isElementPresent} instead.
        695 *
        696 * <p>The search criteria for an element may be defined using one of the
        697 * factories in the {@link webdriver.By} namespace, or as a short-hand
        698 * {@link webdriver.By.Hash} object. For example, the following two statements
        699 * are equivalent:
        700 * <code><pre>
        701 * var e1 = driver.findElement(By.id('foo'));
        702 * var e2 = driver.findElement({id:'foo'});
        703 * </pre></code>
        704 *
        705 * <p>You may also provide a custom locator function, which takes as input
        706 * this WebDriver instance and returns a {@link webdriver.WebElement}, or a
        707 * promise that will resolve to a WebElement. For example, to find the first
        708 * visible link on a page, you could write:
        709 * <code><pre>
        710 * var link = driver.findElement(firstVisibleLink);
        711 *
        712 * function firstVisibleLink(driver) {
        713 * var links = driver.findElements(By.tagName('a'));
        714 * return webdriver.promise.filter(links, function(link) {
        715 * return links.isDisplayed();
        716 * }).then(function(visibleLinks) {
        717 * return visibleLinks[0];
        718 * });
        719 * }
        720 * </pre></code>
        721 *
        722 * <p>When running in the browser, a WebDriver cannot manipulate DOM elements
        723 * directly; it may do so only through a {@link webdriver.WebElement} reference.
        724 * This function may be used to generate a WebElement from a DOM element. A
        725 * reference to the DOM element will be stored in a known location and this
        726 * driver will attempt to retrieve it through {@link #executeScript}. If the
        727 * element cannot be found (eg, it belongs to a different document than the
        728 * one this instance is currently focused on), a
        729 * {@link bot.ErrorCode.NO_SUCH_ELEMENT} error will be returned.
        730 *
        731 * @param {!(webdriver.Locator|webdriver.By.Hash|Element|Function)} locator The
        732 * locator to use.
        733 * @return {!webdriver.WebElement} A WebElement that can be used to issue
        734 * commands against the located element. If the element is not found, the
        735 * element will be invalidated and all scheduled commands aborted.
        736 */
        737webdriver.WebDriver.prototype.findElement = function(locator) {
        738 var id;
        739 if ('nodeType' in locator && 'ownerDocument' in locator) {
        740 var element = /** @type {!Element} */ (locator);
        741 id = this.findDomElement_(element).then(function(element) {
        742 if (!element) {
        743 throw new bot.Error(bot.ErrorCode.NO_SUCH_ELEMENT,
        744 'Unable to locate element. Is WebDriver focused on its ' +
        745 'ownerDocument\'s frame?');
        746 }
        747 return element;
        748 });
        749 } else {
        750 locator = webdriver.Locator.checkLocator(locator);
        751 if (goog.isFunction(locator)) {
        752 id = this.findElementInternal_(locator, this);
        753 } else {
        754 var command = new webdriver.Command(webdriver.CommandName.FIND_ELEMENT).
        755 setParameter('using', locator.using).
        756 setParameter('value', locator.value);
        757 id = this.schedule(command, 'WebDriver.findElement(' + locator + ')');
        758 }
        759 }
        760 return new webdriver.WebElementPromise(this, id);
        761};
        762
        763
        764/**
        765 * @param {!Function} locatorFn The locator function to use.
        766 * @param {!(webdriver.WebDriver|webdriver.WebElement)} context The search
        767 * context.
        768 * @return {!webdriver.promise.Promise.<!webdriver.WebElement>} A
        769 * promise that will resolve to a list of WebElements.
        770 * @private
        771 */
        772webdriver.WebDriver.prototype.findElementInternal_ = function(
        773 locatorFn, context) {
        774 return this.call(goog.partial(locatorFn, context)).then(function(result) {
        775 if (goog.isArray(result)) {
        776 result = result[0];
        777 }
        778 if (!(result instanceof webdriver.WebElement)) {
        779 throw new TypeError('Custom locator did not return a WebElement');
        780 }
        781 return result;
        782 });
        783};
        784
        785
        786/**
        787 * Locates a DOM element so that commands may be issued against it using the
        788 * {@link webdriver.WebElement} class. This is accomplished by storing a
        789 * reference to the element in an object on the element's ownerDocument.
        790 * {@link #executeScript} will then be used to create a WebElement from this
        791 * reference. This requires this driver to currently be focused on the
        792 * ownerDocument's window+frame.
        793
        794 * @param {!Element} element The element to locate.
        795 * @return {!webdriver.promise.Promise.<webdriver.WebElement>} A promise that
        796 * will be fulfilled with the located element, or null if the element
        797 * could not be found.
        798 * @private
        799 */
        800webdriver.WebDriver.prototype.findDomElement_ = function(element) {
        801 var doc = element.ownerDocument;
        802 var store = doc['$webdriver$'] = doc['$webdriver$'] || {};
        803 var id = Math.floor(Math.random() * goog.now()).toString(36);
        804 store[id] = element;
        805 element[id] = id;
        806
        807 function cleanUp() {
        808 delete store[id];
        809 }
        810
        811 function lookupElement(id) {
        812 var store = document['$webdriver$'];
        813 if (!store) {
        814 return null;
        815 }
        816
        817 var element = store[id];
        818 if (!element || element[id] !== id) {
        819 return null;
        820 }
        821 return element;
        822 }
        823
        824 /** @type {!webdriver.promise.Promise.<webdriver.WebElement>} */
        825 var foundElement = this.executeScript(lookupElement, id);
        826 foundElement.thenFinally(cleanUp);
        827 return foundElement;
        828};
        829
        830
        831/**
        832 * Schedules a command to test if an element is present on the page.
        833 *
        834 * <p>If given a DOM element, this function will check if it belongs to the
        835 * document the driver is currently focused on. Otherwise, the function will
        836 * test if at least one element can be found with the given search criteria.
        837 *
        838 * @param {!(webdriver.Locator|webdriver.By.Hash|Element|
        839 * Function)} locatorOrElement The locator to use, or the actual
        840 * DOM element to be located by the server.
        841 * @return {!webdriver.promise.Promise.<boolean>} A promise that will resolve
        842 * with whether the element is present on the page.
        843 */
        844webdriver.WebDriver.prototype.isElementPresent = function(locatorOrElement) {
        845 if ('nodeType' in locatorOrElement && 'ownerDocument' in locatorOrElement) {
        846 return this.findDomElement_(/** @type {!Element} */ (locatorOrElement)).
        847 then(function(result) { return !!result; });
        848 } else {
        849 return this.findElements.apply(this, arguments).then(function(result) {
        850 return !!result.length;
        851 });
        852 }
        853};
        854
        855
        856/**
        857 * Schedule a command to search for multiple elements on the page.
        858 *
        859 * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The locator
        860 * strategy to use when searching for the element.
        861 * @return {!webdriver.promise.Promise.<!Array.<!webdriver.WebElement>>} A
        862 * promise that will resolve to an array of WebElements.
        863 */
        864webdriver.WebDriver.prototype.findElements = function(locator) {
        865 locator = webdriver.Locator.checkLocator(locator);
        866 if (goog.isFunction(locator)) {
        867 return this.findElementsInternal_(locator, this);
        868 } else {
        869 var command = new webdriver.Command(webdriver.CommandName.FIND_ELEMENTS).
        870 setParameter('using', locator.using).
        871 setParameter('value', locator.value);
        872 return this.schedule(command, 'WebDriver.findElements(' + locator + ')');
        873 }
        874};
        875
        876
        877/**
        878 * @param {!Function} locatorFn The locator function to use.
        879 * @param {!(webdriver.WebDriver|webdriver.WebElement)} context The search
        880 * context.
        881 * @return {!webdriver.promise.Promise.<!Array.<!webdriver.WebElement>>} A
        882 * promise that will resolve to an array of WebElements.
        883 * @private
        884 */
        885webdriver.WebDriver.prototype.findElementsInternal_ = function(
        886 locatorFn, context) {
        887 return this.call(goog.partial(locatorFn, context)).then(function(result) {
        888 if (result instanceof webdriver.WebElement) {
        889 return [result];
        890 }
        891
        892 if (!goog.isArray(result)) {
        893 return [];
        894 }
        895
        896 return goog.array.filter(result, function(item) {
        897 return item instanceof webdriver.WebElement;
        898 });
        899 });
        900};
        901
        902
        903/**
        904 * Schedule a command to take a screenshot. The driver makes a best effort to
        905 * return a screenshot of the following, in order of preference:
        906 * <ol>
        907 * <li>Entire page
        908 * <li>Current window
        909 * <li>Visible portion of the current frame
        910 * <li>The screenshot of the entire display containing the browser
        911 * </ol>
        912 *
        913 * @return {!webdriver.promise.Promise.<string>} A promise that will be
        914 * resolved to the screenshot as a base-64 encoded PNG.
        915 */
        916webdriver.WebDriver.prototype.takeScreenshot = function() {
        917 return this.schedule(new webdriver.Command(webdriver.CommandName.SCREENSHOT),
        918 'WebDriver.takeScreenshot()');
        919};
        920
        921
        922/**
        923 * @return {!webdriver.WebDriver.Options} The options interface for this
        924 * instance.
        925 */
        926webdriver.WebDriver.prototype.manage = function() {
        927 return new webdriver.WebDriver.Options(this);
        928};
        929
        930
        931/**
        932 * @return {!webdriver.WebDriver.Navigation} The navigation interface for this
        933 * instance.
        934 */
        935webdriver.WebDriver.prototype.navigate = function() {
        936 return new webdriver.WebDriver.Navigation(this);
        937};
        938
        939
        940/**
        941 * @return {!webdriver.WebDriver.TargetLocator} The target locator interface for
        942 * this instance.
        943 */
        944webdriver.WebDriver.prototype.switchTo = function() {
        945 return new webdriver.WebDriver.TargetLocator(this);
        946};
        947
        948
        949
        950/**
        951 * Interface for navigating back and forth in the browser history.
        952 * @param {!webdriver.WebDriver} driver The parent driver.
        953 * @constructor
        954 */
        955webdriver.WebDriver.Navigation = function(driver) {
        956
        957 /** @private {!webdriver.WebDriver} */
        958 this.driver_ = driver;
        959};
        960
        961
        962/**
        963 * Schedules a command to navigate to a new URL.
        964 * @param {string} url The URL to navigate to.
        965 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        966 * when the URL has been loaded.
        967 */
        968webdriver.WebDriver.Navigation.prototype.to = function(url) {
        969 return this.driver_.schedule(
        970 new webdriver.Command(webdriver.CommandName.GET).
        971 setParameter('url', url),
        972 'WebDriver.navigate().to(' + url + ')');
        973};
        974
        975
        976/**
        977 * Schedules a command to move backwards in the browser history.
        978 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        979 * when the navigation event has completed.
        980 */
        981webdriver.WebDriver.Navigation.prototype.back = function() {
        982 return this.driver_.schedule(
        983 new webdriver.Command(webdriver.CommandName.GO_BACK),
        984 'WebDriver.navigate().back()');
        985};
        986
        987
        988/**
        989 * Schedules a command to move forwards in the browser history.
        990 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        991 * when the navigation event has completed.
        992 */
        993webdriver.WebDriver.Navigation.prototype.forward = function() {
        994 return this.driver_.schedule(
        995 new webdriver.Command(webdriver.CommandName.GO_FORWARD),
        996 'WebDriver.navigate().forward()');
        997};
        998
        999
        1000/**
        1001 * Schedules a command to refresh the current page.
        1002 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1003 * when the navigation event has completed.
        1004 */
        1005webdriver.WebDriver.Navigation.prototype.refresh = function() {
        1006 return this.driver_.schedule(
        1007 new webdriver.Command(webdriver.CommandName.REFRESH),
        1008 'WebDriver.navigate().refresh()');
        1009};
        1010
        1011
        1012
        1013/**
        1014 * Provides methods for managing browser and driver state.
        1015 * @param {!webdriver.WebDriver} driver The parent driver.
        1016 * @constructor
        1017 */
        1018webdriver.WebDriver.Options = function(driver) {
        1019
        1020 /** @private {!webdriver.WebDriver} */
        1021 this.driver_ = driver;
        1022};
        1023
        1024
        1025/**
        1026 * A JSON description of a browser cookie.
        1027 * @typedef {{
        1028 * name: string,
        1029 * value: string,
        1030 * path: (string|undefined),
        1031 * domain: (string|undefined),
        1032 * secure: (boolean|undefined),
        1033 * expiry: (number|undefined)
        1034 * }}
        1035 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object
        1036 */
        1037webdriver.WebDriver.Options.Cookie;
        1038
        1039
        1040/**
        1041 * Schedules a command to add a cookie.
        1042 * @param {string} name The cookie name.
        1043 * @param {string} value The cookie value.
        1044 * @param {string=} opt_path The cookie path.
        1045 * @param {string=} opt_domain The cookie domain.
        1046 * @param {boolean=} opt_isSecure Whether the cookie is secure.
        1047 * @param {(number|!Date)=} opt_expiry When the cookie expires. If specified as
        1048 * a number, should be in milliseconds since midnight, January 1, 1970 UTC.
        1049 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1050 * when the cookie has been added to the page.
        1051 */
        1052webdriver.WebDriver.Options.prototype.addCookie = function(
        1053 name, value, opt_path, opt_domain, opt_isSecure, opt_expiry) {
        1054 // We do not allow '=' or ';' in the name.
        1055 if (/[;=]/.test(name)) {
        1056 throw Error('Invalid cookie name "' + name + '"');
        1057 }
        1058
        1059 // We do not allow ';' in value.
        1060 if (/;/.test(value)) {
        1061 throw Error('Invalid cookie value "' + value + '"');
        1062 }
        1063
        1064 var cookieString = name + '=' + value +
        1065 (opt_domain ? ';domain=' + opt_domain : '') +
        1066 (opt_path ? ';path=' + opt_path : '') +
        1067 (opt_isSecure ? ';secure' : '');
        1068
        1069 var expiry;
        1070 if (goog.isDef(opt_expiry)) {
        1071 var expiryDate;
        1072 if (goog.isNumber(opt_expiry)) {
        1073 expiryDate = new Date(opt_expiry);
        1074 } else {
        1075 expiryDate = /** @type {!Date} */ (opt_expiry);
        1076 opt_expiry = expiryDate.getTime();
        1077 }
        1078 cookieString += ';expires=' + expiryDate.toUTCString();
        1079 // Convert from milliseconds to seconds.
        1080 expiry = Math.floor(/** @type {number} */ (opt_expiry) / 1000);
        1081 }
        1082
        1083 return this.driver_.schedule(
        1084 new webdriver.Command(webdriver.CommandName.ADD_COOKIE).
        1085 setParameter('cookie', {
        1086 'name': name,
        1087 'value': value,
        1088 'path': opt_path,
        1089 'domain': opt_domain,
        1090 'secure': !!opt_isSecure,
        1091 'expiry': expiry
        1092 }),
        1093 'WebDriver.manage().addCookie(' + cookieString + ')');
        1094};
        1095
        1096
        1097/**
        1098 * Schedules a command to delete all cookies visible to the current page.
        1099 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1100 * when all cookies have been deleted.
        1101 */
        1102webdriver.WebDriver.Options.prototype.deleteAllCookies = function() {
        1103 return this.driver_.schedule(
        1104 new webdriver.Command(webdriver.CommandName.DELETE_ALL_COOKIES),
        1105 'WebDriver.manage().deleteAllCookies()');
        1106};
        1107
        1108
        1109/**
        1110 * Schedules a command to delete the cookie with the given name. This command is
        1111 * a no-op if there is no cookie with the given name visible to the current
        1112 * page.
        1113 * @param {string} name The name of the cookie to delete.
        1114 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1115 * when the cookie has been deleted.
        1116 */
        1117webdriver.WebDriver.Options.prototype.deleteCookie = function(name) {
        1118 return this.driver_.schedule(
        1119 new webdriver.Command(webdriver.CommandName.DELETE_COOKIE).
        1120 setParameter('name', name),
        1121 'WebDriver.manage().deleteCookie(' + name + ')');
        1122};
        1123
        1124
        1125/**
        1126 * Schedules a command to retrieve all cookies visible to the current page.
        1127 * Each cookie will be returned as a JSON object as described by the WebDriver
        1128 * wire protocol.
        1129 * @return {!webdriver.promise.Promise.<
        1130 * !Array.<webdriver.WebDriver.Options.Cookie>>} A promise that will be
        1131 * resolved with the cookies visible to the current page.
        1132 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object
        1133 */
        1134webdriver.WebDriver.Options.prototype.getCookies = function() {
        1135 return this.driver_.schedule(
        1136 new webdriver.Command(webdriver.CommandName.GET_ALL_COOKIES),
        1137 'WebDriver.manage().getCookies()');
        1138};
        1139
        1140
        1141/**
        1142 * Schedules a command to retrieve the cookie with the given name. Returns null
        1143 * if there is no such cookie. The cookie will be returned as a JSON object as
        1144 * described by the WebDriver wire protocol.
        1145 * @param {string} name The name of the cookie to retrieve.
        1146 * @return {!webdriver.promise.Promise.<?webdriver.WebDriver.Options.Cookie>} A
        1147 * promise that will be resolved with the named cookie, or {@code null}
        1148 * if there is no such cookie.
        1149 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object
        1150 */
        1151webdriver.WebDriver.Options.prototype.getCookie = function(name) {
        1152 return this.getCookies().then(function(cookies) {
        1153 return goog.array.find(cookies, function(cookie) {
        1154 return cookie && cookie['name'] == name;
        1155 });
        1156 });
        1157};
        1158
        1159
        1160/**
        1161 * @return {!webdriver.WebDriver.Logs} The interface for managing driver
        1162 * logs.
        1163 */
        1164webdriver.WebDriver.Options.prototype.logs = function() {
        1165 return new webdriver.WebDriver.Logs(this.driver_);
        1166};
        1167
        1168
        1169/**
        1170 * @return {!webdriver.WebDriver.Timeouts} The interface for managing driver
        1171 * timeouts.
        1172 */
        1173webdriver.WebDriver.Options.prototype.timeouts = function() {
        1174 return new webdriver.WebDriver.Timeouts(this.driver_);
        1175};
        1176
        1177
        1178/**
        1179 * @return {!webdriver.WebDriver.Window} The interface for managing the
        1180 * current window.
        1181 */
        1182webdriver.WebDriver.Options.prototype.window = function() {
        1183 return new webdriver.WebDriver.Window(this.driver_);
        1184};
        1185
        1186
        1187
        1188/**
        1189 * An interface for managing timeout behavior for WebDriver instances.
        1190 * @param {!webdriver.WebDriver} driver The parent driver.
        1191 * @constructor
        1192 */
        1193webdriver.WebDriver.Timeouts = function(driver) {
        1194
        1195 /** @private {!webdriver.WebDriver} */
        1196 this.driver_ = driver;
        1197};
        1198
        1199
        1200/**
        1201 * Specifies the amount of time the driver should wait when searching for an
        1202 * element if it is not immediately present.
        1203 * <p/>
        1204 * When searching for a single element, the driver should poll the page
        1205 * until the element has been found, or this timeout expires before failing
        1206 * with a {@code bot.ErrorCode.NO_SUCH_ELEMENT} error. When searching
        1207 * for multiple elements, the driver should poll the page until at least one
        1208 * element has been found or this timeout has expired.
        1209 * <p/>
        1210 * Setting the wait timeout to 0 (its default value), disables implicit
        1211 * waiting.
        1212 * <p/>
        1213 * Increasing the implicit wait timeout should be used judiciously as it
        1214 * will have an adverse effect on test run time, especially when used with
        1215 * slower location strategies like XPath.
        1216 *
        1217 * @param {number} ms The amount of time to wait, in milliseconds.
        1218 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1219 * when the implicit wait timeout has been set.
        1220 */
        1221webdriver.WebDriver.Timeouts.prototype.implicitlyWait = function(ms) {
        1222 return this.driver_.schedule(
        1223 new webdriver.Command(webdriver.CommandName.IMPLICITLY_WAIT).
        1224 setParameter('ms', ms < 0 ? 0 : ms),
        1225 'WebDriver.manage().timeouts().implicitlyWait(' + ms + ')');
        1226};
        1227
        1228
        1229/**
        1230 * Sets the amount of time to wait, in milliseconds, for an asynchronous script
        1231 * to finish execution before returning an error. If the timeout is less than or
        1232 * equal to 0, the script will be allowed to run indefinitely.
        1233 *
        1234 * @param {number} ms The amount of time to wait, in milliseconds.
        1235 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1236 * when the script timeout has been set.
        1237 */
        1238webdriver.WebDriver.Timeouts.prototype.setScriptTimeout = function(ms) {
        1239 return this.driver_.schedule(
        1240 new webdriver.Command(webdriver.CommandName.SET_SCRIPT_TIMEOUT).
        1241 setParameter('ms', ms < 0 ? 0 : ms),
        1242 'WebDriver.manage().timeouts().setScriptTimeout(' + ms + ')');
        1243};
        1244
        1245
        1246/**
        1247 * Sets the amount of time to wait for a page load to complete before returning
        1248 * an error. If the timeout is negative, page loads may be indefinite.
        1249 * @param {number} ms The amount of time to wait, in milliseconds.
        1250 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1251 * when the timeout has been set.
        1252 */
        1253webdriver.WebDriver.Timeouts.prototype.pageLoadTimeout = function(ms) {
        1254 return this.driver_.schedule(
        1255 new webdriver.Command(webdriver.CommandName.SET_TIMEOUT).
        1256 setParameter('type', 'page load').
        1257 setParameter('ms', ms),
        1258 'WebDriver.manage().timeouts().pageLoadTimeout(' + ms + ')');
        1259};
        1260
        1261
        1262
        1263/**
        1264 * An interface for managing the current window.
        1265 * @param {!webdriver.WebDriver} driver The parent driver.
        1266 * @constructor
        1267 */
        1268webdriver.WebDriver.Window = function(driver) {
        1269
        1270 /** @private {!webdriver.WebDriver} */
        1271 this.driver_ = driver;
        1272};
        1273
        1274
        1275/**
        1276 * Retrieves the window's current position, relative to the top left corner of
        1277 * the screen.
        1278 * @return {!webdriver.promise.Promise.<{x: number, y: number}>} A promise that
        1279 * will be resolved with the window's position in the form of a
        1280 * {x:number, y:number} object literal.
        1281 */
        1282webdriver.WebDriver.Window.prototype.getPosition = function() {
        1283 return this.driver_.schedule(
        1284 new webdriver.Command(webdriver.CommandName.GET_WINDOW_POSITION).
        1285 setParameter('windowHandle', 'current'),
        1286 'WebDriver.manage().window().getPosition()');
        1287};
        1288
        1289
        1290/**
        1291 * Repositions the current window.
        1292 * @param {number} x The desired horizontal position, relative to the left side
        1293 * of the screen.
        1294 * @param {number} y The desired vertical position, relative to the top of the
        1295 * of the screen.
        1296 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1297 * when the command has completed.
        1298 */
        1299webdriver.WebDriver.Window.prototype.setPosition = function(x, y) {
        1300 return this.driver_.schedule(
        1301 new webdriver.Command(webdriver.CommandName.SET_WINDOW_POSITION).
        1302 setParameter('windowHandle', 'current').
        1303 setParameter('x', x).
        1304 setParameter('y', y),
        1305 'WebDriver.manage().window().setPosition(' + x + ', ' + y + ')');
        1306};
        1307
        1308
        1309/**
        1310 * Retrieves the window's current size.
        1311 * @return {!webdriver.promise.Promise.<{width: number, height: number}>} A
        1312 * promise that will be resolved with the window's size in the form of a
        1313 * {width:number, height:number} object literal.
        1314 */
        1315webdriver.WebDriver.Window.prototype.getSize = function() {
        1316 return this.driver_.schedule(
        1317 new webdriver.Command(webdriver.CommandName.GET_WINDOW_SIZE).
        1318 setParameter('windowHandle', 'current'),
        1319 'WebDriver.manage().window().getSize()');
        1320};
        1321
        1322
        1323/**
        1324 * Resizes the current window.
        1325 * @param {number} width The desired window width.
        1326 * @param {number} height The desired window height.
        1327 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1328 * when the command has completed.
        1329 */
        1330webdriver.WebDriver.Window.prototype.setSize = function(width, height) {
        1331 return this.driver_.schedule(
        1332 new webdriver.Command(webdriver.CommandName.SET_WINDOW_SIZE).
        1333 setParameter('windowHandle', 'current').
        1334 setParameter('width', width).
        1335 setParameter('height', height),
        1336 'WebDriver.manage().window().setSize(' + width + ', ' + height + ')');
        1337};
        1338
        1339
        1340/**
        1341 * Maximizes the current window.
        1342 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1343 * when the command has completed.
        1344 */
        1345webdriver.WebDriver.Window.prototype.maximize = function() {
        1346 return this.driver_.schedule(
        1347 new webdriver.Command(webdriver.CommandName.MAXIMIZE_WINDOW).
        1348 setParameter('windowHandle', 'current'),
        1349 'WebDriver.manage().window().maximize()');
        1350};
        1351
        1352
        1353/**
        1354 * Interface for managing WebDriver log records.
        1355 * @param {!webdriver.WebDriver} driver The parent driver.
        1356 * @constructor
        1357 */
        1358webdriver.WebDriver.Logs = function(driver) {
        1359
        1360 /** @private {!webdriver.WebDriver} */
        1361 this.driver_ = driver;
        1362};
        1363
        1364
        1365/**
        1366 * Fetches available log entries for the given type.
        1367 *
        1368 * <p/>Note that log buffers are reset after each call, meaning that
        1369 * available log entries correspond to those entries not yet returned for a
        1370 * given log type. In practice, this means that this call will return the
        1371 * available log entries since the last call, or from the start of the
        1372 * session.
        1373 *
        1374 * @param {!webdriver.logging.Type} type The desired log type.
        1375 * @return {!webdriver.promise.Promise.<!Array.<!webdriver.logging.Entry>>} A
        1376 * promise that will resolve to a list of log entries for the specified
        1377 * type.
        1378 */
        1379webdriver.WebDriver.Logs.prototype.get = function(type) {
        1380 return this.driver_.schedule(
        1381 new webdriver.Command(webdriver.CommandName.GET_LOG).
        1382 setParameter('type', type),
        1383 'WebDriver.manage().logs().get(' + type + ')').
        1384 then(function(entries) {
        1385 return goog.array.map(entries, function(entry) {
        1386 if (!(entry instanceof webdriver.logging.Entry)) {
        1387 return new webdriver.logging.Entry(
        1388 entry['level'], entry['message'], entry['timestamp'],
        1389 entry['type']);
        1390 }
        1391 return entry;
        1392 });
        1393 });
        1394};
        1395
        1396
        1397/**
        1398 * Retrieves the log types available to this driver.
        1399 * @return {!webdriver.promise.Promise.<!Array.<!webdriver.logging.Type>>} A
        1400 * promise that will resolve to a list of available log types.
        1401 */
        1402webdriver.WebDriver.Logs.prototype.getAvailableLogTypes = function() {
        1403 return this.driver_.schedule(
        1404 new webdriver.Command(webdriver.CommandName.GET_AVAILABLE_LOG_TYPES),
        1405 'WebDriver.manage().logs().getAvailableLogTypes()');
        1406};
        1407
        1408
        1409
        1410/**
        1411 * An interface for changing the focus of the driver to another frame or window.
        1412 * @param {!webdriver.WebDriver} driver The parent driver.
        1413 * @constructor
        1414 */
        1415webdriver.WebDriver.TargetLocator = function(driver) {
        1416
        1417 /** @private {!webdriver.WebDriver} */
        1418 this.driver_ = driver;
        1419};
        1420
        1421
        1422/**
        1423 * Schedules a command retrieve the {@code document.activeElement} element on
        1424 * the current document, or {@code document.body} if activeElement is not
        1425 * available.
        1426 * @return {!webdriver.WebElementPromise} The active element.
        1427 */
        1428webdriver.WebDriver.TargetLocator.prototype.activeElement = function() {
        1429 var id = this.driver_.schedule(
        1430 new webdriver.Command(webdriver.CommandName.GET_ACTIVE_ELEMENT),
        1431 'WebDriver.switchTo().activeElement()');
        1432 return new webdriver.WebElementPromise(this.driver_, id);
        1433};
        1434
        1435
        1436/**
        1437 * Schedules a command to switch focus of all future commands to the first frame
        1438 * on the page.
        1439 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1440 * when the driver has changed focus to the default content.
        1441 */
        1442webdriver.WebDriver.TargetLocator.prototype.defaultContent = function() {
        1443 return this.driver_.schedule(
        1444 new webdriver.Command(webdriver.CommandName.SWITCH_TO_FRAME).
        1445 setParameter('id', null),
        1446 'WebDriver.switchTo().defaultContent()');
        1447};
        1448
        1449
        1450/**
        1451 * Schedules a command to switch the focus of all future commands to another
        1452 * frame on the page.
        1453 * <p/>
        1454 * If the frame is specified by a number, the command will switch to the frame
        1455 * by its (zero-based) index into the {@code window.frames} collection.
        1456 * <p/>
        1457 * If the frame is specified by a string, the command will select the frame by
        1458 * its name or ID. To select sub-frames, simply separate the frame names/IDs by
        1459 * dots. As an example, "main.child" will select the frame with the name "main"
        1460 * and then its child "child".
        1461 * <p/>
        1462 * If the specified frame can not be found, the deferred result will errback
        1463 * with a {@code bot.ErrorCode.NO_SUCH_FRAME} error.
        1464 * @param {string|number} nameOrIndex The frame locator.
        1465 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1466 * when the driver has changed focus to the specified frame.
        1467 */
        1468webdriver.WebDriver.TargetLocator.prototype.frame = function(nameOrIndex) {
        1469 return this.driver_.schedule(
        1470 new webdriver.Command(webdriver.CommandName.SWITCH_TO_FRAME).
        1471 setParameter('id', nameOrIndex),
        1472 'WebDriver.switchTo().frame(' + nameOrIndex + ')');
        1473};
        1474
        1475
        1476/**
        1477 * Schedules a command to switch the focus of all future commands to another
        1478 * window. Windows may be specified by their {@code window.name} attribute or
        1479 * by its handle (as returned by {@code webdriver.WebDriver#getWindowHandles}).
        1480 * <p/>
        1481 * If the specificed window can not be found, the deferred result will errback
        1482 * with a {@code bot.ErrorCode.NO_SUCH_WINDOW} error.
        1483 * @param {string} nameOrHandle The name or window handle of the window to
        1484 * switch focus to.
        1485 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1486 * when the driver has changed focus to the specified window.
        1487 */
        1488webdriver.WebDriver.TargetLocator.prototype.window = function(nameOrHandle) {
        1489 return this.driver_.schedule(
        1490 new webdriver.Command(webdriver.CommandName.SWITCH_TO_WINDOW).
        1491 setParameter('name', nameOrHandle),
        1492 'WebDriver.switchTo().window(' + nameOrHandle + ')');
        1493};
        1494
        1495
        1496/**
        1497 * Schedules a command to change focus to the active alert dialog. This command
        1498 * will return a {@link bot.ErrorCode.NO_SUCH_ALERT} error if an alert dialog
        1499 * is not currently open.
        1500 * @return {!webdriver.AlertPromise} The open alert.
        1501 */
        1502webdriver.WebDriver.TargetLocator.prototype.alert = function() {
        1503 var text = this.driver_.schedule(
        1504 new webdriver.Command(webdriver.CommandName.GET_ALERT_TEXT),
        1505 'WebDriver.switchTo().alert()');
        1506 var driver = this.driver_;
        1507 return new webdriver.AlertPromise(driver, text.then(function(text) {
        1508 return new webdriver.Alert(driver, text);
        1509 }));
        1510};
        1511
        1512
        1513/**
        1514 * Simulate pressing many keys at once in a "chord". Takes a sequence of
        1515 * {@link webdriver.Key}s or strings, appends each of the values to a string,
        1516 * and adds the chord termination key ({@link webdriver.Key.NULL}) and returns
        1517 * the resultant string.
        1518 *
        1519 * Note: when the low-level webdriver key handlers see Keys.NULL, active
        1520 * modifier keys (CTRL/ALT/SHIFT/etc) release via a keyup event.
        1521 *
        1522 * @param {...string} var_args The key sequence to concatenate.
        1523 * @return {string} The null-terminated key sequence.
        1524 * @see http://code.google.com/p/webdriver/issues/detail?id=79
        1525 */
        1526webdriver.Key.chord = function(var_args) {
        1527 var sequence = goog.array.reduce(
        1528 goog.array.slice(arguments, 0),
        1529 function(str, key) {
        1530 return str + key;
        1531 }, '');
        1532 sequence += webdriver.Key.NULL;
        1533 return sequence;
        1534};
        1535
        1536
        1537//////////////////////////////////////////////////////////////////////////////
        1538//
        1539// webdriver.WebElement
        1540//
        1541//////////////////////////////////////////////////////////////////////////////
        1542
        1543
        1544
        1545/**
        1546 * Represents a DOM element. WebElements can be found by searching from the
        1547 * document root using a {@code webdriver.WebDriver} instance, or by searching
        1548 * under another {@code webdriver.WebElement}:
        1549 * <pre><code>
        1550 * driver.get('http://www.google.com');
        1551 * var searchForm = driver.findElement(By.tagName('form'));
        1552 * var searchBox = searchForm.findElement(By.name('q'));
        1553 * searchBox.sendKeys('webdriver');
        1554 * </code></pre>
        1555 *
        1556 * The WebElement is implemented as a promise for compatibility with the promise
        1557 * API. It will always resolve itself when its internal state has been fully
        1558 * resolved and commands may be issued against the element. This can be used to
        1559 * catch errors when an element cannot be located on the page:
        1560 * <pre><code>
        1561 * driver.findElement(By.id('not-there')).then(function(element) {
        1562 * alert('Found an element that was not expected to be there!');
        1563 * }, function(error) {
        1564 * alert('The element was not found, as expected');
        1565 * });
        1566 * </code></pre>
        1567 *
        1568 * @param {!webdriver.WebDriver} driver The parent WebDriver instance for this
        1569 * element.
        1570 * @param {!(webdriver.promise.Promise.<webdriver.WebElement.Id>|
        1571 * webdriver.WebElement.Id)} id The server-assigned opaque ID for the
        1572 * underlying DOM element.
        1573 * @constructor
        1574 */
        1575webdriver.WebElement = function(driver, id) {
        1576
        1577 /** @private {!webdriver.WebDriver} */
        1578 this.driver_ = driver;
        1579
        1580 /** @private {!webdriver.promise.Promise.<webdriver.WebElement.Id>} */
        1581 this.id_ = id instanceof webdriver.promise.Promise ?
        1582 id : webdriver.promise.fulfilled(id);
        1583};
        1584
        1585
        1586/**
        1587 * Wire protocol definition of a WebElement ID.
        1588 * @typedef {{ELEMENT: string}}
        1589 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol
        1590 */
        1591webdriver.WebElement.Id;
        1592
        1593
        1594/**
        1595 * The property key used in the wire protocol to indicate that a JSON object
        1596 * contains the ID of a WebElement.
        1597 * @type {string}
        1598 * @const
        1599 */
        1600webdriver.WebElement.ELEMENT_KEY = 'ELEMENT';
        1601
        1602
        1603/**
        1604 * Compares to WebElements for equality.
        1605 * @param {!webdriver.WebElement} a A WebElement.
        1606 * @param {!webdriver.WebElement} b A WebElement.
        1607 * @return {!webdriver.promise.Promise.<boolean>} A promise that will be
        1608 * resolved to whether the two WebElements are equal.
        1609 */
        1610webdriver.WebElement.equals = function(a, b) {
        1611 if (a == b) {
        1612 return webdriver.promise.fulfilled(true);
        1613 }
        1614 var ids = [a.getId(), b.getId()];
        1615 return webdriver.promise.all(ids).then(function(ids) {
        1616 // If the two element's have the same ID, they should be considered
        1617 // equal. Otherwise, they may still be equivalent, but we'll need to
        1618 // ask the server to check for us.
        1619 if (ids[0][webdriver.WebElement.ELEMENT_KEY] ==
        1620 ids[1][webdriver.WebElement.ELEMENT_KEY]) {
        1621 return true;
        1622 }
        1623
        1624 var command = new webdriver.Command(webdriver.CommandName.ELEMENT_EQUALS);
        1625 command.setParameter('id', ids[0]);
        1626 command.setParameter('other', ids[1]);
        1627 return a.driver_.schedule(command, 'webdriver.WebElement.equals()');
        1628 });
        1629};
        1630
        1631
        1632/**
        1633 * @return {!webdriver.WebDriver} The parent driver for this instance.
        1634 */
        1635webdriver.WebElement.prototype.getDriver = function() {
        1636 return this.driver_;
        1637};
        1638
        1639
        1640/**
        1641 * @return {!webdriver.promise.Promise.<webdriver.WebElement.Id>} A promise
        1642 * that resolves to this element's JSON representation as defined by the
        1643 * WebDriver wire protocol.
        1644 * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol
        1645 */
        1646webdriver.WebElement.prototype.getId = function() {
        1647 return this.id_;
        1648};
        1649
        1650
        1651/**
        1652 * Schedules a command that targets this element with the parent WebDriver
        1653 * instance. Will ensure this element's ID is included in the command parameters
        1654 * under the "id" key.
        1655 * @param {!webdriver.Command} command The command to schedule.
        1656 * @param {string} description A description of the command for debugging.
        1657 * @return {!webdriver.promise.Promise.<T>} A promise that will be resolved
        1658 * with the command result.
        1659 * @template T
        1660 * @see webdriver.WebDriver.prototype.schedule
        1661 * @private
        1662 */
        1663webdriver.WebElement.prototype.schedule_ = function(command, description) {
        1664 command.setParameter('id', this.getId());
        1665 return this.driver_.schedule(command, description);
        1666};
        1667
        1668
        1669/**
        1670 * Schedule a command to find a descendant of this element. If the element
        1671 * cannot be found, a {@code bot.ErrorCode.NO_SUCH_ELEMENT} result will
        1672 * be returned by the driver. Unlike other commands, this error cannot be
        1673 * suppressed. In other words, scheduling a command to find an element doubles
        1674 * as an assert that the element is present on the page. To test whether an
        1675 * element is present on the page, use {@code #isElementPresent} instead.
        1676 *
        1677 * <p>The search criteria for an element may be defined using one of the
        1678 * factories in the {@link webdriver.By} namespace, or as a short-hand
        1679 * {@link webdriver.By.Hash} object. For example, the following two statements
        1680 * are equivalent:
        1681 * <code><pre>
        1682 * var e1 = element.findElement(By.id('foo'));
        1683 * var e2 = element.findElement({id:'foo'});
        1684 * </pre></code>
        1685 *
        1686 * <p>You may also provide a custom locator function, which takes as input
        1687 * this WebDriver instance and returns a {@link webdriver.WebElement}, or a
        1688 * promise that will resolve to a WebElement. For example, to find the first
        1689 * visible link on a page, you could write:
        1690 * <code><pre>
        1691 * var link = element.findElement(firstVisibleLink);
        1692 *
        1693 * function firstVisibleLink(element) {
        1694 * var links = element.findElements(By.tagName('a'));
        1695 * return webdriver.promise.filter(links, function(link) {
        1696 * return links.isDisplayed();
        1697 * }).then(function(visibleLinks) {
        1698 * return visibleLinks[0];
        1699 * });
        1700 * }
        1701 * </pre></code>
        1702 *
        1703 * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The
        1704 * locator strategy to use when searching for the element.
        1705 * @return {!webdriver.WebElement} A WebElement that can be used to issue
        1706 * commands against the located element. If the element is not found, the
        1707 * element will be invalidated and all scheduled commands aborted.
        1708 */
        1709webdriver.WebElement.prototype.findElement = function(locator) {
        1710 locator = webdriver.Locator.checkLocator(locator);
        1711 var id;
        1712 if (goog.isFunction(locator)) {
        1713 id = this.driver_.findElementInternal_(locator, this);
        1714 } else {
        1715 var command = new webdriver.Command(
        1716 webdriver.CommandName.FIND_CHILD_ELEMENT).
        1717 setParameter('using', locator.using).
        1718 setParameter('value', locator.value);
        1719 id = this.schedule_(command, 'WebElement.findElement(' + locator + ')');
        1720 }
        1721 return new webdriver.WebElementPromise(this.driver_, id);
        1722};
        1723
        1724
        1725/**
        1726 * Schedules a command to test if there is at least one descendant of this
        1727 * element that matches the given search criteria.
        1728 *
        1729 * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The
        1730 * locator strategy to use when searching for the element.
        1731 * @return {!webdriver.promise.Promise.<boolean>} A promise that will be
        1732 * resolved with whether an element could be located on the page.
        1733 */
        1734webdriver.WebElement.prototype.isElementPresent = function(locator) {
        1735 return this.findElements(locator).then(function(result) {
        1736 return !!result.length;
        1737 });
        1738};
        1739
        1740
        1741/**
        1742 * Schedules a command to find all of the descendants of this element that
        1743 * match the given search criteria.
        1744 *
        1745 * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The
        1746 * locator strategy to use when searching for the elements.
        1747 * @return {!webdriver.promise.Promise.<!Array.<!webdriver.WebElement>>} A
        1748 * promise that will resolve to an array of WebElements.
        1749 */
        1750webdriver.WebElement.prototype.findElements = function(locator) {
        1751 locator = webdriver.Locator.checkLocator(locator);
        1752 if (goog.isFunction(locator)) {
        1753 return this.driver_.findElementsInternal_(locator, this);
        1754 } else {
        1755 var command = new webdriver.Command(
        1756 webdriver.CommandName.FIND_CHILD_ELEMENTS).
        1757 setParameter('using', locator.using).
        1758 setParameter('value', locator.value);
        1759 return this.schedule_(command, 'WebElement.findElements(' + locator + ')');
        1760 }
        1761};
        1762
        1763
        1764/**
        1765 * Schedules a command to click on this element.
        1766 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1767 * when the click command has completed.
        1768 */
        1769webdriver.WebElement.prototype.click = function() {
        1770 return this.schedule_(
        1771 new webdriver.Command(webdriver.CommandName.CLICK_ELEMENT),
        1772 'WebElement.click()');
        1773};
        1774
        1775
        1776/**
        1777 * Schedules a command to type a sequence on the DOM element represented by this
        1778 * instance.
        1779 * <p/>
        1780 * Modifier keys (SHIFT, CONTROL, ALT, META) are stateful; once a modifier is
        1781 * processed in the keysequence, that key state is toggled until one of the
        1782 * following occurs:
        1783 * <ul>
        1784 * <li>The modifier key is encountered again in the sequence. At this point the
        1785 * state of the key is toggled (along with the appropriate keyup/down events).
        1786 * </li>
        1787 * <li>The {@code webdriver.Key.NULL} key is encountered in the sequence. When
        1788 * this key is encountered, all modifier keys current in the down state are
        1789 * released (with accompanying keyup events). The NULL key can be used to
        1790 * simulate common keyboard shortcuts:
        1791 * <code><pre>
        1792 * element.sendKeys("text was",
        1793 * webdriver.Key.CONTROL, "a", webdriver.Key.NULL,
        1794 * "now text is");
        1795 * // Alternatively:
        1796 * element.sendKeys("text was",
        1797 * webdriver.Key.chord(webdriver.Key.CONTROL, "a"),
        1798 * "now text is");
        1799 * </pre></code></li>
        1800 * <li>The end of the keysequence is encountered. When there are no more keys
        1801 * to type, all depressed modifier keys are released (with accompanying keyup
        1802 * events).
        1803 * </li>
        1804 * </ul>
        1805 * <strong>Note:</strong> On browsers where native keyboard events are not yet
        1806 * supported (e.g. Firefox on OS X), key events will be synthesized. Special
        1807 * punctionation keys will be synthesized according to a standard QWERTY en-us
        1808 * keyboard layout.
        1809 *
        1810 * @param {...string} var_args The sequence of keys to
        1811 * type. All arguments will be joined into a single sequence (var_args is
        1812 * permitted for convenience).
        1813 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1814 * when all keys have been typed.
        1815 */
        1816webdriver.WebElement.prototype.sendKeys = function(var_args) {
        1817 // Coerce every argument to a string. This protects us from users that
        1818 // ignore the jsdoc and give us a number (which ends up causing problems on
        1819 // the server, which requires strings).
        1820 var keys = webdriver.promise.fullyResolved(goog.array.slice(arguments, 0)).
        1821 then(function(args) {
        1822 return goog.array.map(goog.array.slice(args, 0), function(key) {
        1823 return key + '';
        1824 });
        1825 });
        1826 return this.schedule_(
        1827 new webdriver.Command(webdriver.CommandName.SEND_KEYS_TO_ELEMENT).
        1828 setParameter('value', keys),
        1829 'WebElement.sendKeys(' + keys + ')');
        1830};
        1831
        1832
        1833/**
        1834 * Schedules a command to query for the tag/node name of this element.
        1835 * @return {!webdriver.promise.Promise.<string>} A promise that will be
        1836 * resolved with the element's tag name.
        1837 */
        1838webdriver.WebElement.prototype.getTagName = function() {
        1839 return this.schedule_(
        1840 new webdriver.Command(webdriver.CommandName.GET_ELEMENT_TAG_NAME),
        1841 'WebElement.getTagName()');
        1842};
        1843
        1844
        1845/**
        1846 * Schedules a command to query for the computed style of the element
        1847 * represented by this instance. If the element inherits the named style from
        1848 * its parent, the parent will be queried for its value. Where possible, color
        1849 * values will be converted to their hex representation (e.g. #00ff00 instead of
        1850 * rgb(0, 255, 0)).
        1851 * <p/>
        1852 * <em>Warning:</em> the value returned will be as the browser interprets it, so
        1853 * it may be tricky to form a proper assertion.
        1854 *
        1855 * @param {string} cssStyleProperty The name of the CSS style property to look
        1856 * up.
        1857 * @return {!webdriver.promise.Promise.<string>} A promise that will be
        1858 * resolved with the requested CSS value.
        1859 */
        1860webdriver.WebElement.prototype.getCssValue = function(cssStyleProperty) {
        1861 var name = webdriver.CommandName.GET_ELEMENT_VALUE_OF_CSS_PROPERTY;
        1862 return this.schedule_(
        1863 new webdriver.Command(name).
        1864 setParameter('propertyName', cssStyleProperty),
        1865 'WebElement.getCssValue(' + cssStyleProperty + ')');
        1866};
        1867
        1868
        1869/**
        1870 * Schedules a command to query for the value of the given attribute of the
        1871 * element. Will return the current value, even if it has been modified after
        1872 * the page has been loaded. More exactly, this method will return the value of
        1873 * the given attribute, unless that attribute is not present, in which case the
        1874 * value of the property with the same name is returned. If neither value is
        1875 * set, null is returned (for example, the "value" property of a textarea
        1876 * element). The "style" attribute is converted as best can be to a
        1877 * text representation with a trailing semi-colon. The following are deemed to
        1878 * be "boolean" attributes and will return either "true" or null:
        1879 *
        1880 * <p>async, autofocus, autoplay, checked, compact, complete, controls, declare,
        1881 * defaultchecked, defaultselected, defer, disabled, draggable, ended,
        1882 * formnovalidate, hidden, indeterminate, iscontenteditable, ismap, itemscope,
        1883 * loop, multiple, muted, nohref, noresize, noshade, novalidate, nowrap, open,
        1884 * paused, pubdate, readonly, required, reversed, scoped, seamless, seeking,
        1885 * selected, spellcheck, truespeed, willvalidate
        1886 *
        1887 * <p>Finally, the following commonly mis-capitalized attribute/property names
        1888 * are evaluated as expected:
        1889 * <ul>
        1890 * <li>"class"
        1891 * <li>"readonly"
        1892 * </ul>
        1893 * @param {string} attributeName The name of the attribute to query.
        1894 * @return {!webdriver.promise.Promise.<?string>} A promise that will be
        1895 * resolved with the attribute's value. The returned value will always be
        1896 * either a string or null.
        1897 */
        1898webdriver.WebElement.prototype.getAttribute = function(attributeName) {
        1899 return this.schedule_(
        1900 new webdriver.Command(webdriver.CommandName.GET_ELEMENT_ATTRIBUTE).
        1901 setParameter('name', attributeName),
        1902 'WebElement.getAttribute(' + attributeName + ')');
        1903};
        1904
        1905
        1906/**
        1907 * Get the visible (i.e. not hidden by CSS) innerText of this element, including
        1908 * sub-elements, without any leading or trailing whitespace.
        1909 * @return {!webdriver.promise.Promise.<string>} A promise that will be
        1910 * resolved with the element's visible text.
        1911 */
        1912webdriver.WebElement.prototype.getText = function() {
        1913 return this.schedule_(
        1914 new webdriver.Command(webdriver.CommandName.GET_ELEMENT_TEXT),
        1915 'WebElement.getText()');
        1916};
        1917
        1918
        1919/**
        1920 * Schedules a command to compute the size of this element's bounding box, in
        1921 * pixels.
        1922 * @return {!webdriver.promise.Promise.<{width: number, height: number}>} A
        1923 * promise that will be resolved with the element's size as a
        1924 * {@code {width:number, height:number}} object.
        1925 */
        1926webdriver.WebElement.prototype.getSize = function() {
        1927 return this.schedule_(
        1928 new webdriver.Command(webdriver.CommandName.GET_ELEMENT_SIZE),
        1929 'WebElement.getSize()');
        1930};
        1931
        1932
        1933/**
        1934 * Schedules a command to compute the location of this element in page space.
        1935 * @return {!webdriver.promise.Promise.<{x: number, y: number}>} A promise that
        1936 * will be resolved to the element's location as a
        1937 * {@code {x:number, y:number}} object.
        1938 */
        1939webdriver.WebElement.prototype.getLocation = function() {
        1940 return this.schedule_(
        1941 new webdriver.Command(webdriver.CommandName.GET_ELEMENT_LOCATION),
        1942 'WebElement.getLocation()');
        1943};
        1944
        1945
        1946/**
        1947 * Schedules a command to query whether the DOM element represented by this
        1948 * instance is enabled, as dicted by the {@code disabled} attribute.
        1949 * @return {!webdriver.promise.Promise.<boolean>} A promise that will be
        1950 * resolved with whether this element is currently enabled.
        1951 */
        1952webdriver.WebElement.prototype.isEnabled = function() {
        1953 return this.schedule_(
        1954 new webdriver.Command(webdriver.CommandName.IS_ELEMENT_ENABLED),
        1955 'WebElement.isEnabled()');
        1956};
        1957
        1958
        1959/**
        1960 * Schedules a command to query whether this element is selected.
        1961 * @return {!webdriver.promise.Promise.<boolean>} A promise that will be
        1962 * resolved with whether this element is currently selected.
        1963 */
        1964webdriver.WebElement.prototype.isSelected = function() {
        1965 return this.schedule_(
        1966 new webdriver.Command(webdriver.CommandName.IS_ELEMENT_SELECTED),
        1967 'WebElement.isSelected()');
        1968};
        1969
        1970
        1971/**
        1972 * Schedules a command to submit the form containing this element (or this
        1973 * element if it is a FORM element). This command is a no-op if the element is
        1974 * not contained in a form.
        1975 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1976 * when the form has been submitted.
        1977 */
        1978webdriver.WebElement.prototype.submit = function() {
        1979 return this.schedule_(
        1980 new webdriver.Command(webdriver.CommandName.SUBMIT_ELEMENT),
        1981 'WebElement.submit()');
        1982};
        1983
        1984
        1985/**
        1986 * Schedules a command to clear the {@code value} of this element. This command
        1987 * has no effect if the underlying DOM element is neither a text INPUT element
        1988 * nor a TEXTAREA element.
        1989 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        1990 * when the element has been cleared.
        1991 */
        1992webdriver.WebElement.prototype.clear = function() {
        1993 return this.schedule_(
        1994 new webdriver.Command(webdriver.CommandName.CLEAR_ELEMENT),
        1995 'WebElement.clear()');
        1996};
        1997
        1998
        1999/**
        2000 * Schedules a command to test whether this element is currently displayed.
        2001 * @return {!webdriver.promise.Promise.<boolean>} A promise that will be
        2002 * resolved with whether this element is currently visible on the page.
        2003 */
        2004webdriver.WebElement.prototype.isDisplayed = function() {
        2005 return this.schedule_(
        2006 new webdriver.Command(webdriver.CommandName.IS_ELEMENT_DISPLAYED),
        2007 'WebElement.isDisplayed()');
        2008};
        2009
        2010
        2011/**
        2012 * Schedules a command to retrieve the outer HTML of this element.
        2013 * @return {!webdriver.promise.Promise.<string>} A promise that will be
        2014 * resolved with the element's outer HTML.
        2015 */
        2016webdriver.WebElement.prototype.getOuterHtml = function() {
        2017 return this.driver_.executeScript(function() {
        2018 var element = arguments[0];
        2019 if ('outerHTML' in element) {
        2020 return element.outerHTML;
        2021 } else {
        2022 var div = element.ownerDocument.createElement('div');
        2023 div.appendChild(element.cloneNode(true));
        2024 return div.innerHTML;
        2025 }
        2026 }, this);
        2027};
        2028
        2029
        2030/**
        2031 * Schedules a command to retrieve the inner HTML of this element.
        2032 * @return {!webdriver.promise.Promise.<string>} A promise that will be
        2033 * resolved with the element's inner HTML.
        2034 */
        2035webdriver.WebElement.prototype.getInnerHtml = function() {
        2036 return this.driver_.executeScript('return arguments[0].innerHTML', this);
        2037};
        2038
        2039
        2040
        2041/**
        2042 * WebElementPromise is a promise that will be fulfilled with a WebElement.
        2043 * This serves as a forward proxy on WebElement, allowing calls to be
        2044 * scheduled without directly on this instance before the underlying
        2045 * WebElement has been fulfilled. In other words, the following two statements
        2046 * are equivalent:
        2047 * <pre><code>
        2048 * driver.findElement({id: 'my-button'}).click();
        2049 * driver.findElement({id: 'my-button'}).then(function(el) {
        2050 * return el.click();
        2051 * });
        2052 * </code></pre>
        2053 *
        2054 * @param {!webdriver.WebDriver} driver The parent WebDriver instance for this
        2055 * element.
        2056 * @param {!webdriver.promise.Promise.<!webdriver.WebElement>} el A promise
        2057 * that will resolve to the promised element.
        2058 * @constructor
        2059 * @extends {webdriver.WebElement}
        2060 * @implements {webdriver.promise.Thenable.<!webdriver.WebElement>}
        2061 * @final
        2062 */
        2063webdriver.WebElementPromise = function(driver, el) {
        2064 webdriver.WebElement.call(this, driver, {'ELEMENT': 'unused'});
        2065
        2066 /** @override */
        2067 this.cancel = goog.bind(el.cancel, el);
        2068
        2069 /** @override */
        2070 this.isPending = goog.bind(el.isPending, el);
        2071
        2072 /** @override */
        2073 this.then = goog.bind(el.then, el);
        2074
        2075 /** @override */
        2076 this.thenCatch = goog.bind(el.thenCatch, el);
        2077
        2078 /** @override */
        2079 this.thenFinally = goog.bind(el.thenFinally, el);
        2080
        2081 /**
        2082 * Defers returning the element ID until the wrapped WebElement has been
        2083 * resolved.
        2084 * @override
        2085 */
        2086 this.getId = function() {
        2087 return el.then(function(el) {
        2088 return el.getId();
        2089 });
        2090 };
        2091};
        2092goog.inherits(webdriver.WebElementPromise, webdriver.WebElement);
        2093
        2094
        2095/**
        2096 * Represents a modal dialog such as {@code alert}, {@code confirm}, or
        2097 * {@code prompt}. Provides functions to retrieve the message displayed with
        2098 * the alert, accept or dismiss the alert, and set the response text (in the
        2099 * case of {@code prompt}).
        2100 * @param {!webdriver.WebDriver} driver The driver controlling the browser this
        2101 * alert is attached to.
        2102 * @param {string} text The message text displayed with this alert.
        2103 * @constructor
        2104 */
        2105webdriver.Alert = function(driver, text) {
        2106 /** @private {!webdriver.WebDriver} */
        2107 this.driver_ = driver;
        2108
        2109 /** @private {!webdriver.promise.Promise.<string>} */
        2110 this.text_ = webdriver.promise.when(text);
        2111};
        2112
        2113
        2114/**
        2115 * Retrieves the message text displayed with this alert. For instance, if the
        2116 * alert were opened with alert("hello"), then this would return "hello".
        2117 * @return {!webdriver.promise.Promise.<string>} A promise that will be
        2118 * resolved to the text displayed with this alert.
        2119 */
        2120webdriver.Alert.prototype.getText = function() {
        2121 return this.text_;
        2122};
        2123
        2124
        2125/**
        2126 * Accepts this alert.
        2127 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        2128 * when this command has completed.
        2129 */
        2130webdriver.Alert.prototype.accept = function() {
        2131 return this.driver_.schedule(
        2132 new webdriver.Command(webdriver.CommandName.ACCEPT_ALERT),
        2133 'WebDriver.switchTo().alert().accept()');
        2134};
        2135
        2136
        2137/**
        2138 * Dismisses this alert.
        2139 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        2140 * when this command has completed.
        2141 */
        2142webdriver.Alert.prototype.dismiss = function() {
        2143 return this.driver_.schedule(
        2144 new webdriver.Command(webdriver.CommandName.DISMISS_ALERT),
        2145 'WebDriver.switchTo().alert().dismiss()');
        2146};
        2147
        2148
        2149/**
        2150 * Sets the response text on this alert. This command will return an error if
        2151 * the underlying alert does not support response text (e.g. window.alert and
        2152 * window.confirm).
        2153 * @param {string} text The text to set.
        2154 * @return {!webdriver.promise.Promise.<void>} A promise that will be resolved
        2155 * when this command has completed.
        2156 */
        2157webdriver.Alert.prototype.sendKeys = function(text) {
        2158 return this.driver_.schedule(
        2159 new webdriver.Command(webdriver.CommandName.SET_ALERT_TEXT).
        2160 setParameter('text', text),
        2161 'WebDriver.switchTo().alert().sendKeys(' + text + ')');
        2162};
        2163
        2164
        2165
        2166/**
        2167 * AlertPromise is a promise that will be fulfilled with an Alert. This promise
        2168 * serves as a forward proxy on an Alert, allowing calls to be scheduled
        2169 * directly on this instance before the underlying Alert has been fulfilled. In
        2170 * other words, the following two statements are equivalent:
        2171 * <pre><code>
        2172 * driver.switchTo().alert().dismiss();
        2173 * driver.switchTo().alert().then(function(alert) {
        2174 * return alert.dismiss();
        2175 * });
        2176 * </code></pre>
        2177 *
        2178 * @param {!webdriver.WebDriver} driver The driver controlling the browser this
        2179 * alert is attached to.
        2180 * @param {!webdriver.promise.Thenable.<!webdriver.Alert>} alert A thenable
        2181 * that will be fulfilled with the promised alert.
        2182 * @constructor
        2183 * @extends {webdriver.Alert}
        2184 * @implements {webdriver.promise.Thenable.<!webdriver.Alert>}
        2185 * @final
        2186 */
        2187webdriver.AlertPromise = function(driver, alert) {
        2188 webdriver.Alert.call(this, driver, 'unused');
        2189
        2190 /** @override */
        2191 this.cancel = goog.bind(alert.cancel, alert);
        2192
        2193 /** @override */
        2194 this.isPending = goog.bind(alert.isPending, alert);
        2195
        2196 /** @override */
        2197 this.then = goog.bind(alert.then, alert);
        2198
        2199 /** @override */
        2200 this.thenCatch = goog.bind(alert.thenCatch, alert);
        2201
        2202 /** @override */
        2203 this.thenFinally = goog.bind(alert.thenFinally, alert);
        2204
        2205 /**
        2206 * Defer returning text until the promised alert has been resolved.
        2207 * @override
        2208 */
        2209 this.getText = function() {
        2210 return alert.then(function(alert) {
        2211 return alert.getText();
        2212 });
        2213 };
        2214
        2215 /**
        2216 * Defers action until the alert has been located.
        2217 * @override
        2218 */
        2219 this.accept = function() {
        2220 return alert.then(function(alert) {
        2221 return alert.accept();
        2222 });
        2223 };
        2224
        2225 /**
        2226 * Defers action until the alert has been located.
        2227 * @override
        2228 */
        2229 this.dismiss = function() {
        2230 return alert.then(function(alert) {
        2231 return alert.dismiss();
        2232 });
        2233 };
        2234
        2235 /**
        2236 * Defers action until the alert has been located.
        2237 * @override
        2238 */
        2239 this.sendKeys = function(text) {
        2240 return alert.then(function(alert) {
        2241 return alert.sendKeys(text);
        2242 });
        2243 };
        2244};
        2245goog.inherits(webdriver.AlertPromise, webdriver.Alert);
        2246
        2247
        2248
        2249/**
        2250 * An error returned to indicate that there is an unhandled modal dialog on the
        2251 * current page.
        2252 * @param {string} message The error message.
        2253 * @param {string} text The text displayed with the unhandled alert.
        2254 * @param {!webdriver.Alert} alert The alert handle.
        2255 * @constructor
        2256 * @extends {bot.Error}
        2257 */
        2258webdriver.UnhandledAlertError = function(message, text, alert) {
        2259 goog.base(this, bot.ErrorCode.UNEXPECTED_ALERT_OPEN, message);
        2260
        2261 /** @private {string} */
        2262 this.text_ = text;
        2263
        2264 /** @private {!webdriver.Alert} */
        2265 this.alert_ = alert;
        2266};
        2267goog.inherits(webdriver.UnhandledAlertError, bot.Error);
        2268
        2269
        2270/**
        2271 * @return {string} The text displayed with the unhandled alert.
        2272 */
        2273webdriver.UnhandledAlertError.prototype.getAlertText = function() {
        2274 return this.text_;
        2275};
        2276
        2277
        2278/**
        2279 * @return {!webdriver.Alert} The open alert.
        2280 * @deprecated Use {@link #getAlertText}. This method will be removed in
        2281 * 2.45.0.
        2282 */
        2283webdriver.UnhandledAlertError.prototype.getAlert = function() {
        2284 return this.alert_;
        2285};
        \ No newline at end of file diff --git a/docs/api/javascript/source/net/index.js.src.html b/docs/api/javascript/source/net/index.js.src.html index dbcd6444c349d..db63c9a9a438e 100644 --- a/docs/api/javascript/source/net/index.js.src.html +++ b/docs/api/javascript/source/net/index.js.src.html @@ -1 +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 interfaces = [getLoInterface()];
        45 }
        46 interfaces = interfaces || os.networkInterfaces();
        47 for (var key in interfaces) {
        48 interfaces[key].forEach(function(ipAddress) {
        49 if (ipAddress.family === family &&
        50 ipAddress.internal === loopback) {
        51 addresses.push(ipAddress.address);
        52 }
        53 });
        54 }
        55 return addresses[0];
        56}
        57
        58
        59// PUBLIC API
        60
        61
        62/**
        63 * Retrieves the external IP address for this host.
        64 * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4".
        65 * @return {string} The IP address or undefined if not available.
        66 */
        67exports.getAddress = function(opt_family) {
        68 return getAddress(false, opt_family);
        69};
        70
        71
        72/**
        73 * Retrieves a loopback address for this machine.
        74 * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4".
        75 * @return {string} The IP address or undefined if not available.
        76 */
        77exports.getLoopbackAddress = function(opt_family) {
        78 return getAddress(true, opt_family);
        79};
        \ No newline at end of file +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/docs/api/javascript/source/net/portprober.js.src.html b/docs/api/javascript/source/net/portprober.js.src.html index 115b0c97c30ea..c4667da14dc09 100644 --- a/docs/api/javascript/source/net/portprober.js.src.html +++ b/docs/api/javascript/source/net/portprober.js.src.html @@ -1 +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 +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/docs/api/javascript/source/phantomjs.js.src.html b/docs/api/javascript/source/phantomjs.js.src.html index 8988c7d39b034..4fbff7aba85f1 100644 --- a/docs/api/javascript/source/phantomjs.js.src.html +++ b/docs/api/javascript/source/phantomjs.js.src.html @@ -1 +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 +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 executors = require('./executors'),
        23 io = require('./io'),
        24 portprober = require('./net/portprober'),
        25 remote = require('./remote');
        26
        27
        28/**
        29 * Name of the PhantomJS executable.
        30 * @type {string}
        31 * @const
        32 */
        33var PHANTOMJS_EXE =
        34 process.platform === 'win32' ? 'phantomjs.exe' : 'phantomjs';
        35
        36
        37/**
        38 * Capability that designates the location of the PhantomJS executable to use.
        39 * @type {string}
        40 * @const
        41 */
        42var BINARY_PATH_CAPABILITY = 'phantomjs.binary.path';
        43
        44
        45/**
        46 * Capability that designates the CLI arguments to pass to PhantomJS.
        47 * @type {string}
        48 * @const
        49 */
        50var CLI_ARGS_CAPABILITY = 'phantomjs.cli.args';
        51
        52
        53/**
        54 * Default log file to use if one is not specified through CLI args.
        55 * @type {string}
        56 * @const
        57 */
        58var DEFAULT_LOG_FILE = 'phantomjsdriver.log';
        59
        60
        61/**
        62 * Finds the PhantomJS executable.
        63 * @param {string=} opt_exe Path to the executable to use.
        64 * @return {string} The located executable.
        65 * @throws {Error} If the executable cannot be found on the PATH, or if the
        66 * provided executable path does not exist.
        67 */
        68function findExecutable(opt_exe) {
        69 var exe = opt_exe || io.findInPath(PHANTOMJS_EXE, true);
        70 if (!exe) {
        71 throw Error(
        72 'The PhantomJS executable could not be found on the current PATH. ' +
        73 'Please download the latest version from ' +
        74 'http://phantomjs.org/download.html and ensure it can be found on ' +
        75 'your PATH. For more information, see ' +
        76 'https://github.com/ariya/phantomjs/wiki');
        77 }
        78 if (!fs.existsSync(exe)) {
        79 throw Error('File does not exist: ' + exe);
        80 }
        81 return exe;
        82}
        83
        84
        85/**
        86 * Maps WebDriver logging level name to those recognised by PhantomJS.
        87 * @type {!Object.<string, string>}
        88 * @const
        89 */
        90var WEBDRIVER_TO_PHANTOMJS_LEVEL = (function() {
        91 var map = {};
        92 map[webdriver.logging.Level.ALL.name] = 'DEBUG';
        93 map[webdriver.logging.Level.DEBUG.name] = 'DEBUG';
        94 map[webdriver.logging.Level.INFO.name] = 'INFO';
        95 map[webdriver.logging.Level.WARNING.name] = 'WARN';
        96 map[webdriver.logging.Level.SEVERE.name] = '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 * @param {webdriver.promise.ControlFlow=} opt_flow The control flow to use, or
        105 * {@code null} to use the currently active flow.
        106 * @return {!webdriver.WebDriver} A new WebDriver instance.
        107 * @deprecated Use {@link Driver}.
        108 */
        109function createDriver(opt_capabilities, opt_flow) {
        110 return new Driver(opt_capabilities, opt_flow);
        111}
        112
        113
        114/**
        115 * Creates a new WebDriver client for PhantomJS.
        116 *
        117 * @param {webdriver.Capabilities=} opt_capabilities The desired capabilities.
        118 * @param {webdriver.promise.ControlFlow=} opt_flow The control flow to use, or
        119 * {@code null} to use the currently active flow.
        120 * @constructor
        121 * @extends {webdriver.WebDriver}
        122 */
        123var Driver = function(opt_capabilities, opt_flow) {
        124 var capabilities = opt_capabilities || webdriver.Capabilities.phantomjs();
        125 var exe = findExecutable(capabilities.get(BINARY_PATH_CAPABILITY));
        126 var args = ['--webdriver-logfile=' + DEFAULT_LOG_FILE];
        127
        128 var logPrefs = capabilities.get(webdriver.Capability.LOGGING_PREFS);
        129 if (logPrefs instanceof webdriver.logging.Preferences) {
        130 logPrefs = logPrefs.toJSON();
        131 }
        132
        133 if (logPrefs && logPrefs[webdriver.logging.Type.DRIVER]) {
        134 var level = WEBDRIVER_TO_PHANTOMJS_LEVEL[
        135 logPrefs[webdriver.logging.Type.DRIVER]];
        136 if (level) {
        137 args.push('--webdriver-loglevel=' + level);
        138 }
        139 }
        140
        141 var proxy = capabilities.get(webdriver.Capability.PROXY);
        142 if (proxy) {
        143 switch (proxy.proxyType) {
        144 case 'manual':
        145 if (proxy.httpProxy) {
        146 args.push(
        147 '--proxy-type=http',
        148 '--proxy=http://' + proxy.httpProxy);
        149 }
        150 break;
        151 case 'pac':
        152 throw Error('PhantomJS does not support Proxy PAC files');
        153 case 'system':
        154 args.push('--proxy-type=system');
        155 break;
        156 case 'direct':
        157 args.push('--proxy-type=none');
        158 break;
        159 }
        160 }
        161 args = args.concat(capabilities.get(CLI_ARGS_CAPABILITY) || []);
        162
        163 var port = portprober.findFreePort();
        164 var service = new remote.DriverService(exe, {
        165 port: port,
        166 args: webdriver.promise.when(port, function(port) {
        167 args.push('--webdriver=' + port);
        168 return args;
        169 })
        170 });
        171
        172 var executor = executors.createExecutor(service.start());
        173 var driver = webdriver.WebDriver.createSession(
        174 executor, capabilities, opt_flow);
        175
        176 webdriver.WebDriver.call(
        177 this, driver.getSession(), executor, driver.controlFlow());
        178
        179 var boundQuit = this.quit.bind(this);
        180
        181 /** @override */
        182 this.quit = function() {
        183 return boundQuit().thenFinally(service.kill.bind(service));
        184 };
        185 return driver;
        186};
        187util.inherits(Driver, webdriver.WebDriver);
        188
        189
        190// PUBLIC API
        191
        192exports.Driver = Driver;
        193exports.createDriver = createDriver;
        \ No newline at end of file diff --git a/docs/api/javascript/source/proxy.js.src.html b/docs/api/javascript/source/proxy.js.src.html index 70d3c1d13de85..90edf0dbf77f4 100644 --- a/docs/api/javascript/source/proxy.js.src.html +++ b/docs/api/javascript/source/proxy.js.src.html @@ -1 +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 +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// PUBLIC API
        35
        36
        37/**
        38 * Configures WebDriver to bypass all browser proxies.
        39 * @return {!webdriver.ProxyConfig} A new proxy configuration object.
        40 */
        41exports.direct = function() {
        42 return {proxyType: 'direct'};
        43};
        44
        45
        46/**
        47 * Manually configures the browser proxy. The following options are
        48 * supported:
        49 * <ul>
        50 * <li>{@code ftp}: Proxy host to use for FTP requests
        51 * <li>{@code http}: Proxy host to use for HTTP requests
        52 * <li>{@code https}: Proxy host to use for HTTPS requests
        53 * <li>{@code bypass}: A list of hosts requests should directly connect to,
        54 * bypassing any other proxies for that request. May be specified as a
        55 * comma separated string, or a list of strings.
        56 * </ul>
        57 *
        58 * Behavior is undefined for FTP, HTTP, and HTTPS requests if the
        59 * corresponding key is omitted from the configuration options.
        60 *
        61 * @param {{ftp: (string|undefined),
        62 * http: (string|undefined),
        63 * https: (string|undefined),
        64 * bypass: (string|!Array.<string>|undefined)}} options Proxy
        65 * configuration options.
        66 * @return {!webdriver.ProxyConfig} A new proxy configuration object.
        67 */
        68exports.manual = function(options) {
        69 return {
        70 proxyType: 'manual',
        71 ftpProxy: options.ftp,
        72 httpProxy: options.http,
        73 sslProxy: options.https,
        74 noProxy: util.isArray(options.bypass) ?
        75 options.bypass.join(',') : options.bypass
        76 };
        77};
        78
        79
        80/**
        81 * Configures WebDriver to configure the browser proxy using the PAC file at
        82 * the given URL.
        83 * @param {string} url URL for the PAC proxy to use.
        84 * @return {!webdriver.ProxyConfig} A new proxy configuration object.
        85 */
        86exports.pac = function(url) {
        87 return {
        88 proxyType: 'pac',
        89 proxyAutoconfigUrl: url
        90 };
        91};
        92
        93
        94/**
        95 * Configures WebDriver to use the current system's proxy.
        96 * @return {!webdriver.ProxyConfig} A new proxy configuration object.
        97 */
        98exports.system = function() {
        99 return {proxyType: 'system'};
        100};
        \ No newline at end of file diff --git a/docs/api/javascript/source/remote/index.js.src.html b/docs/api/javascript/source/remote/index.js.src.html index 7ba3bf28ebf07..870271adba118 100644 --- a/docs/api/javascript/source/remote/index.js.src.html +++ b/docs/api/javascript/source/remote/index.js.src.html @@ -1 +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 +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 path = require('path'),
        18 url = require('url'),
        19 util = require('util');
        20
        21var promise = require('../').promise,
        22 httpUtil = require('../http/util'),
        23 exec = require('../io/exec'),
        24 net = require('../net'),
        25 portprober = require('../net/portprober');
        26
        27
        28
        29/**
        30 * Configuration options for a DriverService instance.
        31 * <ul>
        32 * <li>
        33 * <li>{@code loopback} - Whether the service should only be accessed on this
        34 * host's loopback address.
        35 * <li>{@code port} - The port to start the server on (must be > 0). If the
        36 * port is provided as a promise, the service will wait for the promise to
        37 * resolve before starting.
        38 * <li>{@code args} - The arguments to pass to the service. If a promise is
        39 * provided, the service will wait for it to resolve before starting.
        40 * <li>{@code path} - The base path on the server for the WebDriver wire
        41 * protocol (e.g. '/wd/hub'). Defaults to '/'.
        42 * <li>{@code env} - The environment variables that should be visible to the
        43 * server process. Defaults to inheriting the current process's
        44 * environment.
        45 * <li>{@code stdio} - IO configuration for the spawned server process. For
        46 * more information, refer to the documentation of
        47 * {@code child_process.spawn}.
        48 * </ul>
        49 *
        50 * @typedef {{
        51 * port: (number|!webdriver.promise.Promise.<number>),
        52 * args: !(Array.<string>|webdriver.promise.Promise.<!Array.<string>>),
        53 * path: (string|undefined),
        54 * env: (!Object.<string, string>|undefined),
        55 * stdio: (string|!Array.<string|number|!Stream|null|undefined>|undefined)
        56 * }}
        57 */
        58var ServiceOptions;
        59
        60
        61/**
        62 * Manages the life and death of a native executable WebDriver server.
        63 *
        64 * <p>It is expected that the driver server implements the
        65 * <a href="http://code.google.com/p/selenium/wiki/JsonWireProtocol">WebDriver
        66 * Wire Protocol</a>. Furthermore, the managed server should support multiple
        67 * concurrent sessions, so that this class may be reused for multiple clients.
        68 *
        69 * @param {string} executable Path to the executable to run.
        70 * @param {!ServiceOptions} options Configuration options for the service.
        71 * @constructor
        72 */
        73function DriverService(executable, options) {
        74
        75 /** @private {string} */
        76 this.executable_ = executable;
        77
        78 /** @private {boolean} */
        79 this.loopbackOnly_ = !!options.loopback;
        80
        81 /** @private {(number|!webdriver.promise.Promise.<number>)} */
        82 this.port_ = options.port;
        83
        84 /**
        85 * @private {!(Array.<string>|webdriver.promise.Promise.<!Array.<string>>)}
        86 */
        87 this.args_ = options.args;
        88
        89 /** @private {string} */
        90 this.path_ = options.path || '/';
        91
        92 /** @private {!Object.<string, string>} */
        93 this.env_ = options.env || process.env;
        94
        95 /** @private {(string|!Array.<string|number|!Stream|null|undefined>)} */
        96 this.stdio_ = options.stdio || 'ignore';
        97
        98 /**
        99 * A promise for the managed subprocess, or null if the server has not been
        100 * started yet. This promise will never be rejected.
        101 * @private {promise.Promise.<!exec.Command>}
        102 */
        103 this.command_ = null;
        104
        105 /**
        106 * Promise that resolves to the server's address or null if the server has
        107 * not been started. This promise will be rejected if the server terminates
        108 * before it starts accepting WebDriver requests.
        109 * @private {promise.Promise.<string>}
        110 */
        111 this.address_ = null;
        112}
        113
        114
        115/**
        116 * The default amount of time, in milliseconds, to wait for the server to
        117 * start.
        118 * @type {number}
        119 */
        120DriverService.DEFAULT_START_TIMEOUT_MS = 30 * 1000;
        121
        122
        123/**
        124 * @return {!webdriver.promise.Promise.<string>} A promise that resolves to
        125 * the server's address.
        126 * @throws {Error} If the server has not been started.
        127 */
        128DriverService.prototype.address = function() {
        129 if (this.address_) {
        130 return this.address_;
        131 }
        132 throw Error('Server has not been started.');
        133};
        134
        135
        136/**
        137 * Returns whether the underlying process is still running. This does not take
        138 * into account whether the process is in the process of shutting down.
        139 * @return {boolean} Whether the underlying service process is running.
        140 */
        141DriverService.prototype.isRunning = function() {
        142 return !!this.address_;
        143};
        144
        145
        146/**
        147 * Starts the server if it is not already running.
        148 * @param {number=} opt_timeoutMs How long to wait, in milliseconds, for the
        149 * server to start accepting requests. Defaults to 30 seconds.
        150 * @return {!promise.Promise.<string>} A promise that will resolve
        151 * to the server's base URL when it has started accepting requests. If the
        152 * timeout expires before the server has started, the promise will be
        153 * rejected.
        154 */
        155DriverService.prototype.start = function(opt_timeoutMs) {
        156 if (this.address_) {
        157 return this.address_;
        158 }
        159
        160 var timeout = opt_timeoutMs || DriverService.DEFAULT_START_TIMEOUT_MS;
        161
        162 var self = this;
        163 this.command_ = promise.defer();
        164 this.address_ = promise.defer();
        165 this.address_.fulfill(promise.when(this.port_, function(port) {
        166 if (port <= 0) {
        167 throw Error('Port must be > 0: ' + port);
        168 }
        169 return promise.when(self.args_, function(args) {
        170 var command = exec(self.executable_, {
        171 args: args,
        172 env: self.env_,
        173 stdio: self.stdio_
        174 });
        175
        176 self.command_.fulfill(command);
        177
        178 command.result().then(function(result) {
        179 self.address_.reject(result.code == null ?
        180 Error('Server was killed with ' + result.signal) :
        181 Error('Server exited with ' + result.code));
        182 self.address_ = null;
        183 self.command_ = null;
        184 });
        185
        186 var serverUrl = url.format({
        187 protocol: 'http',
        188 hostname: !self.loopbackOnly_ && net.getAddress() ||
        189 net.getLoopbackAddress(),
        190 port: port,
        191 pathname: self.path_
        192 });
        193
        194 return httpUtil.waitForServer(serverUrl, timeout).then(function() {
        195 return serverUrl;
        196 });
        197 });
        198 }));
        199
        200 return this.address_;
        201};
        202
        203
        204/**
        205 * Stops the service if it is not currently running. This function will kill
        206 * the server immediately. To synchronize with the active control flow, use
        207 * {@link #stop()}.
        208 * @return {!webdriver.promise.Promise} A promise that will be resolved when
        209 * the server has been stopped.
        210 */
        211DriverService.prototype.kill = function() {
        212 if (!this.address_ || !this.command_) {
        213 return promise.fulfilled(); // Not currently running.
        214 }
        215 return this.command_.then(function(command) {
        216 command.kill('SIGTERM');
        217 });
        218};
        219
        220
        221/**
        222 * Schedules a task in the current control flow to stop the server if it is
        223 * currently running.
        224 * @return {!webdriver.promise.Promise} A promise that will be resolved when
        225 * the server has been stopped.
        226 */
        227DriverService.prototype.stop = function() {
        228 return promise.controlFlow().execute(this.kill.bind(this));
        229};
        230
        231
        232
        233/**
        234 * Manages the life and death of the Selenium standalone server. The server
        235 * may be obtained from http://selenium-release.storage.googleapis.com/index.html.
        236 * @param {string} jar Path to the Selenium server jar.
        237 * @param {!SeleniumServer.Options} options Configuration options for the
        238 * server.
        239 * @throws {Error} If an invalid port is specified.
        240 * @constructor
        241 * @extends {DriverService}
        242 */
        243function SeleniumServer(jar, options) {
        244 if (options.port < 0)
        245 throw Error('Port must be >= 0: ' + options.port);
        246
        247 var port = options.port || portprober.findFreePort();
        248 var args = promise.when(options.jvmArgs || [], function(jvmArgs) {
        249 return promise.when(options.args || [], function(args) {
        250 return promise.when(port, function(port) {
        251 return jvmArgs.concat(['-jar', jar, '-port', port]).concat(args);
        252 });
        253 });
        254 });
        255
        256 DriverService.call(this, 'java', {
        257 port: port,
        258 args: args,
        259 path: '/wd/hub',
        260 env: options.env,
        261 stdio: options.stdio
        262 });
        263}
        264util.inherits(SeleniumServer, DriverService);
        265
        266
        267/**
        268 * Options for the Selenium server:
        269 * <ul>
        270 * <li>{@code port} - The port to start the server on (must be > 0). If the
        271 * port is provided as a promise, the service will wait for the promise to
        272 * resolve before starting.
        273 * <li>{@code args} - The arguments to pass to the service. If a promise is
        274 * provided, the service will wait for it to resolve before starting.
        275 * <li>{@code jvmArgs} - The arguments to pass to the JVM. If a promise is
        276 * provided, the service will wait for it to resolve before starting.
        277 * <li>{@code env} - The environment variables that should be visible to the
        278 * server process. Defaults to inheriting the current process's
        279 * environment.
        280 * <li>{@code stdio} - IO configuration for the spawned server process. For
        281 * more information, refer to the documentation of
        282 * {@code child_process.spawn}.
        283 * </ul>
        284 *
        285 * @typedef {{
        286 * port: (number|!webdriver.promise.Promise.<number>),
        287 * args: !(Array.<string>|webdriver.promise.Promise.<!Array.<string>>),
        288 * jvmArgs: (!Array.<string>|
        289 * !webdriver.promise.Promise.<!Array.<string>>|
        290 * undefined),
        291 * env: (!Object.<string, string>|undefined),
        292 * stdio: (string|!Array.<string|number|!Stream|null|undefined>|undefined)
        293 * }}
        294 */
        295SeleniumServer.Options;
        296
        297
        298// PUBLIC API
        299
        300exports.DriverService = DriverService;
        301exports.SeleniumServer = SeleniumServer;
        \ No newline at end of file diff --git a/docs/api/javascript/source/testing/assert.js.src.html b/docs/api/javascript/source/testing/assert.js.src.html index 125141da01c54..9869371dec86d 100644 --- a/docs/api/javascript/source/testing/assert.js.src.html +++ b/docs/api/javascript/source/testing/assert.js.src.html @@ -1 +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 +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/docs/api/javascript/source/testing/index.js.src.html b/docs/api/javascript/source/testing/index.js.src.html index c2f4cf90ea095..328152b0ef837 100644 --- a/docs/api/javascript/source/testing/index.js.src.html +++ b/docs/api/javascript/source/testing/index.js.src.html @@ -1 +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 webdriver.promise.ControlFlow to
        31 * 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 flow = require('..').promise.controlFlow();
        84
        85
        86/**
        87 * Wraps a function so that all passed arguments are ignored.
        88 * @param {!Function} fn The function to wrap.
        89 * @return {!Function} The wrapped function.
        90 */
        91function seal(fn) {
        92 return function() {
        93 fn();
        94 };
        95}
        96
        97
        98/**
        99 * Wraps a function on Mocha's BDD interface so it runs inside a
        100 * webdriver.promise.ControlFlow and waits for the flow to complete before
        101 * continuing.
        102 * @param {!Function} globalFn The function to wrap.
        103 * @return {!Function} The new function.
        104 */
        105function wrapped(globalFn) {
        106 return function() {
        107 switch (arguments.length) {
        108 case 1:
        109 globalFn(asyncTestFn(arguments[0]));
        110 break;
        111
        112 case 2:
        113 globalFn(arguments[0], asyncTestFn(arguments[1]));
        114 break;
        115
        116 default:
        117 throw Error('Invalid # arguments: ' + arguments.length);
        118 }
        119 };
        120
        121 function asyncTestFn(fn) {
        122 var ret = function(done) {
        123 this.timeout(0);
        124 var timeout = this.timeout;
        125 this.timeout = undefined; // Do not let tests change the timeout.
        126 try {
        127 flow.execute(fn.bind(this)).then(seal(done), done);
        128 } finally {
        129 this.timeout = timeout;
        130 }
        131 };
        132
        133 ret.toString = function() {
        134 return fn.toString();
        135 };
        136
        137 return ret;
        138 }
        139}
        140
        141
        142/**
        143 * Ignores the test chained to this function if the provided predicate returns
        144 * true.
        145 * @param {function(): boolean} predicateFn A predicate to call to determine
        146 * if the test should be suppressed. This function MUST be synchronous.
        147 * @return {!Object} An object with wrapped versions of {@link #it()} and
        148 * {@link #describe()} that ignore tests as indicated by the predicate.
        149 */
        150function ignore(predicateFn) {
        151 var describe = wrap(exports.xdescribe, exports.describe);
        152 describe.only = wrap(exports.xdescribe, exports.describe.only);
        153
        154 var it = wrap(exports.xit, exports.it);
        155 it.only = wrap(exports.xit, exports.it.only);
        156
        157 return {
        158 describe: describe,
        159 it: it
        160 };
        161
        162 function wrap(onSkip, onRun) {
        163 return function(title, fn) {
        164 if (predicateFn()) {
        165 onSkip(title, fn);
        166 } else {
        167 onRun(title, fn);
        168 }
        169 };
        170 }
        171}
        172
        173
        174// PUBLIC API
        175
        176/**
        177 * Registers a new test suite.
        178 * @param {string} name The suite name.
        179 * @param {function()=} fn The suite function, or {@code undefined} to define
        180 * a pending test suite.
        181 */
        182exports.describe = global.describe;
        183
        184/**
        185 * Defines a suppressed test suite.
        186 * @param {string} name The suite name.
        187 * @param {function()=} fn The suite function, or {@code undefined} to define
        188 * a pending test suite.
        189 */
        190exports.xdescribe = global.xdescribe;
        191exports.describe.skip = global.describe.skip;
        192
        193/**
        194 * Register a function to call after the current suite finishes.
        195 * @param {function()} fn .
        196 */
        197exports.after = wrapped(global.after);
        198
        199/**
        200 * Register a function to call after each test in a suite.
        201 * @param {function()} fn .
        202 */
        203exports.afterEach = wrapped(global.afterEach);
        204
        205/**
        206 * Register a function to call before the current suite starts.
        207 * @param {function()} fn .
        208 */
        209exports.before = wrapped(global.before);
        210
        211/**
        212 * Register a function to call before each test in a suite.
        213 * @param {function()} fn .
        214 */
        215exports.beforeEach = wrapped(global.beforeEach);
        216
        217/**
        218 * Add a test to the current suite.
        219 * @param {string} name The test name.
        220 * @param {function()=} fn The test function, or {@code undefined} to define
        221 * a pending test case.
        222 */
        223exports.it = wrapped(global.it);
        224
        225/**
        226 * An alias for {@link #it()} that flags the test as the only one that should
        227 * be run within the current suite.
        228 * @param {string} name The test name.
        229 * @param {function()=} fn The test function, or {@code undefined} to define
        230 * a pending test case.
        231 */
        232exports.iit = exports.it.only = wrapped(global.it.only);
        233
        234/**
        235 * Adds a test to the current suite while suppressing it so it is not run.
        236 * @param {string} name The test name.
        237 * @param {function()=} fn The test function, or {@code undefined} to define
        238 * a pending test case.
        239 */
        240exports.xit = exports.it.skip = wrapped(global.xit);
        241
        242exports.ignore = ignore;
        \ No newline at end of file +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 if (arguments.length === 1) {
        109 return globalFn(asyncTestFn(arguments[0]));
        110 }
        111 else if (arguments.length === 2) {
        112 return globalFn(arguments[0], asyncTestFn(arguments[1]));
        113 }
        114 else {
        115 throw Error('Invalid # arguments: ' + arguments.length);
        116 }
        117 };
        118
        119 function asyncTestFn(fn) {
        120 var ret = function(done) {
        121 function cleanupBeforeCallback() {
        122 flow.reset();
        123 return cleanupBeforeCallback.mochaCallback.apply(this, arguments);
        124 }
        125 // We set this as an attribute of the callback function to allow us to
        126 // test this properly.
        127 cleanupBeforeCallback.mochaCallback = this.runnable().callback;
        128
        129 this.runnable().callback = cleanupBeforeCallback;
        130
        131 var testFn = fn.bind(this);
        132 flow.execute(function() {
        133 var done = promise.defer();
        134 promise.asap(testFn(done.reject), done.fulfill, done.reject);
        135 return done.promise;
        136 }).then(seal(done), done);
        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/docs/api/javascript/types.js b/docs/api/javascript/types.js index 297d14a2145e4..429f3d7bc2ea4 100644 --- a/docs/api/javascript/types.js +++ b/docs/api/javascript/types.js @@ -1 +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":"docs/dossier.js","href":"source/docs/dossier.js.src.html"},{"name":"docs/types.js","href":"source/docs/types.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/docs/dossier","types":[],"href":"module_selenium-webdriver_docs_dossier.html"},{"name":"selenium-webdriver/docs/types","types":[],"href":"module_selenium-webdriver_docs_types.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 +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":"firefox/binary.js","href":"source/firefox/binary.js.src.html"},{"name":"firefox/extension.js","href":"source/firefox/extension.js.src.html"},{"name":"firefox/index.js","href":"source/firefox/index.js.src.html"},{"name":"firefox/profile.js","href":"source/firefox/profile.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/exec.js","href":"source/io/exec.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/async/nexttick.js","href":"source/lib/goog/async/nexttick.js.src.html"},{"name":"lib/goog/async/run.js","href":"source/lib/goog/async/run.js.src.html"},{"name":"lib/goog/base.js","href":"source/lib/goog/base.js.src.html"},{"name":"lib/goog/debug/debug.js","href":"source/lib/goog/debug/debug.js.src.html"},{"name":"lib/goog/debug/entrypointregistry.js","href":"source/lib/goog/debug/entrypointregistry.js.src.html"},{"name":"lib/goog/debug/error.js","href":"source/lib/goog/debug/error.js.src.html"},{"name":"lib/goog/debug/logbuffer.js","href":"source/lib/goog/debug/logbuffer.js.src.html"},{"name":"lib/goog/debug/logger.js","href":"source/lib/goog/debug/logger.js.src.html"},{"name":"lib/goog/debug/logrecord.js","href":"source/lib/goog/debug/logrecord.js.src.html"},{"name":"lib/goog/deps.js","href":"source/lib/goog/deps.js.src.html"},{"name":"lib/goog/disposable/disposable.js","href":"source/lib/goog/disposable/disposable.js.src.html"},{"name":"lib/goog/disposable/idisposable.js","href":"source/lib/goog/disposable/idisposable.js.src.html"},{"name":"lib/goog/dom/browserfeature.js","href":"source/lib/goog/dom/browserfeature.js.src.html"},{"name":"lib/goog/dom/dom.js","href":"source/lib/goog/dom/dom.js.src.html"},{"name":"lib/goog/dom/nodetype.js","href":"source/lib/goog/dom/nodetype.js.src.html"},{"name":"lib/goog/dom/tagname.js","href":"source/lib/goog/dom/tagname.js.src.html"},{"name":"lib/goog/dom/vendor.js","href":"source/lib/goog/dom/vendor.js.src.html"},{"name":"lib/goog/events/browserevent.js","href":"source/lib/goog/events/browserevent.js.src.html"},{"name":"lib/goog/events/browserfeature.js","href":"source/lib/goog/events/browserfeature.js.src.html"},{"name":"lib/goog/events/event.js","href":"source/lib/goog/events/event.js.src.html"},{"name":"lib/goog/events/eventid.js","href":"source/lib/goog/events/eventid.js.src.html"},{"name":"lib/goog/events/events.js","href":"source/lib/goog/events/events.js.src.html"},{"name":"lib/goog/events/eventtarget.js","href":"source/lib/goog/events/eventtarget.js.src.html"},{"name":"lib/goog/events/eventtype.js","href":"source/lib/goog/events/eventtype.js.src.html"},{"name":"lib/goog/events/keycodes.js","href":"source/lib/goog/events/keycodes.js.src.html"},{"name":"lib/goog/events/listenable.js","href":"source/lib/goog/events/listenable.js.src.html"},{"name":"lib/goog/events/listener.js","href":"source/lib/goog/events/listener.js.src.html"},{"name":"lib/goog/events/listenermap.js","href":"source/lib/goog/events/listenermap.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/box.js","href":"source/lib/goog/math/box.js.src.html"},{"name":"lib/goog/math/coordinate.js","href":"source/lib/goog/math/coordinate.js.src.html"},{"name":"lib/goog/math/math.js","href":"source/lib/goog/math/math.js.src.html"},{"name":"lib/goog/math/rect.js","href":"source/lib/goog/math/rect.js.src.html"},{"name":"lib/goog/math/size.js","href":"source/lib/goog/math/size.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/reflect/reflect.js","href":"source/lib/goog/reflect/reflect.js.src.html"},{"name":"lib/goog/string/string.js","href":"source/lib/goog/string/string.js.src.html"},{"name":"lib/goog/structs/collection.js","href":"source/lib/goog/structs/collection.js.src.html"},{"name":"lib/goog/structs/map.js","href":"source/lib/goog/structs/map.js.src.html"},{"name":"lib/goog/structs/set.js","href":"source/lib/goog/structs/set.js.src.html"},{"name":"lib/goog/structs/structs.js","href":"source/lib/goog/structs/structs.js.src.html"},{"name":"lib/goog/style/style.js","href":"source/lib/goog/style/style.js.src.html"},{"name":"lib/goog/testing/asserts.js","href":"source/lib/goog/testing/asserts.js.src.html"},{"name":"lib/goog/testing/asynctestcase.js","href":"source/lib/goog/testing/asynctestcase.js.src.html"},{"name":"lib/goog/testing/events/events.js","href":"source/lib/goog/testing/events/events.js.src.html"},{"name":"lib/goog/testing/functionmock.js","href":"source/lib/goog/testing/functionmock.js.src.html"},{"name":"lib/goog/testing/jsunit.js","href":"source/lib/goog/testing/jsunit.js.src.html"},{"name":"lib/goog/testing/loosemock.js","href":"source/lib/goog/testing/loosemock.js.src.html"},{"name":"lib/goog/testing/mock.js","href":"source/lib/goog/testing/mock.js.src.html"},{"name":"lib/goog/testing/mockclock.js","href":"source/lib/goog/testing/mockclock.js.src.html"},{"name":"lib/goog/testing/mockcontrol.js","href":"source/lib/goog/testing/mockcontrol.js.src.html"},{"name":"lib/goog/testing/mockinterface.js","href":"source/lib/goog/testing/mockinterface.js.src.html"},{"name":"lib/goog/testing/mockmatchers.js","href":"source/lib/goog/testing/mockmatchers.js.src.html"},{"name":"lib/goog/testing/objectpropertystring.js","href":"source/lib/goog/testing/objectpropertystring.js.src.html"},{"name":"lib/goog/testing/propertyreplacer.js","href":"source/lib/goog/testing/propertyreplacer.js.src.html"},{"name":"lib/goog/testing/recordfunction.js","href":"source/lib/goog/testing/recordfunction.js.src.html"},{"name":"lib/goog/testing/stacktrace.js","href":"source/lib/goog/testing/stacktrace.js.src.html"},{"name":"lib/goog/testing/strictmock.js","href":"source/lib/goog/testing/strictmock.js.src.html"},{"name":"lib/goog/testing/testcase.js","href":"source/lib/goog/testing/testcase.js.src.html"},{"name":"lib/goog/testing/testrunner.js","href":"source/lib/goog/testing/testrunner.js.src.html"},{"name":"lib/goog/testing/watchers.js","href":"source/lib/goog/testing/watchers.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/testing/testcase.js","href":"source/lib/webdriver/testing/testcase.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":"PRIMITIVE_EQUALITY_PREDICATES","isTypedef":false,"href":"namespace_PRIMITIVE_EQUALITY_PREDICATES.html"},{"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.Disposable","isTypedef":false,"href":"class_goog_Disposable.html"},{"isInterface":false,"name":"goog.Disposable.MonitoringMode","isTypedef":false,"href":"enum_goog_Disposable_MonitoringMode.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.async","isTypedef":false,"href":"namespace_goog_async.html"},{"isInterface":false,"name":"goog.async.nextTick","isTypedef":false,"href":"namespace_goog_async_nextTick.html"},{"isInterface":false,"name":"goog.async.run","isTypedef":false,"href":"namespace_goog_async_run.html"},{"isInterface":false,"name":"goog.async.run.WorkItem_","isTypedef":false,"href":"class_goog_async_run_WorkItem_.html"},{"isInterface":false,"name":"goog.debug","isTypedef":false,"href":"namespace_goog_debug.html"},{"name":"goog.debug.Loggable","isTypedef":true,"href":"namespace_goog_debug.html#goog.debug.Loggable"},{"isInterface":true,"name":"goog.debug.EntryPointMonitor","isTypedef":false,"href":"interface_goog_debug_EntryPointMonitor.html"},{"isInterface":false,"name":"goog.debug.Error","isTypedef":false,"href":"class_goog_debug_Error.html"},{"isInterface":false,"name":"goog.debug.LogBuffer","isTypedef":false,"href":"class_goog_debug_LogBuffer.html"},{"isInterface":false,"name":"goog.debug.LogManager","isTypedef":false,"href":"namespace_goog_debug_LogManager.html"},{"isInterface":false,"name":"goog.debug.LogRecord","isTypedef":false,"href":"class_goog_debug_LogRecord.html"},{"isInterface":false,"name":"goog.debug.Logger","isTypedef":false,"href":"class_goog_debug_Logger.html"},{"isInterface":false,"name":"goog.debug.Logger.Level","isTypedef":false,"href":"class_goog_debug_Logger_Level.html"},{"isInterface":false,"name":"goog.debug.entryPointRegistry","isTypedef":false,"href":"namespace_goog_debug_entryPointRegistry.html"},{"isInterface":false,"name":"goog.defineClass","isTypedef":false,"href":"namespace_goog_defineClass.html"},{"name":"goog.defineClass.ClassDescriptor","isTypedef":true,"href":"namespace_goog_defineClass.html#goog.defineClass.ClassDescriptor"},{"isInterface":false,"name":"goog.disposable","isTypedef":false,"href":"namespace_goog_disposable.html"},{"isInterface":true,"name":"goog.disposable.IDisposable","isTypedef":false,"href":"interface_goog_disposable_IDisposable.html"},{"isInterface":false,"name":"goog.dom","isTypedef":false,"href":"namespace_goog_dom.html"},{"name":"goog.dom.Appendable","isTypedef":true,"href":"namespace_goog_dom.html#goog.dom.Appendable"},{"isInterface":false,"name":"goog.dom.BrowserFeature","isTypedef":false,"href":"enum_goog_dom_BrowserFeature.html"},{"isInterface":false,"name":"goog.dom.DomHelper","isTypedef":false,"href":"class_goog_dom_DomHelper.html"},{"isInterface":false,"name":"goog.dom.NodeType","isTypedef":false,"href":"enum_goog_dom_NodeType.html"},{"isInterface":false,"name":"goog.dom.TagName","isTypedef":false,"href":"enum_goog_dom_TagName.html"},{"isInterface":false,"name":"goog.dom.vendor","isTypedef":false,"href":"namespace_goog_dom_vendor.html"},{"isInterface":false,"name":"goog.events","isTypedef":false,"href":"namespace_goog_events.html"},{"name":"goog.events.EventLike","isTypedef":true,"href":"namespace_goog_events.html#goog.events.EventLike"},{"name":"goog.events.Key","isTypedef":true,"href":"namespace_goog_events.html#goog.events.Key"},{"name":"goog.events.ListenableType","isTypedef":true,"href":"namespace_goog_events.html#goog.events.ListenableType"},{"isInterface":false,"name":"goog.events.BrowserEvent","isTypedef":false,"href":"class_goog_events_BrowserEvent.html"},{"isInterface":false,"name":"goog.events.BrowserEvent.MouseButton","isTypedef":false,"href":"enum_goog_events_BrowserEvent_MouseButton.html"},{"isInterface":false,"name":"goog.events.BrowserFeature","isTypedef":false,"href":"enum_goog_events_BrowserFeature.html"},{"isInterface":false,"name":"goog.events.CaptureSimulationMode","isTypedef":false,"href":"enum_goog_events_CaptureSimulationMode.html"},{"isInterface":false,"name":"goog.events.Event","isTypedef":false,"href":"class_goog_events_Event.html"},{"isInterface":false,"name":"goog.events.EventId","isTypedef":false,"href":"class_goog_events_EventId.html"},{"isInterface":false,"name":"goog.events.EventTarget","isTypedef":false,"href":"class_goog_events_EventTarget.html"},{"isInterface":false,"name":"goog.events.EventType","isTypedef":false,"href":"enum_goog_events_EventType.html"},{"isInterface":false,"name":"goog.events.KeyCodes","isTypedef":false,"href":"enum_goog_events_KeyCodes.html"},{"isInterface":true,"name":"goog.events.Listenable","isTypedef":false,"href":"interface_goog_events_Listenable.html"},{"isInterface":true,"name":"goog.events.ListenableKey","isTypedef":false,"href":"interface_goog_events_ListenableKey.html"},{"isInterface":false,"name":"goog.events.Listener","isTypedef":false,"href":"class_goog_events_Listener.html"},{"isInterface":false,"name":"goog.events.ListenerMap","isTypedef":false,"href":"class_goog_events_ListenerMap.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.math.Box","isTypedef":false,"href":"class_goog_math_Box.html"},{"isInterface":false,"name":"goog.math.Coordinate","isTypedef":false,"href":"class_goog_math_Coordinate.html"},{"isInterface":false,"name":"goog.math.Rect","isTypedef":false,"href":"class_goog_math_Rect.html"},{"isInterface":false,"name":"goog.math.Size","isTypedef":false,"href":"class_goog_math_Size.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.reflect","isTypedef":false,"href":"namespace_goog_reflect.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":true,"name":"goog.structs.Collection","isTypedef":false,"href":"interface_goog_structs_Collection.html"},{"isInterface":false,"name":"goog.structs.Map","isTypedef":false,"href":"class_goog_structs_Map.html"},{"isInterface":false,"name":"goog.structs.Set","isTypedef":false,"href":"class_goog_structs_Set.html"},{"isInterface":false,"name":"goog.style","isTypedef":false,"href":"namespace_goog_style.html"},{"isInterface":false,"name":"goog.testing","isTypedef":false,"href":"namespace_goog_testing.html"},{"isInterface":false,"name":"goog.testing.AsyncTestCase","isTypedef":false,"href":"class_goog_testing_AsyncTestCase.html"},{"name":"goog.testing.AsyncTestCase.TopStackFuncResult_","isTypedef":true,"href":"class_goog_testing_AsyncTestCase.html#goog.testing.AsyncTestCase.TopStackFuncResult_"},{"isInterface":false,"name":"goog.testing.AsyncTestCase.ControlBreakingException","isTypedef":false,"href":"class_goog_testing_AsyncTestCase_ControlBreakingException.html"},{"isInterface":false,"name":"goog.testing.FunctionCall","isTypedef":false,"href":"class_goog_testing_FunctionCall.html"},{"isInterface":false,"name":"goog.testing.JsUnitException","isTypedef":false,"href":"class_goog_testing_JsUnitException.html"},{"isInterface":false,"name":"goog.testing.LooseExpectationCollection","isTypedef":false,"href":"class_goog_testing_LooseExpectationCollection.html"},{"isInterface":false,"name":"goog.testing.LooseMock","isTypedef":false,"href":"class_goog_testing_LooseMock.html"},{"isInterface":false,"name":"goog.testing.MethodMock","isTypedef":false,"href":"namespace_goog_testing_MethodMock.html"},{"isInterface":false,"name":"goog.testing.Mock","isTypedef":false,"href":"class_goog_testing_Mock.html"},{"isInterface":false,"name":"goog.testing.MockClock","isTypedef":false,"href":"class_goog_testing_MockClock.html"},{"isInterface":false,"name":"goog.testing.MockControl","isTypedef":false,"href":"class_goog_testing_MockControl.html"},{"isInterface":false,"name":"goog.testing.MockExpectation","isTypedef":false,"href":"class_goog_testing_MockExpectation.html"},{"isInterface":true,"name":"goog.testing.MockInterface","isTypedef":false,"href":"interface_goog_testing_MockInterface.html"},{"isInterface":false,"name":"goog.testing.ObjectPropertyString","isTypedef":false,"href":"class_goog_testing_ObjectPropertyString.html"},{"isInterface":false,"name":"goog.testing.PropertyReplacer","isTypedef":false,"href":"class_goog_testing_PropertyReplacer.html"},{"isInterface":false,"name":"goog.testing.StrictMock","isTypedef":false,"href":"class_goog_testing_StrictMock.html"},{"isInterface":false,"name":"goog.testing.TestCase","isTypedef":false,"href":"class_goog_testing_TestCase.html"},{"isInterface":false,"name":"goog.testing.TestCase.Error","isTypedef":false,"href":"class_goog_testing_TestCase_Error.html"},{"isInterface":false,"name":"goog.testing.TestCase.Order","isTypedef":false,"href":"enum_goog_testing_TestCase_Order.html"},{"isInterface":false,"name":"goog.testing.TestCase.Result","isTypedef":false,"href":"class_goog_testing_TestCase_Result.html"},{"isInterface":false,"name":"goog.testing.TestCase.Test","isTypedef":false,"href":"class_goog_testing_TestCase_Test.html"},{"isInterface":false,"name":"goog.testing.TestCase.protectedDate_","isTypedef":false,"href":"class_Date.html"},{"isInterface":false,"name":"goog.testing.TestRunner","isTypedef":false,"href":"class_goog_testing_TestRunner.html"},{"isInterface":false,"name":"goog.testing.asserts","isTypedef":false,"href":"namespace_goog_testing_asserts.html"},{"name":"goog.testing.asserts.ArrayLike","isTypedef":true,"href":"namespace_goog_testing_asserts.html#goog.testing.asserts.ArrayLike"},{"isInterface":false,"name":"goog.testing.events","isTypedef":false,"href":"namespace_goog_testing_events.html"},{"isInterface":false,"name":"goog.testing.events.Event","isTypedef":false,"href":"class_goog_testing_events_Event.html"},{"isInterface":false,"name":"goog.testing.jsunit","isTypedef":false,"href":"namespace_goog_testing_jsunit.html"},{"isInterface":false,"name":"goog.testing.mockmatchers","isTypedef":false,"href":"namespace_goog_testing_mockmatchers.html"},{"isInterface":false,"name":"goog.testing.mockmatchers.ArgumentMatcher","isTypedef":false,"href":"class_goog_testing_mockmatchers_ArgumentMatcher.html"},{"isInterface":false,"name":"goog.testing.mockmatchers.IgnoreArgument","isTypedef":false,"href":"class_goog_testing_mockmatchers_IgnoreArgument.html"},{"isInterface":false,"name":"goog.testing.mockmatchers.InstanceOf","isTypedef":false,"href":"class_goog_testing_mockmatchers_InstanceOf.html"},{"isInterface":false,"name":"goog.testing.mockmatchers.ObjectEquals","isTypedef":false,"href":"class_goog_testing_mockmatchers_ObjectEquals.html"},{"isInterface":false,"name":"goog.testing.mockmatchers.RegexpMatch","isTypedef":false,"href":"class_goog_testing_mockmatchers_RegexpMatch.html"},{"isInterface":false,"name":"goog.testing.mockmatchers.SaveArgument","isTypedef":false,"href":"class_goog_testing_mockmatchers_SaveArgument.html"},{"isInterface":false,"name":"goog.testing.mockmatchers.TypeOf","isTypedef":false,"href":"class_goog_testing_mockmatchers_TypeOf.html"},{"isInterface":false,"name":"goog.testing.stacktrace","isTypedef":false,"href":"namespace_goog_testing_stacktrace.html"},{"isInterface":false,"name":"goog.testing.stacktrace.Frame","isTypedef":false,"href":"class_goog_testing_stacktrace_Frame.html"},{"isInterface":false,"name":"goog.testing.watchers","isTypedef":false,"href":"namespace_goog_testing_watchers.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"},{"name":"webdriver.ProxyConfig","isTypedef":true,"href":"namespace_webdriver.html#webdriver.ProxyConfig"},{"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.AlertPromise","isTypedef":false,"href":"class_webdriver_AlertPromise.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.WebElementPromise","isTypedef":false,"href":"class_webdriver_WebElementPromise.html"},{"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"},{"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.Preferences","isTypedef":false,"href":"class_webdriver_logging_Preferences.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":true,"name":"webdriver.promise.Thenable","isTypedef":false,"href":"interface_webdriver_promise_Thenable.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.TestCase","isTypedef":false,"href":"class_webdriver_testing_TestCase.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":"WebElementPromise","isTypedef":false,"href":"class_webdriver_WebElementPromise.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":[{"isInterface":false,"name":"Context","isTypedef":false,"href":"module_selenium-webdriver__base_class_Context.html"}],"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":"Driver","isTypedef":false,"href":"module_selenium-webdriver_chrome_class_Driver.html"},{"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/firefox","types":[{"isInterface":false,"name":"Driver","isTypedef":false,"href":"module_selenium-webdriver_firefox_class_Driver.html"},{"isInterface":false,"name":"Binary","isTypedef":false,"href":"module_selenium-webdriver_firefox_class_Binary.html"},{"isInterface":false,"name":"Profile","isTypedef":false,"href":"module_selenium-webdriver_firefox_class_Profile.html"},{"isInterface":false,"name":"Options","isTypedef":false,"href":"module_selenium-webdriver_firefox_class_Options.html"}],"href":"module_selenium-webdriver_firefox.html"},{"name":"selenium-webdriver/firefox/binary","types":[{"isInterface":false,"name":"Binary","isTypedef":false,"href":"module_selenium-webdriver_firefox_binary_class_Binary.html"}],"href":"module_selenium-webdriver_firefox_binary.html"},{"name":"selenium-webdriver/firefox/extension","types":[{"isInterface":false,"name":"AddonDetails","isTypedef":true,"href":"module_selenium-webdriver_firefox_extension_namespace_AddonDetails.html"}],"href":"module_selenium-webdriver_firefox_extension.html"},{"name":"selenium-webdriver/firefox/profile","types":[{"isInterface":false,"name":"Profile","isTypedef":false,"href":"module_selenium-webdriver_firefox_profile_class_Profile.html"}],"href":"module_selenium-webdriver_firefox_profile.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/io/exec","types":[{"isInterface":false,"name":"Options","isTypedef":true,"href":"module_selenium-webdriver_io_exec_namespace_Options.html"}],"href":"module_selenium-webdriver_io_exec.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":[{"isInterface":false,"name":"Driver","isTypedef":false,"href":"module_selenium-webdriver_phantomjs_class_Driver.html"}],"href":"module_selenium-webdriver_phantomjs.html"},{"name":"selenium-webdriver/proxy","types":[],"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