selenium-webdriver 2.48.2 → 2.53.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (534) hide show
  1. package/CHANGES.md +116 -0
  2. package/NOTICE +1 -1
  3. package/README.md +59 -9
  4. package/builder.js +375 -358
  5. package/chrome.js +549 -586
  6. package/edge.js +378 -0
  7. package/error.js +9 -6
  8. package/example/google_search.js +1 -1
  9. package/example/google_search_generator.js +2 -4
  10. package/example/logging.js +6 -2
  11. package/example/sample.js +21 -0
  12. package/executors.js +11 -27
  13. package/firefox/binary.js +149 -98
  14. package/firefox/extension.js +15 -19
  15. package/firefox/index.js +256 -163
  16. package/firefox/profile.js +223 -243
  17. package/http/index.js +487 -81
  18. package/http/util.js +40 -36
  19. package/ie.js +288 -309
  20. package/index.js +34 -125
  21. package/io/exec.js +58 -39
  22. package/io/index.js +72 -60
  23. package/lib/README +4 -0
  24. package/lib/actions.js +596 -0
  25. package/lib/by.js +277 -0
  26. package/lib/capabilities.js +450 -0
  27. package/lib/{webdriver/command.js → command.js} +91 -72
  28. package/lib/{webdriver/button.js → devmode.js} +13 -8
  29. package/lib/error.js +690 -0
  30. package/lib/events.js +212 -0
  31. package/lib/firefox/amd64/libnoblur64.so +0 -0
  32. package/lib/firefox/i386/libnoblur.so +0 -0
  33. package/lib/firefox/webdriver.json +5 -1
  34. package/lib/firefox/webdriver.xpi +0 -0
  35. package/lib/{webdriver/key.js → input.js} +84 -2
  36. package/lib/logging.js +670 -0
  37. package/lib/{webdriver/promise.js → promise.js} +817 -644
  38. package/lib/safari/client.js +266 -214
  39. package/lib/session.js +80 -0
  40. package/lib/{webdriver/serializable.js → symbols.js} +16 -19
  41. package/lib/test/build.js +4 -4
  42. package/lib/test/data/click_tests/html5_submit_buttons.html +2 -1
  43. package/lib/test/data/click_tests/overlapping_elements.html +15 -4
  44. package/lib/test/data/click_tests/partially_overlapping_elements.html +124 -0
  45. package/lib/test/data/click_tests/wrapped_overlapping_elements.html +13 -0
  46. package/lib/test/data/hidden_partially.html +45 -0
  47. package/lib/test/data/readOnlyPage.html +1 -1
  48. package/lib/test/data/selectPage.html +18 -2
  49. package/lib/test/fileserver.js +3 -4
  50. package/lib/test/index.js +7 -3
  51. package/lib/test/resources.js +1 -1
  52. package/lib/until.js +376 -0
  53. package/lib/webdriver.js +2440 -0
  54. package/net/index.js +4 -0
  55. package/net/portprober.js +16 -12
  56. package/opera.js +295 -314
  57. package/package.json +6 -5
  58. package/phantomjs.js +144 -147
  59. package/proxy.js +10 -6
  60. package/remote/index.js +289 -238
  61. package/safari.js +326 -311
  62. package/test/chrome/options_test.js +11 -9
  63. package/test/element_finding_test.js +51 -13
  64. package/test/execute_script_test.js +17 -3
  65. package/test/firefox/firefox_test.js +0 -32
  66. package/test/http/http_test.js +671 -61
  67. package/test/http/util_test.js +25 -23
  68. package/test/io_test.js +67 -1
  69. package/test/lib/by_test.js +139 -0
  70. package/test/lib/capabilities_test.js +111 -0
  71. package/test/lib/error_test.js +325 -0
  72. package/test/lib/events_test.js +177 -0
  73. package/test/lib/logging_test.js +272 -0
  74. package/test/{promise_aplus_test.js → lib/promise_aplus_test.js} +4 -13
  75. package/test/lib/promise_error_test.js +808 -0
  76. package/test/lib/promise_flow_test.js +2282 -0
  77. package/test/lib/promise_generator_test.js +308 -0
  78. package/test/lib/promise_test.js +996 -0
  79. package/test/lib/testutil.js +90 -0
  80. package/test/lib/until_test.js +400 -0
  81. package/test/lib/webdriver_test.js +2157 -0
  82. package/test/page_loading_test.js +7 -9
  83. package/test/remote_test.js +50 -3
  84. package/test/session_test.js +53 -0
  85. package/test/stale_element_test.js +2 -2
  86. package/test/testing/assert_test.js +374 -0
  87. package/test/testing/index_test.js +9 -11
  88. package/testing/assert.js +334 -17
  89. package/testing/index.js +12 -2
  90. package/_base.js +0 -200
  91. package/docs/Changes.html +0 -356
  92. package/docs/class_bot_Error.html +0 -15
  93. package/docs/class_webdriver_ActionSequence.html +0 -115
  94. package/docs/class_webdriver_Alert.html +0 -24
  95. package/docs/class_webdriver_AlertPromise.html +0 -92
  96. package/docs/class_webdriver_Capabilities.html +0 -60
  97. package/docs/class_webdriver_Command.html +0 -15
  98. package/docs/class_webdriver_EventEmitter.html +0 -35
  99. package/docs/class_webdriver_FileDetector.html +0 -21
  100. package/docs/class_webdriver_Locator.html +0 -12
  101. package/docs/class_webdriver_Serializable.html +0 -9
  102. package/docs/class_webdriver_Session.html +0 -13
  103. package/docs/class_webdriver_TouchSequence.html +0 -49
  104. package/docs/class_webdriver_UnhandledAlertError.html +0 -18
  105. package/docs/class_webdriver_WebDriver.html +0 -313
  106. package/docs/class_webdriver_WebDriver_Logs.html +0 -15
  107. package/docs/class_webdriver_WebDriver_Navigation.html +0 -16
  108. package/docs/class_webdriver_WebDriver_Options.html +0 -41
  109. package/docs/class_webdriver_WebDriver_TargetLocator.html +0 -38
  110. package/docs/class_webdriver_WebDriver_Timeouts.html +0 -29
  111. package/docs/class_webdriver_WebDriver_Window.html +0 -27
  112. package/docs/class_webdriver_WebElement.html +0 -223
  113. package/docs/class_webdriver_WebElementPromise.html +0 -274
  114. package/docs/class_webdriver_http_Executor.html +0 -22
  115. package/docs/class_webdriver_http_Request.html +0 -12
  116. package/docs/class_webdriver_http_Response.html +0 -13
  117. package/docs/class_webdriver_logging_Entry.html +0 -15
  118. package/docs/class_webdriver_logging_Level.html +0 -55
  119. package/docs/class_webdriver_logging_LogRecord.html +0 -45
  120. package/docs/class_webdriver_logging_Logger.html +0 -119
  121. package/docs/class_webdriver_logging_Preferences.html +0 -8
  122. package/docs/class_webdriver_promise_CancellationError.html +0 -17
  123. package/docs/class_webdriver_promise_ControlFlow.html +0 -153
  124. package/docs/class_webdriver_promise_Deferred.html +0 -84
  125. package/docs/class_webdriver_promise_MultipleUnhandledRejectionError.html +0 -14
  126. package/docs/class_webdriver_promise_Promise.html +0 -75
  127. package/docs/class_webdriver_stacktrace_Frame.html +0 -20
  128. package/docs/class_webdriver_stacktrace_Snapshot.html +0 -6
  129. package/docs/class_webdriver_testing_Assertion.html +0 -99
  130. package/docs/class_webdriver_testing_Assertion_DelegatingMatcher_.html +0 -13
  131. package/docs/class_webdriver_testing_ContainsMatcher.html +0 -11
  132. package/docs/class_webdriver_testing_NegatedAssertion.html +0 -97
  133. package/docs/class_webdriver_until_Condition.html +0 -7
  134. package/docs/dossier.css +0 -1
  135. package/docs/dossier.js +0 -86
  136. package/docs/enum_bot_ErrorCode.html +0 -3
  137. package/docs/enum_bot_Error_State.html +0 -2
  138. package/docs/enum_webdriver_Browser.html +0 -2
  139. package/docs/enum_webdriver_Button.html +0 -2
  140. package/docs/enum_webdriver_Capability.html +0 -33
  141. package/docs/enum_webdriver_CommandName.html +0 -3
  142. package/docs/enum_webdriver_Key.html +0 -12
  143. package/docs/enum_webdriver_logging_Type.html +0 -6
  144. package/docs/enum_webdriver_promise_ControlFlow_EventType.html +0 -9
  145. package/docs/index.html +0 -125
  146. package/docs/interface_webdriver_CommandExecutor.html +0 -9
  147. package/docs/interface_webdriver_http_Client.html +0 -10
  148. package/docs/interface_webdriver_promise_Thenable.html +0 -77
  149. package/docs/module_selenium-webdriver.html +0 -23
  150. package/docs/module_selenium-webdriver__base.html +0 -23
  151. package/docs/module_selenium-webdriver__base_class_Context.html +0 -5
  152. package/docs/module_selenium-webdriver_builder.html +0 -2
  153. package/docs/module_selenium-webdriver_builder_class_Builder.html +0 -138
  154. package/docs/module_selenium-webdriver_chrome.html +0 -90
  155. package/docs/module_selenium-webdriver_chrome_class_Driver.html +0 -280
  156. package/docs/module_selenium-webdriver_chrome_class_Options.html +0 -127
  157. package/docs/module_selenium-webdriver_chrome_class_ServiceBuilder.html +0 -46
  158. package/docs/module_selenium-webdriver_class_ActionSequence.html +0 -115
  159. package/docs/module_selenium-webdriver_class_Builder.html +0 -138
  160. package/docs/module_selenium-webdriver_class_Capabilities.html +0 -60
  161. package/docs/module_selenium-webdriver_class_Command.html +0 -15
  162. package/docs/module_selenium-webdriver_class_EventEmitter.html +0 -35
  163. package/docs/module_selenium-webdriver_class_FileDetector.html +0 -21
  164. package/docs/module_selenium-webdriver_class_Serializable.html +0 -9
  165. package/docs/module_selenium-webdriver_class_Session.html +0 -13
  166. package/docs/module_selenium-webdriver_class_WebDriver.html +0 -313
  167. package/docs/module_selenium-webdriver_class_WebElement.html +0 -223
  168. package/docs/module_selenium-webdriver_class_WebElementPromise.html +0 -274
  169. package/docs/module_selenium-webdriver_enum_Browser.html +0 -2
  170. package/docs/module_selenium-webdriver_enum_Button.html +0 -2
  171. package/docs/module_selenium-webdriver_enum_Capability.html +0 -33
  172. package/docs/module_selenium-webdriver_enum_CommandName.html +0 -3
  173. package/docs/module_selenium-webdriver_enum_Key.html +0 -12
  174. package/docs/module_selenium-webdriver_error.html +0 -4
  175. package/docs/module_selenium-webdriver_error_class_Error.html +0 -15
  176. package/docs/module_selenium-webdriver_error_enum_ErrorCode.html +0 -3
  177. package/docs/module_selenium-webdriver_executors.html +0 -10
  178. package/docs/module_selenium-webdriver_executors_class_DeferredExecutor.html +0 -12
  179. package/docs/module_selenium-webdriver_firefox.html +0 -68
  180. package/docs/module_selenium-webdriver_firefox_binary.html +0 -5
  181. package/docs/module_selenium-webdriver_firefox_binary_class_Binary.html +0 -20
  182. package/docs/module_selenium-webdriver_firefox_class_Binary.html +0 -20
  183. package/docs/module_selenium-webdriver_firefox_class_Driver.html +0 -276
  184. package/docs/module_selenium-webdriver_firefox_class_Options.html +0 -19
  185. package/docs/module_selenium-webdriver_firefox_class_Profile.html +0 -50
  186. package/docs/module_selenium-webdriver_firefox_extension.html +0 -8
  187. package/docs/module_selenium-webdriver_firefox_profile.html +0 -13
  188. package/docs/module_selenium-webdriver_firefox_profile_class_Profile.html +0 -50
  189. package/docs/module_selenium-webdriver_http.html +0 -9
  190. package/docs/module_selenium-webdriver_http_class_Executor.html +0 -22
  191. package/docs/module_selenium-webdriver_http_class_HttpClient.html +0 -16
  192. package/docs/module_selenium-webdriver_http_class_Request.html +0 -12
  193. package/docs/module_selenium-webdriver_http_class_Response.html +0 -13
  194. package/docs/module_selenium-webdriver_http_util.html +0 -17
  195. package/docs/module_selenium-webdriver_ie.html +0 -11
  196. package/docs/module_selenium-webdriver_ie_class_Driver.html +0 -274
  197. package/docs/module_selenium-webdriver_ie_class_Options.html +0 -89
  198. package/docs/module_selenium-webdriver_ie_enum_Level.html +0 -1
  199. package/docs/module_selenium-webdriver_io.html +0 -37
  200. package/docs/module_selenium-webdriver_io_exec.html +0 -6
  201. package/docs/module_selenium-webdriver_namespace_By.html +0 -56
  202. package/docs/module_selenium-webdriver_namespace_error.html +0 -4
  203. package/docs/module_selenium-webdriver_namespace_logging.html +0 -18
  204. package/docs/module_selenium-webdriver_namespace_promise.html +0 -163
  205. package/docs/module_selenium-webdriver_namespace_stacktrace.html +0 -17
  206. package/docs/module_selenium-webdriver_namespace_until.html +0 -82
  207. package/docs/module_selenium-webdriver_net.html +0 -7
  208. package/docs/module_selenium-webdriver_net_portprober.html +0 -12
  209. package/docs/module_selenium-webdriver_opera.html +0 -62
  210. package/docs/module_selenium-webdriver_opera_class_Driver.html +0 -276
  211. package/docs/module_selenium-webdriver_opera_class_Options.html +0 -44
  212. package/docs/module_selenium-webdriver_opera_class_ServiceBuilder.html +0 -35
  213. package/docs/module_selenium-webdriver_phantomjs.html +0 -2
  214. package/docs/module_selenium-webdriver_phantomjs_class_Driver.html +0 -299
  215. package/docs/module_selenium-webdriver_proxy.html +0 -28
  216. package/docs/module_selenium-webdriver_remote.html +0 -8
  217. package/docs/module_selenium-webdriver_remote_class_DriverService.html +0 -32
  218. package/docs/module_selenium-webdriver_remote_class_FileDetector.html +0 -22
  219. package/docs/module_selenium-webdriver_remote_class_SeleniumServer.html +0 -41
  220. package/docs/module_selenium-webdriver_safari.html +0 -9
  221. package/docs/module_selenium-webdriver_safari_class_Driver.html +0 -279
  222. package/docs/module_selenium-webdriver_safari_class_Options.html +0 -23
  223. package/docs/module_selenium-webdriver_testing.html +0 -74
  224. package/docs/module_selenium-webdriver_testing_assert.html +0 -9
  225. package/docs/namespace_bot.html +0 -4
  226. package/docs/namespace_bot_json.html +0 -20
  227. package/docs/namespace_bot_response.html +0 -18
  228. package/docs/namespace_bot_userAgent.html +0 -33
  229. package/docs/namespace_webdriver.html +0 -30
  230. package/docs/namespace_webdriver_By.html +0 -56
  231. package/docs/namespace_webdriver_http.html +0 -6
  232. package/docs/namespace_webdriver_logging.html +0 -70
  233. package/docs/namespace_webdriver_promise.html +0 -688
  234. package/docs/namespace_webdriver_stacktrace.html +0 -17
  235. package/docs/namespace_webdriver_testing.html +0 -7
  236. package/docs/namespace_webdriver_testing_assert.html +0 -9
  237. package/docs/namespace_webdriver_testing_asserts.html +0 -18
  238. package/docs/namespace_webdriver_until.html +0 -82
  239. package/docs/source/_base.js.src.html +0 -1
  240. package/docs/source/builder.js.src.html +0 -1
  241. package/docs/source/chrome.js.src.html +0 -1
  242. package/docs/source/error.js.src.html +0 -1
  243. package/docs/source/executors.js.src.html +0 -1
  244. package/docs/source/firefox/binary.js.src.html +0 -1
  245. package/docs/source/firefox/extension.js.src.html +0 -1
  246. package/docs/source/firefox/index.js.src.html +0 -1
  247. package/docs/source/firefox/profile.js.src.html +0 -1
  248. package/docs/source/http/index.js.src.html +0 -1
  249. package/docs/source/http/util.js.src.html +0 -1
  250. package/docs/source/ie.js.src.html +0 -1
  251. package/docs/source/index.js.src.html +0 -1
  252. package/docs/source/io/exec.js.src.html +0 -1
  253. package/docs/source/io/index.js.src.html +0 -1
  254. package/docs/source/lib/atoms/error.js.src.html +0 -1
  255. package/docs/source/lib/atoms/json.js.src.html +0 -1
  256. package/docs/source/lib/atoms/response.js.src.html +0 -1
  257. package/docs/source/lib/atoms/userAgent.js.src.html +0 -1
  258. package/docs/source/lib/goog/array/array.js.src.html +0 -1
  259. package/docs/source/lib/goog/asserts/asserts.js.src.html +0 -1
  260. package/docs/source/lib/goog/async/freelist.js.src.html +0 -1
  261. package/docs/source/lib/goog/async/nexttick.js.src.html +0 -1
  262. package/docs/source/lib/goog/async/run.js.src.html +0 -1
  263. package/docs/source/lib/goog/async/workqueue.js.src.html +0 -1
  264. package/docs/source/lib/goog/base.js.src.html +0 -1
  265. package/docs/source/lib/goog/debug/debug.js.src.html +0 -1
  266. package/docs/source/lib/goog/debug/entrypointregistry.js.src.html +0 -1
  267. package/docs/source/lib/goog/debug/error.js.src.html +0 -1
  268. package/docs/source/lib/goog/debug/logbuffer.js.src.html +0 -1
  269. package/docs/source/lib/goog/debug/logger.js.src.html +0 -1
  270. package/docs/source/lib/goog/debug/logrecord.js.src.html +0 -1
  271. package/docs/source/lib/goog/deps.js.src.html +0 -1
  272. package/docs/source/lib/goog/disposable/disposable.js.src.html +0 -1
  273. package/docs/source/lib/goog/disposable/idisposable.js.src.html +0 -1
  274. package/docs/source/lib/goog/dom/browserfeature.js.src.html +0 -1
  275. package/docs/source/lib/goog/dom/dom.js.src.html +0 -1
  276. package/docs/source/lib/goog/dom/nodetype.js.src.html +0 -1
  277. package/docs/source/lib/goog/dom/safe.js.src.html +0 -1
  278. package/docs/source/lib/goog/dom/tagname.js.src.html +0 -1
  279. package/docs/source/lib/goog/dom/tags.js.src.html +0 -1
  280. package/docs/source/lib/goog/dom/vendor.js.src.html +0 -1
  281. package/docs/source/lib/goog/events/browserevent.js.src.html +0 -1
  282. package/docs/source/lib/goog/events/browserfeature.js.src.html +0 -1
  283. package/docs/source/lib/goog/events/event.js.src.html +0 -1
  284. package/docs/source/lib/goog/events/eventid.js.src.html +0 -1
  285. package/docs/source/lib/goog/events/events.js.src.html +0 -1
  286. package/docs/source/lib/goog/events/eventtarget.js.src.html +0 -1
  287. package/docs/source/lib/goog/events/eventtype.js.src.html +0 -1
  288. package/docs/source/lib/goog/events/keycodes.js.src.html +0 -1
  289. package/docs/source/lib/goog/events/listenable.js.src.html +0 -1
  290. package/docs/source/lib/goog/events/listener.js.src.html +0 -1
  291. package/docs/source/lib/goog/events/listenermap.js.src.html +0 -1
  292. package/docs/source/lib/goog/fs/url.js.src.html +0 -1
  293. package/docs/source/lib/goog/functions/functions.js.src.html +0 -1
  294. package/docs/source/lib/goog/html/safehtml.js.src.html +0 -1
  295. package/docs/source/lib/goog/html/safescript.js.src.html +0 -1
  296. package/docs/source/lib/goog/html/safestyle.js.src.html +0 -1
  297. package/docs/source/lib/goog/html/safestylesheet.js.src.html +0 -1
  298. package/docs/source/lib/goog/html/safeurl.js.src.html +0 -1
  299. package/docs/source/lib/goog/html/trustedresourceurl.js.src.html +0 -1
  300. package/docs/source/lib/goog/html/uncheckedconversions.js.src.html +0 -1
  301. package/docs/source/lib/goog/i18n/bidi.js.src.html +0 -1
  302. package/docs/source/lib/goog/iter/iter.js.src.html +0 -1
  303. package/docs/source/lib/goog/json/json.js.src.html +0 -1
  304. package/docs/source/lib/goog/labs/testing/assertthat.js.src.html +0 -1
  305. package/docs/source/lib/goog/labs/testing/logicmatcher.js.src.html +0 -1
  306. package/docs/source/lib/goog/labs/testing/matcher.js.src.html +0 -1
  307. package/docs/source/lib/goog/labs/testing/numbermatcher.js.src.html +0 -1
  308. package/docs/source/lib/goog/labs/testing/objectmatcher.js.src.html +0 -1
  309. package/docs/source/lib/goog/labs/testing/stringmatcher.js.src.html +0 -1
  310. package/docs/source/lib/goog/labs/useragent/browser.js.src.html +0 -1
  311. package/docs/source/lib/goog/labs/useragent/engine.js.src.html +0 -1
  312. package/docs/source/lib/goog/labs/useragent/platform.js.src.html +0 -1
  313. package/docs/source/lib/goog/labs/useragent/util.js.src.html +0 -1
  314. package/docs/source/lib/goog/log/log.js.src.html +0 -1
  315. package/docs/source/lib/goog/math/box.js.src.html +0 -1
  316. package/docs/source/lib/goog/math/coordinate.js.src.html +0 -1
  317. package/docs/source/lib/goog/math/math.js.src.html +0 -1
  318. package/docs/source/lib/goog/math/rect.js.src.html +0 -1
  319. package/docs/source/lib/goog/math/size.js.src.html +0 -1
  320. package/docs/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html +0 -1
  321. package/docs/source/lib/goog/net/xhrlike.js.src.html +0 -1
  322. package/docs/source/lib/goog/net/xmlhttp.js.src.html +0 -1
  323. package/docs/source/lib/goog/net/xmlhttpfactory.js.src.html +0 -1
  324. package/docs/source/lib/goog/object/object.js.src.html +0 -1
  325. package/docs/source/lib/goog/promise/promise.js.src.html +0 -1
  326. package/docs/source/lib/goog/promise/resolver.js.src.html +0 -1
  327. package/docs/source/lib/goog/promise/thenable.js.src.html +0 -1
  328. package/docs/source/lib/goog/reflect/reflect.js.src.html +0 -1
  329. package/docs/source/lib/goog/string/const.js.src.html +0 -1
  330. package/docs/source/lib/goog/string/string.js.src.html +0 -1
  331. package/docs/source/lib/goog/string/typedstring.js.src.html +0 -1
  332. package/docs/source/lib/goog/structs/collection.js.src.html +0 -1
  333. package/docs/source/lib/goog/structs/map.js.src.html +0 -1
  334. package/docs/source/lib/goog/structs/set.js.src.html +0 -1
  335. package/docs/source/lib/goog/structs/structs.js.src.html +0 -1
  336. package/docs/source/lib/goog/style/style.js.src.html +0 -1
  337. package/docs/source/lib/goog/testing/asserts.js.src.html +0 -1
  338. package/docs/source/lib/goog/testing/events/events.js.src.html +0 -1
  339. package/docs/source/lib/goog/testing/functionmock.js.src.html +0 -1
  340. package/docs/source/lib/goog/testing/jsunit.js.src.html +0 -1
  341. package/docs/source/lib/goog/testing/loosemock.js.src.html +0 -1
  342. package/docs/source/lib/goog/testing/mock.js.src.html +0 -1
  343. package/docs/source/lib/goog/testing/mockclock.js.src.html +0 -1
  344. package/docs/source/lib/goog/testing/mockcontrol.js.src.html +0 -1
  345. package/docs/source/lib/goog/testing/mockinterface.js.src.html +0 -1
  346. package/docs/source/lib/goog/testing/mockmatchers.js.src.html +0 -1
  347. package/docs/source/lib/goog/testing/objectpropertystring.js.src.html +0 -1
  348. package/docs/source/lib/goog/testing/propertyreplacer.js.src.html +0 -1
  349. package/docs/source/lib/goog/testing/recordfunction.js.src.html +0 -1
  350. package/docs/source/lib/goog/testing/stacktrace.js.src.html +0 -1
  351. package/docs/source/lib/goog/testing/strictmock.js.src.html +0 -1
  352. package/docs/source/lib/goog/testing/testcase.js.src.html +0 -1
  353. package/docs/source/lib/goog/testing/testrunner.js.src.html +0 -1
  354. package/docs/source/lib/goog/uri/uri.js.src.html +0 -1
  355. package/docs/source/lib/goog/uri/utils.js.src.html +0 -1
  356. package/docs/source/lib/goog/useragent/product.js.src.html +0 -1
  357. package/docs/source/lib/goog/useragent/product_isversion.js.src.html +0 -1
  358. package/docs/source/lib/goog/useragent/useragent.js.src.html +0 -1
  359. package/docs/source/lib/webdriver/actionsequence.js.src.html +0 -1
  360. package/docs/source/lib/webdriver/button.js.src.html +0 -1
  361. package/docs/source/lib/webdriver/capabilities.js.src.html +0 -1
  362. package/docs/source/lib/webdriver/command.js.src.html +0 -1
  363. package/docs/source/lib/webdriver/events.js.src.html +0 -1
  364. package/docs/source/lib/webdriver/http/http.js.src.html +0 -1
  365. package/docs/source/lib/webdriver/key.js.src.html +0 -1
  366. package/docs/source/lib/webdriver/locators.js.src.html +0 -1
  367. package/docs/source/lib/webdriver/logging.js.src.html +0 -1
  368. package/docs/source/lib/webdriver/promise.js.src.html +0 -1
  369. package/docs/source/lib/webdriver/serializable.js.src.html +0 -1
  370. package/docs/source/lib/webdriver/session.js.src.html +0 -1
  371. package/docs/source/lib/webdriver/stacktrace.js.src.html +0 -1
  372. package/docs/source/lib/webdriver/testing/asserts.js.src.html +0 -1
  373. package/docs/source/lib/webdriver/touchsequence.js.src.html +0 -1
  374. package/docs/source/lib/webdriver/until.js.src.html +0 -1
  375. package/docs/source/lib/webdriver/webdriver.js.src.html +0 -1
  376. package/docs/source/net/index.js.src.html +0 -1
  377. package/docs/source/net/portprober.js.src.html +0 -1
  378. package/docs/source/opera.js.src.html +0 -1
  379. package/docs/source/phantomjs.js.src.html +0 -1
  380. package/docs/source/proxy.js.src.html +0 -1
  381. package/docs/source/remote/index.js.src.html +0 -1
  382. package/docs/source/safari.js.src.html +0 -1
  383. package/docs/source/testing/assert.js.src.html +0 -1
  384. package/docs/source/testing/index.js.src.html +0 -1
  385. package/docs/types.js +0 -1
  386. package/lib/atoms/error.js +0 -202
  387. package/lib/atoms/json.js +0 -80
  388. package/lib/atoms/response.js +0 -110
  389. package/lib/atoms/userAgent.js +0 -257
  390. package/lib/goog/LICENSE +0 -176
  391. package/lib/goog/array/array.js +0 -1654
  392. package/lib/goog/asserts/asserts.js +0 -365
  393. package/lib/goog/async/freelist.js +0 -88
  394. package/lib/goog/async/nexttick.js +0 -241
  395. package/lib/goog/async/run.js +0 -133
  396. package/lib/goog/async/workqueue.js +0 -139
  397. package/lib/goog/base.js +0 -2548
  398. package/lib/goog/debug/debug.js +0 -653
  399. package/lib/goog/debug/entrypointregistry.js +0 -158
  400. package/lib/goog/debug/error.js +0 -63
  401. package/lib/goog/debug/logbuffer.js +0 -148
  402. package/lib/goog/debug/logger.js +0 -873
  403. package/lib/goog/debug/logrecord.js +0 -242
  404. package/lib/goog/deps.js +0 -151
  405. package/lib/goog/disposable/disposable.js +0 -307
  406. package/lib/goog/disposable/idisposable.js +0 -45
  407. package/lib/goog/dom/browserfeature.js +0 -72
  408. package/lib/goog/dom/dom.js +0 -2991
  409. package/lib/goog/dom/nodetype.js +0 -48
  410. package/lib/goog/dom/safe.js +0 -347
  411. package/lib/goog/dom/tagname.js +0 -160
  412. package/lib/goog/dom/tags.js +0 -41
  413. package/lib/goog/dom/vendor.js +0 -96
  414. package/lib/goog/events/browserevent.js +0 -400
  415. package/lib/goog/events/browserfeature.js +0 -85
  416. package/lib/goog/events/event.js +0 -143
  417. package/lib/goog/events/eventid.js +0 -47
  418. package/lib/goog/events/events.js +0 -984
  419. package/lib/goog/events/eventtarget.js +0 -394
  420. package/lib/goog/events/eventtype.js +0 -237
  421. package/lib/goog/events/keycodes.js +0 -427
  422. package/lib/goog/events/listenable.js +0 -335
  423. package/lib/goog/events/listener.js +0 -131
  424. package/lib/goog/events/listenermap.js +0 -308
  425. package/lib/goog/fs/url.js +0 -109
  426. package/lib/goog/functions/functions.js +0 -442
  427. package/lib/goog/html/safehtml.js +0 -757
  428. package/lib/goog/html/safescript.js +0 -234
  429. package/lib/goog/html/safestyle.js +0 -442
  430. package/lib/goog/html/safestylesheet.js +0 -276
  431. package/lib/goog/html/safeurl.js +0 -398
  432. package/lib/goog/html/trustedresourceurl.js +0 -224
  433. package/lib/goog/html/uncheckedconversions.js +0 -232
  434. package/lib/goog/i18n/bidi.js +0 -908
  435. package/lib/goog/iter/iter.js +0 -1302
  436. package/lib/goog/json/json.js +0 -363
  437. package/lib/goog/labs/testing/assertthat.js +0 -58
  438. package/lib/goog/labs/testing/logicmatcher.js +0 -212
  439. package/lib/goog/labs/testing/matcher.js +0 -80
  440. package/lib/goog/labs/testing/numbermatcher.js +0 -346
  441. package/lib/goog/labs/testing/objectmatcher.js +0 -317
  442. package/lib/goog/labs/testing/stringmatcher.js +0 -415
  443. package/lib/goog/labs/useragent/browser.js +0 -341
  444. package/lib/goog/labs/useragent/engine.js +0 -160
  445. package/lib/goog/labs/useragent/platform.js +0 -160
  446. package/lib/goog/labs/useragent/util.js +0 -148
  447. package/lib/goog/log/log.js +0 -197
  448. package/lib/goog/math/box.js +0 -398
  449. package/lib/goog/math/coordinate.js +0 -268
  450. package/lib/goog/math/math.js +0 -451
  451. package/lib/goog/math/rect.js +0 -476
  452. package/lib/goog/math/size.js +0 -227
  453. package/lib/goog/net/wrapperxmlhttpfactory.js +0 -71
  454. package/lib/goog/net/xhrlike.js +0 -124
  455. package/lib/goog/net/xmlhttp.js +0 -246
  456. package/lib/goog/net/xmlhttpfactory.js +0 -67
  457. package/lib/goog/object/object.js +0 -686
  458. package/lib/goog/promise/promise.js +0 -1350
  459. package/lib/goog/promise/resolver.js +0 -48
  460. package/lib/goog/promise/thenable.js +0 -126
  461. package/lib/goog/reflect/reflect.js +0 -77
  462. package/lib/goog/string/const.js +0 -182
  463. package/lib/goog/string/string.js +0 -1599
  464. package/lib/goog/string/typedstring.js +0 -48
  465. package/lib/goog/structs/collection.js +0 -56
  466. package/lib/goog/structs/map.js +0 -457
  467. package/lib/goog/structs/set.js +0 -279
  468. package/lib/goog/structs/structs.js +0 -354
  469. package/lib/goog/style/style.js +0 -2037
  470. package/lib/goog/testing/asserts.js +0 -1278
  471. package/lib/goog/testing/events/events.js +0 -767
  472. package/lib/goog/testing/functionmock.js +0 -175
  473. package/lib/goog/testing/jsunit.js +0 -162
  474. package/lib/goog/testing/loosemock.js +0 -242
  475. package/lib/goog/testing/mock.js +0 -645
  476. package/lib/goog/testing/mockclock.js +0 -606
  477. package/lib/goog/testing/mockcontrol.js +0 -220
  478. package/lib/goog/testing/mockinterface.js +0 -45
  479. package/lib/goog/testing/mockmatchers.js +0 -400
  480. package/lib/goog/testing/objectpropertystring.js +0 -68
  481. package/lib/goog/testing/propertyreplacer.js +0 -262
  482. package/lib/goog/testing/recordfunction.js +0 -215
  483. package/lib/goog/testing/stacktrace.js +0 -594
  484. package/lib/goog/testing/strictmock.js +0 -130
  485. package/lib/goog/testing/testcase.js +0 -1629
  486. package/lib/goog/testing/testrunner.js +0 -440
  487. package/lib/goog/uri/uri.js +0 -1524
  488. package/lib/goog/uri/utils.js +0 -1064
  489. package/lib/goog/useragent/product.js +0 -183
  490. package/lib/goog/useragent/product_isversion.js +0 -144
  491. package/lib/goog/useragent/useragent.js +0 -572
  492. package/lib/webdriver/actionsequence.js +0 -356
  493. package/lib/webdriver/builder.js +0 -207
  494. package/lib/webdriver/capabilities.js +0 -412
  495. package/lib/webdriver/events.js +0 -179
  496. package/lib/webdriver/firefoxdomexecutor.js +0 -175
  497. package/lib/webdriver/http/corsclient.js +0 -133
  498. package/lib/webdriver/http/http.js +0 -525
  499. package/lib/webdriver/http/xhrclient.js +0 -67
  500. package/lib/webdriver/locators.js +0 -257
  501. package/lib/webdriver/logging.js +0 -347
  502. package/lib/webdriver/session.js +0 -74
  503. package/lib/webdriver/stacktrace.js +0 -619
  504. package/lib/webdriver/test/builder_test.js +0 -53
  505. package/lib/webdriver/test/capabilities_test.js +0 -72
  506. package/lib/webdriver/test/events_test.js +0 -203
  507. package/lib/webdriver/test/http/corsclient_test.js +0 -151
  508. package/lib/webdriver/test/http/http_test.js +0 -428
  509. package/lib/webdriver/test/http/xhrclient_test.js +0 -196
  510. package/lib/webdriver/test/locators_test.js +0 -59
  511. package/lib/webdriver/test/logging_test.js +0 -85
  512. package/lib/webdriver/test/promise_error_test.js +0 -892
  513. package/lib/webdriver/test/promise_flow_test.js +0 -2365
  514. package/lib/webdriver/test/promise_generator_test.js +0 -323
  515. package/lib/webdriver/test/promise_test.js +0 -2012
  516. package/lib/webdriver/test/stacktrace_test.js +0 -480
  517. package/lib/webdriver/test/test_bootstrap.js +0 -67
  518. package/lib/webdriver/test/testing/asserts_test.js +0 -117
  519. package/lib/webdriver/test/testing/client_test.js +0 -88
  520. package/lib/webdriver/test/testing/testcase_test.js +0 -229
  521. package/lib/webdriver/test/testutil.js +0 -209
  522. package/lib/webdriver/test/testutil_test.js +0 -104
  523. package/lib/webdriver/test/until_test.js +0 -411
  524. package/lib/webdriver/test/webdriver_generator_test.js +0 -92
  525. package/lib/webdriver/test/webdriver_test.js +0 -2369
  526. package/lib/webdriver/testing/asserts.js +0 -487
  527. package/lib/webdriver/testing/client.js +0 -179
  528. package/lib/webdriver/testing/jsunit.js +0 -363
  529. package/lib/webdriver/testing/testcase.js +0 -168
  530. package/lib/webdriver/testing/window.js +0 -244
  531. package/lib/webdriver/touchsequence.js +0 -248
  532. package/lib/webdriver/until.js +0 -412
  533. package/lib/webdriver/webdriver.js +0 -2511
  534. package/test/_base_test.js +0 -129
@@ -15,44 +15,15 @@
15
15
  // specific language governing permissions and limitations
16
16
  // under the License.
17
17
 
18
- /**
19
- * @license Portions of this code are from the Dojo toolkit, received under the
20
- * BSD License:
21
- * Redistribution and use in source and binary forms, with or without
22
- * modification, are permitted provided that the following conditions are met:
23
- *
24
- * * Redistributions of source code must retain the above copyright notice,
25
- * this list of conditions and the following disclaimer.
26
- * * Redistributions in binary form must reproduce the above copyright notice,
27
- * this list of conditions and the following disclaimer in the documentation
28
- * and/or other materials provided with the distribution.
29
- * * Neither the name of the Dojo Foundation nor the names of its contributors
30
- * may be used to endorse or promote products derived from this software
31
- * without specific prior written permission.
32
- *
33
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
37
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43
- * POSSIBILITY OF SUCH DAMAGE.
44
- */
45
-
46
18
  /**
47
19
  * @fileoverview
48
- * The promise module is centered around the
49
- * {@linkplain webdriver.promise.ControlFlow ControlFlow}, a class that
50
- * coordinates the execution of asynchronous tasks. The ControlFlow allows users
51
- * to focus on the imperative commands for their script without worrying about
52
- * chaining together every single asynchronous action, which can be tedious and
53
- * verbose. APIs may be layered on top of the control flow to read as if they
54
- * were synchronous. For instance, the core
55
- * {@linkplain webdriver.WebDriver WebDriver} API is built on top of the
20
+ * The promise module is centered around the {@linkplain ControlFlow}, a class
21
+ * that coordinates the execution of asynchronous tasks. The ControlFlow allows
22
+ * users to focus on the imperative commands for their script without worrying
23
+ * about chaining together every single asynchronous action, which can be
24
+ * tedious and verbose. APIs may be layered on top of the control flow to read
25
+ * as if they were synchronous. For instance, the core
26
+ * {@linkplain ./webdriver.WebDriver WebDriver} API is built on top of the
56
27
  * control flow, allowing users to write
57
28
  *
58
29
  * driver.get('http://www.google.com/ncr');
@@ -79,10 +50,9 @@
79
50
  *
80
51
  * The control flow is based on the concept of tasks and task queues. Tasks are
81
52
  * functions that define the basic unit of work for the control flow to execute.
82
- * Each task is scheduled via
83
- * {@link webdriver.promise.ControlFlow#execute() ControlFlow#execute()}, which
84
- * will return a {@link webdriver.promise.Promise Promise} that will be resolved
85
- * with the task's result.
53
+ * Each task is scheduled via {@link ControlFlow#execute()}, which will return
54
+ * a {@link ManagedPromise ManagedPromise} that will be resolved with the task's
55
+ * result.
86
56
  *
87
57
  * A task queue contains all of the tasks scheduled within a single turn of the
88
58
  * [JavaScript event loop][JSEL]. The control flow will create a new task queue
@@ -98,12 +68,12 @@
98
68
  * Whenever the control flow creates a new task queue, it will automatically
99
69
  * begin executing tasks in the next available turn of the event loop. This
100
70
  * execution is scheduled using a "micro-task" timer, such as a (native)
101
- * `Promise.then()` callback.
71
+ * `ManagedPromise.then()` callback.
102
72
  *
103
73
  * setTimeout(() => console.log('a'));
104
- * Promise.resolve().then(() => console.log('b')); // A native promise.
74
+ * ManagedPromise.resolve().then(() => console.log('b')); // A native promise.
105
75
  * flow.execute(() => console.log('c'));
106
- * Promise.resolve().then(() => console.log('d'));
76
+ * ManagedPromise.resolve().then(() => console.log('d'));
107
77
  * setTimeout(() => console.log('fin'));
108
78
  * // b
109
79
  * // c
@@ -127,14 +97,13 @@
127
97
  * There are several important events that may occur while executing a task
128
98
  * function:
129
99
  *
130
- * 1. A new task queue is created by a call to
131
- * {@link webdriver.promise.ControlFlow#execute ControlFlow#execute()}. Any
132
- * tasks scheduled within this task queue are considered subtasks of the
100
+ * 1. A new task queue is created by a call to {@link ControlFlow#execute()}.
101
+ * Any tasks scheduled within this task queue are considered subtasks of the
133
102
  * current task.
134
103
  * 2. The task function throws an error. Any scheduled tasks are immediately
135
104
  * discarded and the task's promised result (previously returned by
136
- * {@link webdriver.promise.ControlFlow#execute ControlFlow#execute()}) is
137
- * immediately rejected with the thrown error.
105
+ * {@link ControlFlow#execute()}) is immediately rejected with the thrown
106
+ * error.
138
107
  * 3. The task function returns sucessfully.
139
108
  *
140
109
  * If a task function created a new task queue, the control flow will wait for
@@ -153,13 +122,12 @@
153
122
  * // b
154
123
  * // c
155
124
  *
156
- * ## Promise Integration
125
+ * ## ManagedPromise Integration
157
126
  *
158
- * In addition to the {@link webdriver.promise.ControlFlow ControlFlow} class,
159
- * the promise module also exports a [Promise/A+]
160
- * {@linkplain webdriver.promise.Promise implementation} that is deeply
127
+ * In addition to the {@link ControlFlow} class, the promise module also exports
128
+ * a [ManagedPromise/A+] {@linkplain ManagedPromise implementation} that is deeply
161
129
  * integrated with the ControlFlow. First and foremost, each promise
162
- * {@linkplain webdriver.promise.Promise#then() callback} is scheduled with the
130
+ * {@linkplain ManagedPromise#then() callback} is scheduled with the
163
131
  * control flow as a task. As a result, each callback is invoked in its own turn
164
132
  * of the JavaScript event loop with its own task queue. If any tasks are
165
133
  * scheduled within a callback, the callback's promised result will not be
@@ -173,7 +141,7 @@
173
141
  * // b
174
142
  * // a
175
143
  *
176
- * ### Scheduling Promise Callbacks <a id="scheduling_callbacks"></a>
144
+ * ### Scheduling ManagedPromise Callbacks <a id="scheduling_callbacks"></a>
177
145
  *
178
146
  * How callbacks are scheduled in the control flow depends on when they are
179
147
  * attached to the promise. Callbacks attached to a _previously_ resolved
@@ -463,18 +431,17 @@
463
431
  *
464
432
  * ES6 promises do not require users to handle a promise rejections. This can
465
433
  * result in subtle bugs as the rejections are silently "swallowed" by the
466
- * Promise class.
434
+ * ManagedPromise class.
467
435
  *
468
- * Promise.reject(Error('boom'));
436
+ * ManagedPromise.reject(Error('boom'));
469
437
  * // ... *crickets* ...
470
438
  *
471
- * Selenium's {@link webdriver.promise promise} module, on the other hand,
472
- * requires that every rejection be explicitly handled. When a
473
- * {@linkplain webdriver.promise.Promise Promise} is rejected and no callbacks
474
- * are defined on that promise, it is considered an _unhandled rejection_ and
475
- * reproted to the active task queue. If the rejection remains unhandled after
476
- * a single turn of the [event loop][JSEL] (scheduled with a micro-task), it
477
- * will propagate up the stack.
439
+ * Selenium's promise module, on the other hand, requires that every rejection
440
+ * be explicitly handled. When a {@linkplain ManagedPromise ManagedPromise} is
441
+ * rejected and no callbacks are defined on that promise, it is considered an
442
+ * _unhandled rejection_ and reproted to the active task queue. If the rejection
443
+ * remains unhandled after a single turn of the [event loop][JSEL] (scheduled
444
+ * with a micro-task), it will propagate up the stack.
478
445
  *
479
446
  * ## Error Propagation
480
447
  *
@@ -485,7 +452,7 @@
485
452
  * // No callbacks registered on promise -> unhandled rejection
486
453
  * promise.rejected(Error('boom'));
487
454
  * flow.execute(function() { console.log('this will never run'); });
488
- * }).thenCatch(function(e) {
455
+ * }).catch(function(e) {
489
456
  * console.log(e.message);
490
457
  * });
491
458
  * // boom
@@ -497,7 +464,7 @@
497
464
  * promise.rejected(Error('boom'));
498
465
  * flow.execute(function() { console.log('a'); }).
499
466
  * then(function() { console.log('b'); });
500
- * }).thenCatch(function(e) {
467
+ * }).catch(function(e) {
501
468
  * console.log(e.message);
502
469
  * });
503
470
  * // boom
@@ -508,21 +475,20 @@
508
475
  * flow.execute(function() {
509
476
  * promise.rejected(Error('boom'));
510
477
  * return flow.execute(someOtherTask);
511
- * }).thenCatch(function(e) {
478
+ * }).catch(function(e) {
512
479
  * console.log(e.message);
513
480
  * });
514
481
  * // boom
515
482
  *
516
483
  * If there are multiple unhandled rejections within a task, they are packaged
517
- * in a {@link webdriver.promise.MultipleUnhandledRejectionError
518
- * MultipleUnhandledRejectionError}, which has an `errors` property that is a
519
- * `Set` of the recorded unhandled rejections:
484
+ * in a {@link MultipleUnhandledRejectionError}, which has an `errors` property
485
+ * that is a `Set` of the recorded unhandled rejections:
520
486
  *
521
487
  * flow.execute(function() {
522
488
  * promise.rejected(Error('boom1'));
523
489
  * promise.rejected(Error('boom2'));
524
- * }).thenCatch(function(ex) {
525
- * console.log(ex instanceof promise.MultipleUnhandledRejectionError);
490
+ * }).catch(function(ex) {
491
+ * console.log(ex instanceof MultipleUnhandledRejectionError);
526
492
  * for (var e of ex.errors) {
527
493
  * console.log(e.message);
528
494
  * }
@@ -542,7 +508,7 @@
542
508
  * flow.execute(function() {
543
509
  * promise.rejected(Error('boom'));
544
510
  * subTask = flow.execute(function() {});
545
- * }).thenCatch(function(e) {
511
+ * }).catch(function(e) {
546
512
  * console.log(e.message);
547
513
  * }).then(function() {
548
514
  * return subTask.then(
@@ -564,7 +530,7 @@
564
530
  * throw Error('fail!');
565
531
  * });
566
532
  * });
567
- * }).thenCatch(function(e) {
533
+ * }).catch(function(e) {
568
534
  * console.log(e.message);
569
535
  * });
570
536
  * // fail!
@@ -580,9 +546,9 @@
580
546
  *
581
547
  * Bottom line: you __*must*__ handle rejected promises.
582
548
  *
583
- * # Promise/A+ Compatibility
549
+ * # ManagedPromise/A+ Compatibility
584
550
  *
585
- * This `promise` module is compliant with the [Promise/A+][] specification
551
+ * This `promise` module is compliant with the [ManagedPromise/A+][] specification
586
552
  * except for sections `2.2.6.1` and `2.2.6.2`:
587
553
  *
588
554
  * >
@@ -596,7 +562,7 @@
596
562
  * Specifically, the conformance tests contains the following scenario (for
597
563
  * brevity, only the fulfillment version is shown):
598
564
  *
599
- * var p1 = Promise.resolve();
565
+ * var p1 = ManagedPromise.resolve();
600
566
  * p1.then(function() {
601
567
  * console.log('A');
602
568
  * p1.then(() => console.log('B'));
@@ -621,36 +587,73 @@
621
587
  *
622
588
  * [JSEL]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
623
589
  * [GF]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
624
- * [Promise/A+]: https://promisesaplus.com/
590
+ * [ManagedPromise/A+]: https://promisesaplus.com/
625
591
  */
626
592
 
627
- goog.module('webdriver.promise');
628
- goog.module.declareLegacyNamespace();
593
+ 'use strict';
629
594
 
630
- var Arrays = goog.require('goog.array');
631
- var asserts = goog.require('goog.asserts');
632
- var asyncRun = goog.require('goog.async.run');
633
- var throwException = goog.require('goog.async.throwException');
634
- var DebugError = goog.require('goog.debug.Error');
635
- var log = goog.require('goog.log');
636
- var Objects = goog.require('goog.object');
637
- var EventEmitter = goog.require('webdriver.EventEmitter');
638
- var stacktrace = goog.require('webdriver.stacktrace');
595
+ const events = require('./events');
596
+ const logging = require('./logging');
639
597
 
640
598
 
599
+ /**
600
+ * Alias to help with readability and differentiate types.
601
+ * @const
602
+ */
603
+ const NativePromise = Promise;
604
+
641
605
 
642
606
  /**
643
- * @define {boolean} Whether to append traces of {@code then} to rejection
644
- * errors.
607
+ * Whether to append traces of `then` to rejection errors.
608
+ * @type {boolean}
645
609
  */
646
- goog.define('webdriver.promise.LONG_STACK_TRACES', false);
610
+ var LONG_STACK_TRACES = false; // TODO: this should not be CONSTANT_CASE
611
+
647
612
 
648
613
  /** @const */
649
- var promise = exports;
614
+ const LOG = logging.getLogger('promise');
650
615
 
651
616
 
652
- /** @const */
653
- var LOG = log.getLogger('webdriver.promise');
617
+ const UNIQUE_IDS = new WeakMap;
618
+ let nextId = 1;
619
+
620
+
621
+ function getUid(obj) {
622
+ let id = UNIQUE_IDS.get(obj);
623
+ if (!id) {
624
+ id = nextId;
625
+ nextId += 1;
626
+ UNIQUE_IDS.set(obj, id);
627
+ }
628
+ return id;
629
+ }
630
+
631
+
632
+ /**
633
+ * Runs the given function after a micro-task yield.
634
+ * @param {function()} fn The function to run.
635
+ */
636
+ function asyncRun(fn) {
637
+ NativePromise.resolve().then(function() {
638
+ try {
639
+ fn();
640
+ } catch (ignored) {
641
+ // Do nothing.
642
+ }
643
+ });
644
+ }
645
+
646
+
647
+ /**
648
+ * Throws an error asynchronously so it is reported to the global error handler.
649
+ *
650
+ * @param {!Error} error The error to throw.
651
+ */
652
+ function asyncThrow(error) {
653
+ setTimeout(function() {
654
+ throw error;
655
+ }, 0);
656
+ }
654
657
 
655
658
 
656
659
  /**
@@ -661,18 +664,18 @@ var LOG = log.getLogger('webdriver.promise');
661
664
  * @template T
662
665
  */
663
666
  function vlog(level, loggable, opt_self) {
664
- var logLevel = log.Level.FINE;
667
+ var logLevel = logging.Level.FINE;
665
668
  if (level > 1) {
666
- logLevel = log.Level.FINEST;
669
+ logLevel = logging.Level.FINEST;
667
670
  } else if (level > 0) {
668
- logLevel = log.Level.FINER;
671
+ logLevel = logging.Level.FINER;
669
672
  }
670
673
 
671
674
  if (typeof loggable === 'function') {
672
675
  loggable = loggable.bind(opt_self);
673
676
  }
674
677
 
675
- log.log(LOG, logLevel, loggable);
678
+ LOG.log(logLevel, loggable);
676
679
  }
677
680
 
678
681
 
@@ -680,150 +683,134 @@ function vlog(level, loggable, opt_self) {
680
683
  * Generates an error to capture the current stack trace.
681
684
  * @param {string} name Error name for this stack trace.
682
685
  * @param {string} msg Message to record.
683
- * @param {!Function} topFn The function that should appear at the top of the
684
- * stack; only applicable in V8.
686
+ * @param {Function=} opt_topFn The function that should appear at the top of
687
+ * the stack; only applicable in V8.
685
688
  * @return {!Error} The generated error.
686
689
  */
687
- promise.captureStackTrace = function(name, msg, topFn) {
690
+ function captureStackTrace(name, msg, opt_topFn) {
688
691
  var e = Error(msg);
689
692
  e.name = name;
690
693
  if (Error.captureStackTrace) {
691
- Error.captureStackTrace(e, topFn);
694
+ Error.captureStackTrace(e, opt_topFn);
692
695
  } else {
693
- var stack = stacktrace.getStack(e);
694
- e.stack = e.toString();
696
+ var stack = Error().stack;
695
697
  if (stack) {
698
+ e.stack = e.toString();
696
699
  e.stack += '\n' + stack;
697
700
  }
698
701
  }
699
702
  return e;
700
- };
703
+ }
701
704
 
702
705
 
703
706
  /**
704
707
  * Error used when the computation of a promise is cancelled.
705
- *
706
- * @unrestricted
707
708
  */
708
- promise.CancellationError = goog.defineClass(DebugError, {
709
+ class CancellationError extends Error {
709
710
  /**
710
711
  * @param {string=} opt_msg The cancellation message.
711
712
  */
712
- constructor: function(opt_msg) {
713
- promise.CancellationError.base(this, 'constructor', opt_msg);
713
+ constructor(opt_msg) {
714
+ super(opt_msg);
714
715
 
715
716
  /** @override */
716
- this.name = 'CancellationError';
717
+ this.name = this.constructor.name;
717
718
 
718
719
  /** @private {boolean} */
719
720
  this.silent_ = false;
720
- },
721
+ }
721
722
 
722
- statics: {
723
- /**
724
- * Wraps the given error in a CancellationError.
725
- *
726
- * @param {*} error The error to wrap.
727
- * @param {string=} opt_msg The prefix message to use.
728
- * @return {!promise.CancellationError} A cancellation error.
729
- */
730
- wrap: function(error, opt_msg) {
731
- var message;
732
- if (error instanceof promise.CancellationError) {
733
- return new promise.CancellationError(
734
- opt_msg ? (opt_msg + ': ' + error.message) : error.message);
735
- } else if (opt_msg) {
736
- message = opt_msg;
737
- if (error) {
738
- message += ': ' + error;
739
- }
740
- return new promise.CancellationError(message);
741
- }
723
+ /**
724
+ * Wraps the given error in a CancellationError.
725
+ *
726
+ * @param {*} error The error to wrap.
727
+ * @param {string=} opt_msg The prefix message to use.
728
+ * @return {!CancellationError} A cancellation error.
729
+ */
730
+ static wrap(error, opt_msg) {
731
+ var message;
732
+ if (error instanceof CancellationError) {
733
+ return new CancellationError(
734
+ opt_msg ? (opt_msg + ': ' + error.message) : error.message);
735
+ } else if (opt_msg) {
736
+ message = opt_msg;
742
737
  if (error) {
743
- message = error + '';
738
+ message += ': ' + error;
744
739
  }
745
- return new promise.CancellationError(message);
740
+ return new CancellationError(message);
746
741
  }
742
+ if (error) {
743
+ message = error + '';
744
+ }
745
+ return new CancellationError(message);
747
746
  }
748
- });
747
+ }
749
748
 
750
749
 
751
750
  /**
752
751
  * Error used to cancel tasks when a control flow is reset.
753
- * @unrestricted
754
752
  * @final
755
753
  */
756
- var FlowResetError = goog.defineClass(promise.CancellationError, {
757
- constructor: function() {
758
- FlowResetError.base(this, 'constructor', 'ControlFlow was reset');
759
-
760
- /** @override */
761
- this.name = 'FlowResetError';
762
-
754
+ class FlowResetError extends CancellationError {
755
+ constructor() {
756
+ super('ControlFlow was reset');
763
757
  this.silent_ = true;
764
758
  }
765
- });
759
+ }
766
760
 
767
761
 
768
762
  /**
769
763
  * Error used to cancel tasks that have been discarded due to an uncaught error
770
764
  * reported earlier in the control flow.
771
- * @unrestricted
772
765
  * @final
773
766
  */
774
- var DiscardedTaskError = goog.defineClass(promise.CancellationError, {
767
+ class DiscardedTaskError extends CancellationError {
775
768
  /** @param {*} error The original error. */
776
- constructor: function(error) {
769
+ constructor(error) {
777
770
  if (error instanceof DiscardedTaskError) {
778
771
  return /** @type {!DiscardedTaskError} */(error);
779
772
  }
780
773
 
781
774
  var msg = '';
782
775
  if (error) {
783
- msg = ': ' + (typeof error.message === 'string' ? error.message : error);
776
+ msg = ': ' + (
777
+ typeof error.message === 'string' ? error.message : error);
784
778
  }
785
779
 
786
- DiscardedTaskError.base(this, 'constructor',
787
- 'Task was discarded due to a previous failure' + msg);
788
-
789
- /** @override */
790
- this.name = 'DiscardedTaskError';
780
+ super('Task was discarded due to a previous failure' + msg);
791
781
  this.silent_ = true;
792
782
  }
793
- });
783
+ }
794
784
 
795
785
 
796
786
  /**
797
787
  * Error used when there are multiple unhandled promise rejections detected
798
788
  * within a task or callback.
799
789
  *
800
- * @unrestricted
801
790
  * @final
802
791
  */
803
- promise.MultipleUnhandledRejectionError = goog.defineClass(DebugError, {
792
+ class MultipleUnhandledRejectionError extends Error {
804
793
  /**
805
794
  * @param {!(Set<*>)} errors The errors to report.
806
795
  */
807
- constructor: function(errors) {
808
- promise.MultipleUnhandledRejectionError.base(
809
- this, 'constructor', 'Multiple unhandled promise rejections reported');
796
+ constructor(errors) {
797
+ super('Multiple unhandled promise rejections reported');
810
798
 
811
799
  /** @override */
812
- this.name = 'MultipleUnhandledRejectionError';
800
+ this.name = this.constructor.name;
813
801
 
814
802
  /** @type {!Set<*>} */
815
803
  this.errors = errors;
816
804
  }
817
- });
805
+ }
818
806
 
819
807
 
820
808
  /**
821
809
  * Property used to flag constructor's as implementing the Thenable interface
822
810
  * for runtime type checking.
823
- * @type {string}
824
811
  * @const
825
812
  */
826
- var IMPLEMENTED_BY_PROP = '$webdriver_Thenable';
813
+ const IMPLEMENTED_BY_SYMBOL = Symbol('promise.Thenable');
827
814
 
828
815
 
829
816
  /**
@@ -834,64 +821,54 @@ var IMPLEMENTED_BY_PROP = '$webdriver_Thenable';
834
821
  * @extends {IThenable<T>}
835
822
  * @template T
836
823
  */
837
- promise.Thenable = goog.defineClass(null, {
838
- statics: {
839
- /**
840
- * Adds a property to a class prototype to allow runtime checks of whether
841
- * instances of that class implement the Thenable interface. This function
842
- * will also ensure the prototype's {@code then} function is exported from
843
- * compiled code.
844
- * @param {function(new: promise.Thenable, ...?)} ctor The
845
- * constructor whose prototype to modify.
846
- */
847
- addImplementation: function(ctor) {
848
- // Based on goog.promise.Thenable.isImplementation.
849
- ctor.prototype['then'] = ctor.prototype.then;
850
- try {
851
- // Old IE7 does not support defineProperty; IE8 only supports it for
852
- // DOM elements.
853
- Object.defineProperty(
854
- ctor.prototype,
855
- IMPLEMENTED_BY_PROP,
856
- {'value': true, 'enumerable': false});
857
- } catch (ex) {
858
- ctor.prototype[IMPLEMENTED_BY_PROP] = true;
859
- }
860
- },
824
+ class Thenable {
825
+ /**
826
+ * Adds a property to a class prototype to allow runtime checks of whether
827
+ * instances of that class implement the Thenable interface. This function
828
+ * will also ensure the prototype's {@code then} function is exported from
829
+ * compiled code.
830
+ * @param {function(new: Thenable, ...?)} ctor The
831
+ * constructor whose prototype to modify.
832
+ */
833
+ static addImplementation(ctor) {
834
+ ctor.prototype['then'] = ctor.prototype.then;
835
+ try {
836
+ ctor.prototype[IMPLEMENTED_BY_SYMBOL] = true;
837
+ } catch (ignored) {
838
+ // Property access denied?
839
+ }
840
+ }
861
841
 
862
- /**
863
- * Checks if an object has been tagged for implementing the Thenable
864
- * interface as defined by
865
- * {@link webdriver.promise.Thenable.addImplementation}.
866
- * @param {*} object The object to test.
867
- * @return {boolean} Whether the object is an implementation of the Thenable
868
- * interface.
869
- */
870
- isImplementation: function(object) {
871
- // Based on goog.promise.Thenable.isImplementation.
872
- if (!object) {
873
- return false;
874
- }
875
- try {
876
- return !!object[IMPLEMENTED_BY_PROP];
877
- } catch (e) {
878
- return false; // Property access seems to be forbidden.
879
- }
842
+ /**
843
+ * Checks if an object has been tagged for implementing the Thenable
844
+ * interface as defined by {@link Thenable.addImplementation}.
845
+ * @param {*} object The object to test.
846
+ * @return {boolean} Whether the object is an implementation of the Thenable
847
+ * interface.
848
+ */
849
+ static isImplementation(object) {
850
+ if (!object) {
851
+ return false;
880
852
  }
881
- },
853
+ try {
854
+ return !!object[IMPLEMENTED_BY_SYMBOL];
855
+ } catch (e) {
856
+ return false; // Property access seems to be forbidden.
857
+ }
858
+ }
882
859
 
883
860
  /**
884
861
  * Cancels the computation of this promise's value, rejecting the promise in
885
862
  * the process. This method is a no-op if the promise has already been
886
863
  * resolved.
887
864
  *
888
- * @param {(string|promise.CancellationError)=} opt_reason The reason this
889
- * promise is being cancelled.
865
+ * @param {(string|Error)=} opt_reason The reason this promise is being
866
+ * cancelled. This value will be wrapped in a {@link CancellationError}.
890
867
  */
891
- cancel: function(opt_reason) {},
868
+ cancel(opt_reason) {}
892
869
 
893
870
  /** @return {boolean} Whether this promise's value is still being computed. */
894
- isPending: function() {},
871
+ isPending() {}
895
872
 
896
873
  /**
897
874
  * Registers listeners for when this instance is resolved.
@@ -902,11 +879,11 @@ promise.Thenable = goog.defineClass(null, {
902
879
  * @param {?(function(*): (R|IThenable<R>))=} opt_errback
903
880
  * The function to call if this promise is rejected. The function should
904
881
  * expect a single argument: the rejection reason.
905
- * @return {!promise.Promise<R>} A new promise which will be
882
+ * @return {!ManagedPromise<R>} A new promise which will be
906
883
  * resolved with the result of the invoked callback.
907
884
  * @template R
908
885
  */
909
- then: function(opt_callback, opt_errback) {},
886
+ then(opt_callback, opt_errback) {}
910
887
 
911
888
  /**
912
889
  * Registers a listener for when this promise is rejected. This is synonymous
@@ -920,18 +897,69 @@ promise.Thenable = goog.defineClass(null, {
920
897
  * }
921
898
  *
922
899
  * // Asynchronous promise API:
923
- * doAsynchronousWork().thenCatch(function(ex) {
900
+ * doAsynchronousWork().catch(function(ex) {
924
901
  * console.error(ex);
925
902
  * });
926
903
  *
927
904
  * @param {function(*): (R|IThenable<R>)} errback The
928
905
  * function to call if this promise is rejected. The function should
929
906
  * expect a single argument: the rejection reason.
930
- * @return {!promise.Promise<R>} A new promise which will be
907
+ * @return {!ManagedPromise<R>} A new promise which will be
931
908
  * resolved with the result of the invoked callback.
932
909
  * @template R
933
910
  */
934
- thenCatch: function(errback) {},
911
+ catch(errback) {}
912
+
913
+ /**
914
+ * An alias for {@link #catch()}
915
+ *
916
+ * @param {function(*): (R|IThenable<R>)} errback The
917
+ * function to call if this promise is rejected. The function should
918
+ * expect a single argument: the rejection reason.
919
+ * @return {!ManagedPromise<R>} A new promise which will be
920
+ * resolved wdith the result of the invoked callback.
921
+ * @deprecated Use {@link #catch()} instead.
922
+ * @template R
923
+ */
924
+ thenCatch(errback) {}
925
+
926
+ /**
927
+ * Registers a listener to invoke when this promise is resolved, regardless
928
+ * of whether the promise's value was successfully computed. This function
929
+ * is synonymous with the {@code finally} clause in a synchronous API:
930
+ *
931
+ * // Synchronous API:
932
+ * try {
933
+ * doSynchronousWork();
934
+ * } finally {
935
+ * cleanUp();
936
+ * }
937
+ *
938
+ * // Asynchronous promise API:
939
+ * doAsynchronousWork().finally(cleanUp);
940
+ *
941
+ * __Note:__ similar to the {@code finally} clause, if the registered
942
+ * callback returns a rejected promise or throws an error, it will silently
943
+ * replace the rejection error (if any) from this promise:
944
+ *
945
+ * try {
946
+ * throw Error('one');
947
+ * } finally {
948
+ * throw Error('two'); // Hides Error: one
949
+ * }
950
+ *
951
+ * promise.rejected(Error('one'))
952
+ * .finally(function() {
953
+ * throw Error('two'); // Hides Error: one
954
+ * });
955
+ *
956
+ * @param {function(): (R|IThenable<R>)} callback The function to call when
957
+ * this promise is resolved.
958
+ * @return {!ManagedPromise<R>} A promise that will be fulfilled
959
+ * with the callback result.
960
+ * @template R
961
+ */
962
+ finally(callback) {}
935
963
 
936
964
  /**
937
965
  * Registers a listener to invoke when this promise is resolved, regardless
@@ -965,19 +993,18 @@ promise.Thenable = goog.defineClass(null, {
965
993
  *
966
994
  * @param {function(): (R|IThenable<R>)} callback The function
967
995
  * to call when this promise is resolved.
968
- * @return {!promise.Promise<R>} A promise that will be fulfilled
996
+ * @return {!ManagedPromise<R>} A promise that will be fulfilled
969
997
  * with the callback result.
998
+ * @deprecated Use {@link #finally()} instead.
970
999
  * @template R
971
1000
  */
972
- thenFinally: function(callback) {}
973
- });
974
-
1001
+ thenFinally(callback) {}}
975
1002
 
976
1003
 
977
1004
  /**
978
1005
  * @enum {string}
979
1006
  */
980
- var PromiseState = {
1007
+ const PromiseState = {
981
1008
  PENDING: 'pending',
982
1009
  BLOCKED: 'blocked',
983
1010
  REJECTED: 'rejected',
@@ -987,11 +1014,11 @@ var PromiseState = {
987
1014
 
988
1015
  /**
989
1016
  * Internal symbol used to store a cancellation handler for
990
- * {@link promise.Promise} objects. This is an internal implementation detail
1017
+ * {@link ManagedPromise} objects. This is an internal implementation detail
991
1018
  * used by the {@link TaskQueue} class to monitor for when a promise is
992
1019
  * cancelled without generating an extra promise via then().
993
1020
  */
994
- var CANCEL_HANDLER_SYMBOL = Symbol('on cancel');
1021
+ const CANCEL_HANDLER_SYMBOL = Symbol('on cancel');
995
1022
 
996
1023
 
997
1024
  /**
@@ -1001,12 +1028,12 @@ var CANCEL_HANDLER_SYMBOL = Symbol('on cancel');
1001
1028
  * fulfilled or rejected state, at which point the promise is considered
1002
1029
  * resolved.
1003
1030
  *
1004
- * @implements {promise.Thenable<T>}
1031
+ * @implements {Thenable<T>}
1032
+ * @unrestricted
1005
1033
  * @template T
1006
1034
  * @see http://promises-aplus.github.io/promises-spec/
1007
- * @unrestricted // For using CANCEL_HANDLER_SYMBOL.
1008
1035
  */
1009
- promise.Promise = goog.defineClass(null, {
1036
+ class ManagedPromise {
1010
1037
  /**
1011
1038
  * @param {function(
1012
1039
  * function((T|IThenable<T>|Thenable)=),
@@ -1014,23 +1041,22 @@ promise.Promise = goog.defineClass(null, {
1014
1041
  * Function that is invoked immediately to begin computation of this
1015
1042
  * promise's value. The function should accept a pair of callback
1016
1043
  * functions, one for fulfilling the promise and another for rejecting it.
1017
- * @param {promise.ControlFlow=} opt_flow The control flow
1044
+ * @param {ControlFlow=} opt_flow The control flow
1018
1045
  * this instance was created under. Defaults to the currently active flow.
1019
1046
  */
1020
- constructor: function(resolver, opt_flow) {
1021
- goog.getUid(this);
1047
+ constructor(resolver, opt_flow) {
1048
+ getUid(this);
1022
1049
 
1023
- /** @private {!promise.ControlFlow} */
1024
- this.flow_ = opt_flow || promise.controlFlow();
1050
+ /** @private {!ControlFlow} */
1051
+ this.flow_ = opt_flow || controlFlow();
1025
1052
 
1026
1053
  /** @private {Error} */
1027
1054
  this.stack_ = null;
1028
- if (promise.LONG_STACK_TRACES) {
1029
- this.stack_ = promise.captureStackTrace(
1030
- 'Promise', 'new', promise.Promise);
1055
+ if (LONG_STACK_TRACES) {
1056
+ this.stack_ = captureStackTrace('ManagedPromise', 'new', this.constructor);
1031
1057
  }
1032
1058
 
1033
- /** @private {promise.Promise<?>} */
1059
+ /** @private {ManagedPromise<?>} */
1034
1060
  this.parent_ = null;
1035
1061
 
1036
1062
  /** @private {Array<!Task>} */
@@ -1048,7 +1074,7 @@ promise.Promise = goog.defineClass(null, {
1048
1074
  /** @private {TaskQueue} */
1049
1075
  this.queue_ = null;
1050
1076
 
1051
- /** @private {(function(promise.CancellationError)|null)} */
1077
+ /** @private {(function(CancellationError)|null)} */
1052
1078
  this[CANCEL_HANDLER_SYMBOL] = null;
1053
1079
 
1054
1080
  try {
@@ -1061,13 +1087,13 @@ promise.Promise = goog.defineClass(null, {
1061
1087
  } catch (ex) {
1062
1088
  this.resolve_(PromiseState.REJECTED, ex);
1063
1089
  }
1064
- },
1090
+ }
1065
1091
 
1066
1092
  /** @override */
1067
- toString: function() {
1068
- return 'Promise::' + goog.getUid(this) +
1093
+ toString() {
1094
+ return 'ManagedPromise::' + getUid(this) +
1069
1095
  ' {[[PromiseStatus]]: "' + this.state_ + '"}';
1070
- },
1096
+ }
1071
1097
 
1072
1098
  /**
1073
1099
  * Resolves this promise. If the new value is itself a promise, this function
@@ -1077,7 +1103,7 @@ promise.Promise = goog.defineClass(null, {
1077
1103
  * @throws {TypeError} If {@code newValue === this}.
1078
1104
  * @private
1079
1105
  */
1080
- resolve_: function(newState, newValue) {
1106
+ resolve_(newState, newValue) {
1081
1107
  if (PromiseState.PENDING !== this.state_) {
1082
1108
  return;
1083
1109
  }
@@ -1093,15 +1119,16 @@ promise.Promise = goog.defineClass(null, {
1093
1119
  this.state_ = PromiseState.BLOCKED;
1094
1120
 
1095
1121
  if (newState !== PromiseState.REJECTED) {
1096
- if (promise.Thenable.isImplementation(newValue)) {
1122
+ if (Thenable.isImplementation(newValue)) {
1097
1123
  // 2.3.2
1098
- newValue = /** @type {!promise.Thenable} */(newValue);
1124
+ newValue = /** @type {!Thenable} */(newValue);
1099
1125
  newValue.then(
1100
1126
  this.unblockAndResolve_.bind(this, PromiseState.FULFILLED),
1101
1127
  this.unblockAndResolve_.bind(this, PromiseState.REJECTED));
1102
1128
  return;
1103
1129
 
1104
- } else if (goog.isObject(newValue)) {
1130
+ } else if (newValue
1131
+ && (typeof newValue === 'object' || typeof newValue === 'function')) {
1105
1132
  // 2.3.3
1106
1133
 
1107
1134
  try {
@@ -1115,10 +1142,9 @@ promise.Promise = goog.defineClass(null, {
1115
1142
  return;
1116
1143
  }
1117
1144
 
1118
- // NB: goog.isFunction is loose and will accept instanceof Function.
1119
1145
  if (typeof then === 'function') {
1120
1146
  // 2.3.3.3
1121
- this.invokeThen_(newValue, then);
1147
+ this.invokeThen_(/** @type {!Object} */(newValue), then);
1122
1148
  return;
1123
1149
  }
1124
1150
  }
@@ -1133,7 +1159,7 @@ promise.Promise = goog.defineClass(null, {
1133
1159
  this.state_ = newState;
1134
1160
  this.value_ = newValue;
1135
1161
  this.scheduleNotifications_();
1136
- },
1162
+ }
1137
1163
 
1138
1164
  /**
1139
1165
  * Invokes a thenable's "then" method according to 2.3.3.3 of the promise
@@ -1142,7 +1168,7 @@ promise.Promise = goog.defineClass(null, {
1142
1168
  * @param {!Function} then The "then" function to invoke.
1143
1169
  * @private
1144
1170
  */
1145
- invokeThen_: function(x, then) {
1171
+ invokeThen_(x, then) {
1146
1172
  var called = false;
1147
1173
  var self = this;
1148
1174
 
@@ -1169,28 +1195,28 @@ promise.Promise = goog.defineClass(null, {
1169
1195
  // 2.3.3.3.4.2
1170
1196
  rejectPromise(e);
1171
1197
  }
1172
- },
1198
+ }
1173
1199
 
1174
1200
  /**
1175
1201
  * @param {PromiseState} newState The promise's new state.
1176
1202
  * @param {*} newValue The promise's new value.
1177
1203
  * @private
1178
1204
  */
1179
- unblockAndResolve_: function(newState, newValue) {
1205
+ unblockAndResolve_(newState, newValue) {
1180
1206
  if (this.state_ === PromiseState.BLOCKED) {
1181
1207
  this.state_ = PromiseState.PENDING;
1182
1208
  this.resolve_(newState, newValue);
1183
1209
  }
1184
- },
1210
+ }
1185
1211
 
1186
1212
  /**
1187
1213
  * @private
1188
1214
  */
1189
- scheduleNotifications_: function() {
1215
+ scheduleNotifications_() {
1190
1216
  vlog(2, () => this + ' scheduling notifications', this);
1191
1217
 
1192
1218
  this[CANCEL_HANDLER_SYMBOL] = null;
1193
- if (this.value_ instanceof promise.CancellationError
1219
+ if (this.value_ instanceof CancellationError
1194
1220
  && this.value_.silent_) {
1195
1221
  this.callbacks_ = null;
1196
1222
  }
@@ -1201,14 +1227,14 @@ promise.Promise = goog.defineClass(null, {
1201
1227
 
1202
1228
  if (!this.handled_ &&
1203
1229
  this.state_ === PromiseState.REJECTED &&
1204
- !(this.value_ instanceof promise.CancellationError)) {
1230
+ !(this.value_ instanceof CancellationError)) {
1205
1231
  this.queue_.addUnhandledRejection(this);
1206
1232
  }
1207
1233
  this.queue_.scheduleCallbacks(this);
1208
- },
1234
+ }
1209
1235
 
1210
1236
  /** @override */
1211
- cancel: function(opt_reason) {
1237
+ cancel(opt_reason) {
1212
1238
  if (!canCancel(this)) {
1213
1239
  return;
1214
1240
  }
@@ -1216,7 +1242,7 @@ promise.Promise = goog.defineClass(null, {
1216
1242
  if (this.parent_ && canCancel(this.parent_)) {
1217
1243
  this.parent_.cancel(opt_reason);
1218
1244
  } else {
1219
- var reason = promise.CancellationError.wrap(opt_reason);
1245
+ var reason = CancellationError.wrap(opt_reason);
1220
1246
  if (this[CANCEL_HANDLER_SYMBOL]) {
1221
1247
  this[CANCEL_HANDLER_SYMBOL](reason);
1222
1248
  this[CANCEL_HANDLER_SYMBOL] = null;
@@ -1233,27 +1259,35 @@ promise.Promise = goog.defineClass(null, {
1233
1259
  return promise.state_ === PromiseState.PENDING
1234
1260
  || promise.state_ === PromiseState.BLOCKED;
1235
1261
  }
1236
- },
1262
+ }
1237
1263
 
1238
1264
  /** @override */
1239
- isPending: function() {
1265
+ isPending() {
1240
1266
  return this.state_ === PromiseState.PENDING;
1241
- },
1267
+ }
1242
1268
 
1243
1269
  /** @override */
1244
- then: function(opt_callback, opt_errback) {
1270
+ then(opt_callback, opt_errback) {
1245
1271
  return this.addCallback_(
1246
- opt_callback, opt_errback, 'then', promise.Promise.prototype.then);
1247
- },
1272
+ opt_callback, opt_errback, 'then', ManagedPromise.prototype.then);
1273
+ }
1248
1274
 
1249
1275
  /** @override */
1250
- thenCatch: function(errback) {
1276
+ catch(errback) {
1251
1277
  return this.addCallback_(
1252
- null, errback, 'thenCatch', promise.Promise.prototype.thenCatch);
1253
- },
1278
+ null, errback, 'catch', ManagedPromise.prototype.catch);
1279
+ }
1280
+
1281
+ /**
1282
+ * @override
1283
+ * @deprecated Use {@link #catch()} instead.
1284
+ */
1285
+ thenCatch(errback) {
1286
+ return this.catch(errback);
1287
+ }
1254
1288
 
1255
1289
  /** @override */
1256
- thenFinally: function(callback) {
1290
+ finally(callback) {
1257
1291
  var error;
1258
1292
  var mustThrow = false;
1259
1293
  return this.then(function() {
@@ -1267,7 +1301,15 @@ promise.Promise = goog.defineClass(null, {
1267
1301
  throw error;
1268
1302
  }
1269
1303
  });
1270
- },
1304
+ }
1305
+
1306
+ /**
1307
+ * @override
1308
+ * @deprecated Use {@link #finally()} instead.
1309
+ */
1310
+ thenFinally(callback) {
1311
+ return this.finally(callback);
1312
+ }
1271
1313
 
1272
1314
  /**
1273
1315
  * Registers a new callback with this promise
@@ -1278,13 +1320,13 @@ promise.Promise = goog.defineClass(null, {
1278
1320
  * @param {string} name The callback name.
1279
1321
  * @param {!Function} fn The function to use as the top of the stack when
1280
1322
  * recording the callback's creation point.
1281
- * @return {!promise.Promise<R>} A new promise which will be resolved with the
1323
+ * @return {!ManagedPromise<R>} A new promise which will be resolved with the
1282
1324
  * esult of the invoked callback.
1283
1325
  * @template R
1284
1326
  * @private
1285
1327
  */
1286
- addCallback_: function(callback, errback, name, fn) {
1287
- if (!goog.isFunction(callback) && !goog.isFunction(errback)) {
1328
+ addCallback_(callback, errback, name, fn) {
1329
+ if (typeof callback !== 'function' && typeof errback !== 'function') {
1288
1330
  return this;
1289
1331
  }
1290
1332
 
@@ -1297,7 +1339,7 @@ promise.Promise = goog.defineClass(null, {
1297
1339
  this.flow_,
1298
1340
  this.invokeCallback_.bind(this, callback, errback),
1299
1341
  name,
1300
- promise.LONG_STACK_TRACES ? {name: 'Promise', top: fn} : undefined);
1342
+ LONG_STACK_TRACES ? {name: 'Promise', top: fn} : undefined);
1301
1343
  cb.promise.parent_ = this;
1302
1344
 
1303
1345
  if (this.state_ !== PromiseState.PENDING &&
@@ -1313,7 +1355,7 @@ promise.Promise = goog.defineClass(null, {
1313
1355
  }
1314
1356
 
1315
1357
  return cb.promise;
1316
- },
1358
+ }
1317
1359
 
1318
1360
  /**
1319
1361
  * Invokes a callback function attached to this promise.
@@ -1324,15 +1366,15 @@ promise.Promise = goog.defineClass(null, {
1324
1366
  * @template R
1325
1367
  * @private
1326
1368
  */
1327
- invokeCallback_: function(callback, errback) {
1369
+ invokeCallback_(callback, errback) {
1328
1370
  var callbackFn = callback;
1329
1371
  if (this.state_ === PromiseState.REJECTED) {
1330
1372
  callbackFn = errback;
1331
1373
  }
1332
1374
 
1333
- if (goog.isFunction(callbackFn)) {
1334
- if (promise.isGenerator(callbackFn)) {
1335
- return promise.consume(callbackFn, null, this.value_);
1375
+ if (typeof callbackFn === 'function') {
1376
+ if (isGenerator(callbackFn)) {
1377
+ return consume(callbackFn, null, this.value_);
1336
1378
  }
1337
1379
  return callbackFn(this.value_);
1338
1380
  } else if (this.state_ === PromiseState.REJECTED) {
@@ -1341,34 +1383,34 @@ promise.Promise = goog.defineClass(null, {
1341
1383
  return this.value_;
1342
1384
  }
1343
1385
  }
1344
- });
1345
- promise.Thenable.addImplementation(promise.Promise);
1386
+ }
1387
+ Thenable.addImplementation(ManagedPromise);
1346
1388
 
1347
1389
 
1348
1390
  /**
1349
1391
  * Represents a value that will be resolved at some point in the future. This
1350
- * class represents the protected "producer" half of a Promise - each Deferred
1392
+ * class represents the protected "producer" half of a ManagedPromise - each Deferred
1351
1393
  * has a {@code promise} property that may be returned to consumers for
1352
1394
  * registering callbacks, reserving the ability to resolve the deferred to the
1353
1395
  * producer.
1354
1396
  *
1355
1397
  * If this Deferred is rejected and there are no listeners registered before
1356
1398
  * the next turn of the event loop, the rejection will be passed to the
1357
- * {@link webdriver.promise.ControlFlow} as an unhandled failure.
1399
+ * {@link ControlFlow} as an unhandled failure.
1358
1400
  *
1359
- * @implements {promise.Thenable<T>}
1401
+ * @implements {Thenable<T>}
1360
1402
  * @template T
1361
1403
  */
1362
- promise.Deferred = goog.defineClass(null, {
1404
+ class Deferred {
1363
1405
  /**
1364
- * @param {promise.ControlFlow=} opt_flow The control flow this instance was
1406
+ * @param {ControlFlow=} opt_flow The control flow this instance was
1365
1407
  * created under. This should only be provided during unit tests.
1366
1408
  */
1367
- constructor: function(opt_flow) {
1409
+ constructor(opt_flow) {
1368
1410
  var fulfill, reject;
1369
1411
 
1370
- /** @type {!promise.Promise<T>} */
1371
- this.promise = new promise.Promise(function(f, r) {
1412
+ /** @type {!ManagedPromise<T>} */
1413
+ this.promise = new ManagedPromise(function(f, r) {
1372
1414
  fulfill = f;
1373
1415
  reject = r;
1374
1416
  }, opt_flow);
@@ -1399,43 +1441,124 @@ promise.Deferred = goog.defineClass(null, {
1399
1441
  checkNotSelf(opt_reason);
1400
1442
  reject(opt_reason);
1401
1443
  };
1402
- },
1444
+ }
1403
1445
 
1404
1446
  /** @override */
1405
- isPending: function() {
1447
+ isPending() {
1406
1448
  return this.promise.isPending();
1407
- },
1449
+ }
1408
1450
 
1409
1451
  /** @override */
1410
- cancel: function(opt_reason) {
1452
+ cancel(opt_reason) {
1411
1453
  this.promise.cancel(opt_reason);
1412
- },
1454
+ }
1413
1455
 
1414
1456
  /**
1415
1457
  * @override
1416
1458
  * @deprecated Use {@code then} from the promise property directly.
1417
1459
  */
1418
- then: function(opt_cb, opt_eb) {
1460
+ then(opt_cb, opt_eb) {
1419
1461
  return this.promise.then(opt_cb, opt_eb);
1420
- },
1462
+ }
1463
+
1464
+ /**
1465
+ * @override
1466
+ * @deprecated Use {@lcode catch} from the promise property directly.
1467
+ */
1468
+ catch(opt_eb) {
1469
+ return this.promise.catch(opt_eb);
1470
+ }
1421
1471
 
1422
1472
  /**
1423
1473
  * @override
1424
1474
  * @deprecated Use {@code thenCatch} from the promise property directly.
1425
1475
  */
1426
- thenCatch: function(opt_eb) {
1476
+ thenCatch(opt_eb) {
1427
1477
  return this.promise.thenCatch(opt_eb);
1428
- },
1478
+ }
1429
1479
 
1430
1480
  /**
1431
1481
  * @override
1432
1482
  * @deprecated Use {@code thenFinally} from the promise property directly.
1433
1483
  */
1434
- thenFinally: function(opt_cb) {
1484
+ thenFinally(opt_cb) {
1435
1485
  return this.promise.thenFinally(opt_cb);
1436
1486
  }
1437
- });
1438
- promise.Thenable.addImplementation(promise.Deferred);
1487
+
1488
+ /**
1489
+ * @override
1490
+ * @deprecated Use {@code finally} from the promise property directly.
1491
+ */
1492
+ finally(opt_cb) {
1493
+ return this.promise.finally(opt_cb);
1494
+ }
1495
+ }
1496
+ Thenable.addImplementation(Deferred);
1497
+
1498
+
1499
+ /**
1500
+ * Registers a listener to invoke when a promise is resolved, regardless of
1501
+ * whether the promise's value was successfully computed. This function is
1502
+ * synonymous with the `finally` clause in a synchronous API:
1503
+ *
1504
+ * // Synchronous API:
1505
+ * try {
1506
+ * doSynchronousWork();
1507
+ * } finally {
1508
+ * cleanUp();
1509
+ * }
1510
+ *
1511
+ * // Asynchronous promise API:
1512
+ * promise.finally(doAsynchronousWork(), cleanUp);
1513
+ *
1514
+ * __Note:__ similar to the `finally` clause, if the registered callback returns
1515
+ * a rejected promise or throws an error, that error will silently replace the
1516
+ * rejection (if any) from the initial promise:
1517
+ *
1518
+ * try {
1519
+ * throw Error('one');
1520
+ * } finally {
1521
+ * throw Error('two'); // Hides Error: one
1522
+ * }
1523
+ *
1524
+ * let p = promise.rejected(Error('one'));
1525
+ * promise.finally(p, function() {
1526
+ * throw Error('two'); // Hides Error: one
1527
+ * });
1528
+ *
1529
+ * @param {PROMISE_TYPE} promise The thenable, promise-like object with which
1530
+ * to register the callback.
1531
+ * @param {function(): *} callback The function to call when the promise is
1532
+ * resolved.
1533
+ * @return {!PROMISE_TYPE} A new promise that is chained to the callback. This
1534
+ * promise will inherit the value of the original input if the callback
1535
+ * does not throw or return a rejected promise.
1536
+ * @template PROMISE_TYPE
1537
+ * @deprecated
1538
+ */
1539
+ function thenFinally(promise, callback) {
1540
+ if (!isPromise(promise)) {
1541
+ throw TypeError('first argument must be a promise-like object');
1542
+ }
1543
+
1544
+ if (typeof callback !== 'function') {
1545
+ throw TypeError('second argument must be a function');
1546
+ }
1547
+
1548
+ let error;
1549
+ let mustThrow = false;
1550
+ return promise
1551
+ .then(() => callback(), (e) => {
1552
+ error = e;
1553
+ mustThrow = true;
1554
+ return callback();
1555
+ })
1556
+ .then(() => {
1557
+ if (mustThrow) {
1558
+ throw error;
1559
+ }
1560
+ });
1561
+ }
1439
1562
 
1440
1563
 
1441
1564
  /**
@@ -1446,11 +1569,8 @@ promise.Thenable.addImplementation(promise.Deferred);
1446
1569
  */
1447
1570
  function isError(value) {
1448
1571
  return value instanceof Error ||
1449
- goog.isObject(value) &&
1450
- (goog.isString(value.message) ||
1451
- // A special test for goog.testing.JsUnitException.
1452
- value.isJsUnitException);
1453
-
1572
+ (!!value && typeof value === 'object'
1573
+ && typeof value.message === 'string');
1454
1574
  }
1455
1575
 
1456
1576
 
@@ -1458,97 +1578,101 @@ function isError(value) {
1458
1578
  * Determines whether a {@code value} should be treated as a promise.
1459
1579
  * Any object whose "then" property is a function will be considered a promise.
1460
1580
  *
1461
- * @param {*} value The value to test.
1581
+ * @param {?} value The value to test.
1462
1582
  * @return {boolean} Whether the value is a promise.
1463
1583
  */
1464
- promise.isPromise = function(value) {
1465
- return !!value && goog.isObject(value) &&
1466
- // Use array notation so the Closure compiler does not obfuscate away our
1467
- // contract. Use typeof rather than goog.isFunction because
1468
- // goog.isFunction accepts instanceof Function, which the promise spec
1469
- // does not.
1470
- typeof value['then'] === 'function';
1471
- };
1584
+ function isPromise(value) {
1585
+ try {
1586
+ // Use array notation so the Closure compiler does not obfuscate away our
1587
+ // contract.
1588
+ return value
1589
+ && (typeof value === 'object' || typeof value === 'function')
1590
+ && typeof value['then'] === 'function';
1591
+ } catch (ex) {
1592
+ return false;
1593
+ }
1594
+ }
1472
1595
 
1473
1596
 
1474
1597
  /**
1475
1598
  * Creates a promise that will be resolved at a set time in the future.
1476
1599
  * @param {number} ms The amount of time, in milliseconds, to wait before
1477
1600
  * resolving the promise.
1478
- * @return {!promise.Promise} The promise.
1601
+ * @return {!ManagedPromise} The promise.
1479
1602
  */
1480
- promise.delayed = function(ms) {
1603
+ function delayed(ms) {
1481
1604
  var key;
1482
- return new promise.Promise(function(fulfill) {
1605
+ return new ManagedPromise(function(fulfill) {
1483
1606
  key = setTimeout(function() {
1484
1607
  key = null;
1485
1608
  fulfill();
1486
1609
  }, ms);
1487
- }).thenCatch(function(e) {
1610
+ }).catch(function(e) {
1488
1611
  clearTimeout(key);
1489
1612
  key = null;
1490
1613
  throw e;
1491
1614
  });
1492
- };
1615
+ }
1493
1616
 
1494
1617
 
1495
1618
  /**
1496
1619
  * Creates a new deferred object.
1497
- * @return {!promise.Deferred<T>} The new deferred object.
1620
+ * @return {!Deferred<T>} The new deferred object.
1498
1621
  * @template T
1499
1622
  */
1500
- promise.defer = function() {
1501
- return new promise.Deferred();
1502
- };
1623
+ function defer() {
1624
+ return new Deferred();
1625
+ }
1503
1626
 
1504
1627
 
1505
1628
  /**
1506
1629
  * Creates a promise that has been resolved with the given value.
1507
1630
  * @param {T=} opt_value The resolved value.
1508
- * @return {!promise.Promise<T>} The resolved promise.
1631
+ * @return {!ManagedPromise<T>} The resolved promise.
1509
1632
  * @template T
1510
1633
  */
1511
- promise.fulfilled = function(opt_value) {
1512
- if (opt_value instanceof promise.Promise) {
1634
+ function fulfilled(opt_value) {
1635
+ if (opt_value instanceof ManagedPromise) {
1513
1636
  return opt_value;
1514
1637
  }
1515
- return new promise.Promise(function(fulfill) {
1638
+ return new ManagedPromise(function(fulfill) {
1516
1639
  fulfill(opt_value);
1517
1640
  });
1518
- };
1641
+ }
1519
1642
 
1520
1643
 
1521
1644
  /**
1522
1645
  * Creates a promise that has been rejected with the given reason.
1523
1646
  * @param {*=} opt_reason The rejection reason; may be any value, but is
1524
1647
  * usually an Error or a string.
1525
- * @return {!promise.Promise<T>} The rejected promise.
1648
+ * @return {!ManagedPromise<T>} The rejected promise.
1526
1649
  * @template T
1527
1650
  */
1528
- promise.rejected = function(opt_reason) {
1529
- if (opt_reason instanceof promise.Promise) {
1651
+ function rejected(opt_reason) {
1652
+ if (opt_reason instanceof ManagedPromise) {
1530
1653
  return opt_reason;
1531
1654
  }
1532
- return new promise.Promise(function(_, reject) {
1655
+ return new ManagedPromise(function(_, reject) {
1533
1656
  reject(opt_reason);
1534
1657
  });
1535
- };
1658
+ }
1536
1659
 
1537
1660
 
1538
1661
  /**
1539
1662
  * Wraps a function that expects a node-style callback as its final
1540
1663
  * argument. This callback expects two arguments: an error value (which will be
1541
1664
  * null if the call succeeded), and the success value as the second argument.
1542
- * The callback will the resolve or reject the returned promise, based on its arguments.
1665
+ * The callback will the resolve or reject the returned promise, based on its
1666
+ * arguments.
1543
1667
  * @param {!Function} fn The function to wrap.
1544
1668
  * @param {...?} var_args The arguments to apply to the function, excluding the
1545
1669
  * final callback.
1546
- * @return {!promise.Promise} A promise that will be resolved with the
1670
+ * @return {!ManagedPromise} A promise that will be resolved with the
1547
1671
  * result of the provided function's callback.
1548
1672
  */
1549
- promise.checkedNodeCall = function(fn, var_args) {
1550
- var args = Arrays.slice(arguments, 1);
1551
- return new promise.Promise(function(fulfill, reject) {
1673
+ function checkedNodeCall(fn, var_args) {
1674
+ let args = Array.prototype.slice.call(arguments, 1);
1675
+ return new ManagedPromise(function(fulfill, reject) {
1552
1676
  try {
1553
1677
  args.push(function(error, value) {
1554
1678
  error ? reject(error) : fulfill(value);
@@ -1558,7 +1682,7 @@ promise.checkedNodeCall = function(fn, var_args) {
1558
1682
  reject(ex);
1559
1683
  }
1560
1684
  });
1561
- };
1685
+ }
1562
1686
 
1563
1687
 
1564
1688
  /**
@@ -1570,43 +1694,37 @@ promise.checkedNodeCall = function(fn, var_args) {
1570
1694
  * resolved successfully.
1571
1695
  * @param {Function=} opt_errback The function to call when the value is
1572
1696
  * rejected.
1573
- * @return {!promise.Promise} A new promise.
1697
+ * @return {!ManagedPromise} A new promise.
1574
1698
  */
1575
- promise.when = function(value, opt_callback, opt_errback) {
1576
- if (promise.Thenable.isImplementation(value)) {
1699
+ function when(value, opt_callback, opt_errback) {
1700
+ if (Thenable.isImplementation(value)) {
1577
1701
  return value.then(opt_callback, opt_errback);
1578
1702
  }
1579
1703
 
1580
- return new promise.Promise(function(fulfill, reject) {
1581
- promise.asap(value, fulfill, reject);
1704
+ return new ManagedPromise(function(fulfill) {
1705
+ fulfill(value);
1582
1706
  }).then(opt_callback, opt_errback);
1583
- };
1707
+ }
1584
1708
 
1585
1709
 
1586
1710
  /**
1587
- * Invokes the appropriate callback function as soon as a promised
1588
- * {@code value} is resolved. This function is similar to
1589
- * {@link webdriver.promise.when}, except it does not return a new promise.
1711
+ * Invokes the appropriate callback function as soon as a promised `value` is
1712
+ * resolved. This function is similar to `when()`, except it does not return
1713
+ * a new promise.
1590
1714
  * @param {*} value The value to observe.
1591
1715
  * @param {Function} callback The function to call when the value is
1592
1716
  * resolved successfully.
1593
1717
  * @param {Function=} opt_errback The function to call when the value is
1594
1718
  * rejected.
1595
1719
  */
1596
- promise.asap = function(value, callback, opt_errback) {
1597
- if (promise.isPromise(value)) {
1720
+ function asap(value, callback, opt_errback) {
1721
+ if (isPromise(value)) {
1598
1722
  value.then(callback, opt_errback);
1599
1723
 
1600
- // Maybe a Dojo-like deferred object?
1601
- } else if (!!value && goog.isObject(value) &&
1602
- goog.isFunction(value.addCallbacks)) {
1603
- value.addCallbacks(callback, opt_errback);
1604
-
1605
- // A raw value, return a resolved promise.
1606
1724
  } else if (callback) {
1607
1725
  callback(value);
1608
1726
  }
1609
- };
1727
+ }
1610
1728
 
1611
1729
 
1612
1730
  /**
@@ -1615,16 +1733,16 @@ promise.asap = function(value, callback, opt_errback) {
1615
1733
  * input array's promises are rejected, the returned promise will be rejected
1616
1734
  * with the same reason.
1617
1735
  *
1618
- * @param {!Array<(T|!promise.Promise<T>)>} arr An array of
1736
+ * @param {!Array<(T|!ManagedPromise<T>)>} arr An array of
1619
1737
  * promises to wait on.
1620
- * @return {!promise.Promise<!Array<T>>} A promise that is
1738
+ * @return {!ManagedPromise<!Array<T>>} A promise that is
1621
1739
  * fulfilled with an array containing the fulfilled values of the
1622
1740
  * input array, or rejected with the same reason as the first
1623
1741
  * rejected value.
1624
1742
  * @template T
1625
1743
  */
1626
- promise.all = function(arr) {
1627
- return new promise.Promise(function(fulfill, reject) {
1744
+ function all(arr) {
1745
+ return new ManagedPromise(function(fulfill, reject) {
1628
1746
  var n = arr.length;
1629
1747
  var values = [];
1630
1748
 
@@ -1642,11 +1760,17 @@ promise.all = function(arr) {
1642
1760
  }
1643
1761
  };
1644
1762
 
1763
+ function processPromise(index) {
1764
+ asap(arr[index], function(value) {
1765
+ onFulfilled(index, value);
1766
+ }, reject);
1767
+ }
1768
+
1645
1769
  for (var i = 0; i < n; ++i) {
1646
- promise.asap(arr[i], goog.partial(onFulfilled, i), reject);
1770
+ processPromise(i);
1647
1771
  }
1648
1772
  });
1649
- };
1773
+ }
1650
1774
 
1651
1775
 
1652
1776
  /**
@@ -1662,7 +1786,7 @@ promise.all = function(arr) {
1662
1786
  * Only the first failure will be reported; all subsequent errors will be
1663
1787
  * silently ignored.
1664
1788
  *
1665
- * @param {!(Array<TYPE>|promise.Promise<!Array<TYPE>>)} arr The
1789
+ * @param {!(Array<TYPE>|ManagedPromise<!Array<TYPE>>)} arr The
1666
1790
  * array to iterator over, or a promise that will resolve to said array.
1667
1791
  * @param {function(this: SELF, TYPE, number, !Array<TYPE>): ?} fn The
1668
1792
  * function to call for each element in the array. This function should
@@ -1671,11 +1795,13 @@ promise.all = function(arr) {
1671
1795
  * {@code fn}.
1672
1796
  * @template TYPE, SELF
1673
1797
  */
1674
- promise.map = function(arr, fn, opt_self) {
1675
- return promise.fulfilled(arr).then(function(v) {
1676
- goog.asserts.assertNumber(v.length, 'not an array like value');
1798
+ function map(arr, fn, opt_self) {
1799
+ return fulfilled(arr).then(function(v) {
1800
+ if (!Array.isArray(v)) {
1801
+ throw TypeError('not an array');
1802
+ }
1677
1803
  var arr = /** @type {!Array} */(v);
1678
- return new promise.Promise(function(fulfill, reject) {
1804
+ return new ManagedPromise(function(fulfill, reject) {
1679
1805
  var n = arr.length;
1680
1806
  var values = new Array(n);
1681
1807
  (function processNext(i) {
@@ -1689,7 +1815,7 @@ promise.map = function(arr, fn, opt_self) {
1689
1815
  return;
1690
1816
  }
1691
1817
  try {
1692
- promise.asap(
1818
+ asap(
1693
1819
  fn.call(opt_self, arr[i], i, /** @type {!Array} */(arr)),
1694
1820
  function(value) {
1695
1821
  values[i] = value;
@@ -1702,7 +1828,7 @@ promise.map = function(arr, fn, opt_self) {
1702
1828
  })(0);
1703
1829
  });
1704
1830
  });
1705
- };
1831
+ }
1706
1832
 
1707
1833
 
1708
1834
  /**
@@ -1718,20 +1844,22 @@ promise.map = function(arr, fn, opt_self) {
1718
1844
  * first failure will be reported; all subsequent errors will be silently
1719
1845
  * ignored.
1720
1846
  *
1721
- * @param {!(Array<TYPE>|promise.Promise<!Array<TYPE>>)} arr The
1847
+ * @param {!(Array<TYPE>|ManagedPromise<!Array<TYPE>>)} arr The
1722
1848
  * array to iterator over, or a promise that will resolve to said array.
1723
1849
  * @param {function(this: SELF, TYPE, number, !Array<TYPE>): (
1724
- * boolean|promise.Promise<boolean>)} fn The function
1850
+ * boolean|ManagedPromise<boolean>)} fn The function
1725
1851
  * to call for each element in the array.
1726
1852
  * @param {SELF=} opt_self The object to be used as the value of 'this' within
1727
1853
  * {@code fn}.
1728
1854
  * @template TYPE, SELF
1729
1855
  */
1730
- promise.filter = function(arr, fn, opt_self) {
1731
- return promise.fulfilled(arr).then(function(v) {
1732
- goog.asserts.assertNumber(v.length, 'not an array like value');
1856
+ function filter(arr, fn, opt_self) {
1857
+ return fulfilled(arr).then(function(v) {
1858
+ if (!Array.isArray(v)) {
1859
+ throw TypeError('not an array');
1860
+ }
1733
1861
  var arr = /** @type {!Array} */(v);
1734
- return new promise.Promise(function(fulfill, reject) {
1862
+ return new ManagedPromise(function(fulfill, reject) {
1735
1863
  var n = arr.length;
1736
1864
  var values = [];
1737
1865
  var valuesLength = 0;
@@ -1748,7 +1876,7 @@ promise.filter = function(arr, fn, opt_self) {
1748
1876
  try {
1749
1877
  var value = arr[i];
1750
1878
  var include = fn.call(opt_self, value, i, /** @type {!Array} */(arr));
1751
- promise.asap(include, function(include) {
1879
+ asap(include, function(include) {
1752
1880
  if (include) {
1753
1881
  values[valuesLength++] = value;
1754
1882
  }
@@ -1760,7 +1888,7 @@ promise.filter = function(arr, fn, opt_self) {
1760
1888
  })(0);
1761
1889
  });
1762
1890
  });
1763
- };
1891
+ }
1764
1892
 
1765
1893
 
1766
1894
  /**
@@ -1779,90 +1907,91 @@ promise.filter = function(arr, fn, opt_self) {
1779
1907
  * promise.fullyResolved(value); // Stack overflow.
1780
1908
  *
1781
1909
  * @param {*} value The value to fully resolve.
1782
- * @return {!promise.Promise} A promise for a fully resolved version
1910
+ * @return {!ManagedPromise} A promise for a fully resolved version
1783
1911
  * of the input value.
1784
1912
  */
1785
- promise.fullyResolved = function(value) {
1786
- if (promise.isPromise(value)) {
1787
- return promise.when(value, fullyResolveValue);
1913
+ function fullyResolved(value) {
1914
+ if (isPromise(value)) {
1915
+ return when(value, fullyResolveValue);
1788
1916
  }
1789
1917
  return fullyResolveValue(value);
1790
- };
1918
+ }
1791
1919
 
1792
1920
 
1793
1921
  /**
1794
1922
  * @param {*} value The value to fully resolve. If a promise, assumed to
1795
1923
  * already be resolved.
1796
- * @return {!promise.Promise} A promise for a fully resolved version
1924
+ * @return {!ManagedPromise} A promise for a fully resolved version
1797
1925
  * of the input value.
1798
1926
  */
1799
- function fullyResolveValue(value) {
1800
- switch (goog.typeOf(value)) {
1801
- case 'array':
1802
- return fullyResolveKeys(/** @type {!Array} */ (value));
1803
-
1804
- case 'object':
1805
- if (promise.isPromise(value)) {
1806
- // We get here when the original input value is a promise that
1807
- // resolves to itself. When the user provides us with such a promise,
1808
- // trust that it counts as a "fully resolved" value and return it.
1809
- // Of course, since it's already a promise, we can just return it
1810
- // to the user instead of wrapping it in another promise.
1811
- return /** @type {!promise.Promise} */ (value);
1812
- }
1927
+ function fullyResolveValue(value) {
1928
+ if (Array.isArray(value)) {
1929
+ return fullyResolveKeys(/** @type {!Array} */ (value));
1930
+ }
1813
1931
 
1814
- if (goog.isNumber(value.nodeType) &&
1815
- goog.isObject(value.ownerDocument) &&
1816
- goog.isNumber(value.ownerDocument.nodeType)) {
1817
- // DOM node; return early to avoid infinite recursion. Should we
1818
- // only support objects with a certain level of nesting?
1819
- return promise.fulfilled(value);
1820
- }
1932
+ if (isPromise(value)) {
1933
+ if (isPromise(value)) {
1934
+ // We get here when the original input value is a promise that
1935
+ // resolves to itself. When the user provides us with such a promise,
1936
+ // trust that it counts as a "fully resolved" value and return it.
1937
+ // Of course, since it's already a promise, we can just return it
1938
+ // to the user instead of wrapping it in another promise.
1939
+ return /** @type {!ManagedPromise} */ (value);
1940
+ }
1941
+ }
1821
1942
 
1822
- return fullyResolveKeys(/** @type {!Object} */ (value));
1943
+ if (value && typeof value === 'object') {
1944
+ return fullyResolveKeys(/** @type {!Object} */ (value));
1945
+ }
1823
1946
 
1824
- default: // boolean, function, null, number, string, undefined
1825
- return promise.fulfilled(value);
1947
+ if (typeof value === 'function') {
1948
+ return fullyResolveKeys(/** @type {!Object} */ (value));
1826
1949
  }
1950
+
1951
+ return fulfilled(value);
1827
1952
  }
1828
1953
 
1829
1954
 
1830
1955
  /**
1831
1956
  * @param {!(Array|Object)} obj the object to resolve.
1832
- * @return {!promise.Promise} A promise that will be resolved with the
1957
+ * @return {!ManagedPromise} A promise that will be resolved with the
1833
1958
  * input object once all of its values have been fully resolved.
1834
1959
  */
1835
- function fullyResolveKeys(obj) {
1836
- var isArray = goog.isArray(obj);
1837
- var numKeys = isArray ? obj.length : Objects.getCount(obj);
1960
+ function fullyResolveKeys(obj) {
1961
+ var isArray = Array.isArray(obj);
1962
+ var numKeys = isArray ? obj.length : (function() {
1963
+ let n = 0;
1964
+ for (let key in obj) {
1965
+ n += 1;
1966
+ }
1967
+ return n;
1968
+ })();
1838
1969
  if (!numKeys) {
1839
- return promise.fulfilled(obj);
1970
+ return fulfilled(obj);
1971
+ }
1972
+
1973
+ function forEachProperty(obj, fn) {
1974
+ for (let key in obj) {
1975
+ fn.call(null, obj[key], key, obj);
1976
+ }
1977
+ }
1978
+
1979
+ function forEachElement(arr, fn) {
1980
+ arr.forEach(fn);
1840
1981
  }
1841
1982
 
1842
1983
  var numResolved = 0;
1843
- return new promise.Promise(function(fulfill, reject) {
1844
- // In pre-IE9, goog.array.forEach will not iterate properly over arrays
1845
- // containing undefined values because "index in array" returns false
1846
- // when array[index] === undefined (even for x = [undefined, 1]). To get
1847
- // around this, we need to use our own forEach implementation.
1848
- // DO NOT REMOVE THIS UNTIL WE NO LONGER SUPPORT IE8. This cannot be
1849
- // reproduced in IE9 by changing the browser/document modes, it requires an
1850
- // actual pre-IE9 browser. Yay, IE!
1851
- var forEachKey = !isArray ? Objects.forEach : function(arr, fn) {
1852
- var n = arr.length;
1853
- for (var i = 0; i < n; ++i) {
1854
- fn.call(null, arr[i], i, arr);
1855
- }
1856
- };
1984
+ return new ManagedPromise(function(fulfill, reject) {
1985
+ var forEachKey = isArray ? forEachElement: forEachProperty;
1857
1986
 
1858
1987
  forEachKey(obj, function(partialValue, key) {
1859
- var type = goog.typeOf(partialValue);
1860
- if (type != 'array' && type != 'object') {
1988
+ if (!Array.isArray(partialValue)
1989
+ && (!partialValue || typeof partialValue !== 'object')) {
1861
1990
  maybeResolveValue();
1862
1991
  return;
1863
1992
  }
1864
1993
 
1865
- promise.fullyResolved(partialValue).then(
1994
+ fullyResolved(partialValue).then(
1866
1995
  function(resolvedValue) {
1867
1996
  obj[key] = resolvedValue;
1868
1997
  maybeResolveValue();
@@ -1881,7 +2010,7 @@ promise.fullyResolved = function(value) {
1881
2010
 
1882
2011
  //////////////////////////////////////////////////////////////////////////////
1883
2012
  //
1884
- // promise.ControlFlow
2013
+ // ControlFlow
1885
2014
  //
1886
2015
  //////////////////////////////////////////////////////////////////////////////
1887
2016
 
@@ -1893,37 +2022,33 @@ promise.fullyResolved = function(value) {
1893
2022
  * the ordered scheduled, starting each task only once those before it have
1894
2023
  * completed.
1895
2024
  *
1896
- * Each task scheduled within this flow may return a
1897
- * {@link webdriver.promise.Promise} to indicate it is an asynchronous
1898
- * operation. The ControlFlow will wait for such promises to be resolved before
1899
- * marking the task as completed.
2025
+ * Each task scheduled within this flow may return a {@link ManagedPromise} to
2026
+ * indicate it is an asynchronous operation. The ControlFlow will wait for such
2027
+ * promises to be resolved before marking the task as completed.
1900
2028
  *
1901
- * Tasks and each callback registered on a {@link webdriver.promise.Promise}
1902
- * will be run in their own ControlFlow frame. Any tasks scheduled within a
1903
- * frame will take priority over previously scheduled tasks. Furthermore, if any
1904
- * of the tasks in the frame fail, the remainder of the tasks in that frame will
1905
- * be discarded and the failure will be propagated to the user through the
1906
- * callback/task's promised result.
2029
+ * Tasks and each callback registered on a {@link ManagedPromise} will be run
2030
+ * in their own ControlFlow frame. Any tasks scheduled within a frame will take
2031
+ * priority over previously scheduled tasks. Furthermore, if any of the tasks in
2032
+ * the frame fail, the remainder of the tasks in that frame will be discarded
2033
+ * and the failure will be propagated to the user through the callback/task's
2034
+ * promised result.
1907
2035
  *
1908
2036
  * Each time a ControlFlow empties its task queue, it will fire an
1909
- * {@link webdriver.promise.ControlFlow.EventType.IDLE IDLE} event. Conversely,
2037
+ * {@link ControlFlow.EventType.IDLE IDLE} event. Conversely,
1910
2038
  * whenever the flow terminates due to an unhandled error, it will remove all
1911
2039
  * remaining tasks in its queue and fire an
1912
- * {@link webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION
1913
- * UNCAUGHT_EXCEPTION} event. If there are no listeners registered with the
1914
- * flow, the error will be rethrown to the global error handler.
2040
+ * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION UNCAUGHT_EXCEPTION} event.
2041
+ * If there are no listeners registered with the flow, the error will be
2042
+ * rethrown to the global error handler.
1915
2043
  *
1916
- * Refer to the {@link webdriver.promise} module documentation for a detailed
2044
+ * Refer to the {@link ./promise} module documentation fora detailed
1917
2045
  * explanation of how the ControlFlow coordinates task execution.
1918
2046
  *
1919
2047
  * @final
1920
2048
  */
1921
- promise.ControlFlow = goog.defineClass(EventEmitter, {
1922
- // TODO: remove this empty comment when the compiler properly handles
1923
- // goog.defineClass with a missing constructor comment.
1924
- /** @constructor */
1925
- constructor: function() {
1926
- promise.ControlFlow.base(this, 'constructor');
2049
+ class ControlFlow extends events.EventEmitter {
2050
+ constructor() {
2051
+ super();
1927
2052
 
1928
2053
  /** @private {boolean} */
1929
2054
  this.propagateUnhandledRejections_ = true;
@@ -1937,7 +2062,7 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
1937
2062
  /**
1938
2063
  * Micro task that controls shutting down the control flow. Upon shut down,
1939
2064
  * the flow will emit an
1940
- * {@link webdriver.promise.ControlFlow.EventType.IDLE} event. Idle events
2065
+ * {@link ControlFlow.EventType.IDLE} event. Idle events
1941
2066
  * always follow a brief timeout in order to catch latent errors from the
1942
2067
  * last completed task. If this task had a callback registered, but no
1943
2068
  * errback, and the task fails, the unhandled failure would not be reported
@@ -1948,7 +2073,7 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
1948
2073
  * function() { return promise.rejected('failed'); });
1949
2074
  * // Set a callback on the result. This delays reporting the unhandled
1950
2075
  * // failure for 1 turn of the event loop.
1951
- * result.then(goog.nullFunction);
2076
+ * result.then(function() {});
1952
2077
  *
1953
2078
  * @private {MicroTask}
1954
2079
  */
@@ -1961,28 +2086,27 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
1961
2086
  * _actually_ something to run. When a control flow is waiting on a task,
1962
2087
  * there will be nothing in the JS event loop and the process would
1963
2088
  * terminate without this.
1964
- *
1965
- * @private {?number}
2089
+ * @private
1966
2090
  */
1967
2091
  this.hold_ = null;
1968
- },
2092
+ }
1969
2093
 
1970
2094
  /**
1971
2095
  * Returns a string representation of this control flow, which is its current
1972
- * {@link #getSchedule() schedule}, sans task stack traces.
2096
+ * {@linkplain #getSchedule() schedule}, sans task stack traces.
1973
2097
  * @return {string} The string representation of this contorl flow.
1974
2098
  * @override
1975
2099
  */
1976
- toString: function() {
2100
+ toString() {
1977
2101
  return this.getSchedule();
1978
- },
2102
+ }
1979
2103
 
1980
2104
  /**
1981
2105
  * Sets whether any unhandled rejections should propagate up through the
1982
2106
  * control flow stack and cause rejections within parent tasks. If error
1983
2107
  * propagation is disabled, tasks will not be aborted when an unhandled
1984
2108
  * promise rejection is detected, but the rejection _will_ trigger an
1985
- * {@link webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION}
2109
+ * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION}
1986
2110
  * event.
1987
2111
  *
1988
2112
  * The default behavior is to propagate all unhandled rejections. _The use
@@ -1990,26 +2114,26 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
1990
2114
  *
1991
2115
  * @param {boolean} propagate whether to propagate errors.
1992
2116
  */
1993
- setPropagateUnhandledRejections: function(propagate) {
2117
+ setPropagateUnhandledRejections(propagate) {
1994
2118
  this.propagateUnhandledRejections_ = propagate;
1995
- },
2119
+ }
1996
2120
 
1997
2121
  /**
1998
2122
  * @return {boolean} Whether this flow is currently idle.
1999
2123
  */
2000
- isIdle: function() {
2124
+ isIdle() {
2001
2125
  return !this.shutdownTask_ && (!this.taskQueues_ || !this.taskQueues_.size);
2002
- },
2126
+ }
2003
2127
 
2004
2128
  /**
2005
2129
  * Resets this instance, clearing its queue and removing all event listeners.
2006
2130
  */
2007
- reset: function() {
2131
+ reset() {
2008
2132
  this.cancelQueues_(new FlowResetError);
2009
- this.emit(promise.ControlFlow.EventType.RESET);
2133
+ this.emit(ControlFlow.EventType.RESET);
2010
2134
  this.removeAllListeners();
2011
2135
  this.cancelShutdown_();
2012
- },
2136
+ }
2013
2137
 
2014
2138
  /**
2015
2139
  * Generates an annotated string describing the internal state of this control
@@ -2020,8 +2144,8 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2020
2144
  * from when each task was scheduled. Defaults to false.
2021
2145
  * @return {string} String representation of this flow's internal state.
2022
2146
  */
2023
- getSchedule: function(opt_includeStackTraces) {
2024
- var ret = 'ControlFlow::' + goog.getUid(this);
2147
+ getSchedule(opt_includeStackTraces) {
2148
+ var ret = 'ControlFlow::' + getUid(this);
2025
2149
  var activeQueue = this.activeQueue_;
2026
2150
  if (!this.taskQueues_ || !this.taskQueues_.size) {
2027
2151
  return ret;
@@ -2066,7 +2190,7 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2066
2190
  }
2067
2191
  return ret;
2068
2192
  }
2069
- },
2193
+ }
2070
2194
 
2071
2195
  /**
2072
2196
  * Returns the currently actively task queue for this flow. If there is no
@@ -2074,7 +2198,7 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2074
2198
  * @return {!TaskQueue} the currently active task queue for this flow.
2075
2199
  * @private
2076
2200
  */
2077
- getActiveQueue_: function() {
2201
+ getActiveQueue_() {
2078
2202
  if (this.activeQueue_) {
2079
2203
  return this.activeQueue_;
2080
2204
  }
@@ -2088,45 +2212,46 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2088
2212
  .once('end', this.onQueueEnd_, this)
2089
2213
  .once('error', this.onQueueError_, this);
2090
2214
 
2091
- asyncRun(() => this.activeQueue_ = null, this);
2215
+ asyncRun(() => this.activeQueue_ = null);
2092
2216
  this.activeQueue_.start();
2093
2217
  return this.activeQueue_;
2094
- },
2218
+ }
2095
2219
 
2096
2220
  /**
2097
2221
  * Schedules a task for execution. If there is nothing currently in the
2098
2222
  * queue, the task will be executed in the next turn of the event loop. If
2099
2223
  * the task function is a generator, the task will be executed using
2100
- * {@link webdriver.promise.consume}.
2224
+ * {@link ./promise.consume consume()}.
2101
2225
  *
2102
- * @param {function(): (T|promise.Promise<T>)} fn The function to
2226
+ * @param {function(): (T|ManagedPromise<T>)} fn The function to
2103
2227
  * call to start the task. If the function returns a
2104
- * {@link webdriver.promise.Promise}, this instance will wait for it to be
2228
+ * {@link ManagedPromise}, this instance will wait for it to be
2105
2229
  * resolved before starting the next task.
2106
2230
  * @param {string=} opt_description A description of the task.
2107
- * @return {!promise.Promise<T>} A promise that will be resolved
2231
+ * @return {!ManagedPromise<T>} A promise that will be resolved
2108
2232
  * with the result of the action.
2109
2233
  * @template T
2110
2234
  */
2111
- execute: function(fn, opt_description) {
2112
- if (promise.isGenerator(fn)) {
2113
- fn = goog.partial(promise.consume, fn);
2235
+ execute(fn, opt_description) {
2236
+ if (isGenerator(fn)) {
2237
+ let original = fn;
2238
+ fn = () => consume(original);
2114
2239
  }
2115
2240
 
2116
2241
  if (!this.hold_) {
2117
2242
  var holdIntervalMs = 2147483647; // 2^31-1; max timer length for Node.js
2118
- this.hold_ = setInterval(goog.nullFunction, holdIntervalMs);
2243
+ this.hold_ = setInterval(function() {}, holdIntervalMs);
2119
2244
  }
2120
2245
 
2121
2246
  var task = new Task(
2122
2247
  this, fn, opt_description || '<anonymous>',
2123
- {name: 'Task', top: promise.ControlFlow.prototype.execute});
2248
+ {name: 'Task', top: ControlFlow.prototype.execute});
2124
2249
 
2125
2250
  var q = this.getActiveQueue_();
2126
2251
  q.enqueue(task);
2127
- this.emit(promise.ControlFlow.EventType.SCHEDULE_TASK, task.description);
2252
+ this.emit(ControlFlow.EventType.SCHEDULE_TASK, task.description);
2128
2253
  return task.promise;
2129
- },
2254
+ }
2130
2255
 
2131
2256
  /**
2132
2257
  * Inserts a {@code setTimeout} into the command queue. This is equivalent to
@@ -2134,14 +2259,14 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2134
2259
  *
2135
2260
  * @param {number} ms The timeout delay, in milliseconds.
2136
2261
  * @param {string=} opt_description A description to accompany the timeout.
2137
- * @return {!promise.Promise} A promise that will be resolved with
2262
+ * @return {!ManagedPromise} A promise that will be resolved with
2138
2263
  * the result of the action.
2139
2264
  */
2140
- timeout: function(ms, opt_description) {
2265
+ timeout(ms, opt_description) {
2141
2266
  return this.execute(function() {
2142
- return promise.delayed(ms);
2267
+ return delayed(ms);
2143
2268
  }, opt_description);
2144
- },
2269
+ }
2145
2270
 
2146
2271
  /**
2147
2272
  * Schedules a task that shall wait for a condition to hold. Each condition
@@ -2151,7 +2276,7 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2151
2276
  * Condition functions may schedule sub-tasks with this instance, however,
2152
2277
  * their execution time will be factored into whether a wait has timed out.
2153
2278
  *
2154
- * In the event a condition returns a Promise, the polling loop will wait for
2279
+ * In the event a condition returns a ManagedPromise, the polling loop will wait for
2155
2280
  * it to be resolved before evaluating whether the condition has been
2156
2281
  * satisfied. The resolution time for a promise is factored into whether a
2157
2282
  * wait has timed out.
@@ -2166,38 +2291,38 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2166
2291
  * If this function is invoked with `timeout === 0`, or the timeout is
2167
2292
  * omitted, the flow will wait indefinitely for the condition to be satisfied.
2168
2293
  *
2169
- * @param {(!promise.Promise<T>|function())} condition The condition to poll,
2294
+ * @param {(!ManagedPromise<T>|function())} condition The condition to poll,
2170
2295
  * or a promise to wait on.
2171
2296
  * @param {number=} opt_timeout How long to wait, in milliseconds, for the
2172
2297
  * condition to hold before timing out. If omitted, the flow will wait
2173
2298
  * indefinitely.
2174
2299
  * @param {string=} opt_message An optional error message to include if the
2175
2300
  * wait times out; defaults to the empty string.
2176
- * @return {!promise.Promise<T>} A promise that will be fulfilled
2301
+ * @return {!ManagedPromise<T>} A promise that will be fulfilled
2177
2302
  * when the condition has been satisified. The promise shall be rejected
2178
2303
  * if the wait times out waiting for the condition.
2179
2304
  * @throws {TypeError} If condition is not a function or promise or if timeout
2180
2305
  * is not a number >= 0.
2181
2306
  * @template T
2182
2307
  */
2183
- wait: function(condition, opt_timeout, opt_message) {
2308
+ wait(condition, opt_timeout, opt_message) {
2184
2309
  var timeout = opt_timeout || 0;
2185
- if (!goog.isNumber(timeout) || timeout < 0) {
2310
+ if (typeof timeout !== 'number' || timeout < 0) {
2186
2311
  throw TypeError('timeout must be a number >= 0: ' + timeout);
2187
2312
  }
2188
2313
 
2189
- if (promise.isPromise(condition)) {
2314
+ if (isPromise(condition)) {
2190
2315
  return this.execute(function() {
2191
2316
  if (!timeout) {
2192
2317
  return condition;
2193
2318
  }
2194
- return new promise.Promise(function(fulfill, reject) {
2195
- var start = goog.now();
2319
+ return new ManagedPromise(function(fulfill, reject) {
2320
+ var start = Date.now();
2196
2321
  var timer = setTimeout(function() {
2197
2322
  timer = null;
2198
2323
  reject(Error((opt_message ? opt_message + '\n' : '') +
2199
2324
  'Timed out waiting for promise to resolve after ' +
2200
- (goog.now() - start) + 'ms'));
2325
+ (Date.now() - start) + 'ms'));
2201
2326
  }, timeout);
2202
2327
 
2203
2328
  /** @type {Thenable} */(condition).then(
@@ -2213,25 +2338,26 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2213
2338
  }, opt_message || '<anonymous wait: promise resolution>');
2214
2339
  }
2215
2340
 
2216
- if (!goog.isFunction(condition)) {
2341
+ if (typeof condition !== 'function') {
2217
2342
  throw TypeError('Invalid condition; must be a function or promise: ' +
2218
- goog.typeOf(condition));
2343
+ typeof condition);
2219
2344
  }
2220
2345
 
2221
- if (promise.isGenerator(condition)) {
2222
- condition = goog.partial(promise.consume, condition);
2346
+ if (isGenerator(condition)) {
2347
+ let original = condition;
2348
+ condition = () => consume(original);
2223
2349
  }
2224
2350
 
2225
2351
  var self = this;
2226
2352
  return this.execute(function() {
2227
- var startTime = goog.now();
2228
- return new promise.Promise(function(fulfill, reject) {
2353
+ var startTime = Date.now();
2354
+ return new ManagedPromise(function(fulfill, reject) {
2229
2355
  pollCondition();
2230
2356
 
2231
2357
  function pollCondition() {
2232
2358
  var conditionFn = /** @type {function()} */(condition);
2233
2359
  self.execute(conditionFn).then(function(value) {
2234
- var elapsed = goog.now() - startTime;
2360
+ var elapsed = Date.now() - startTime;
2235
2361
  if (!!value) {
2236
2362
  fulfill(value);
2237
2363
  } else if (timeout && elapsed >= timeout) {
@@ -2247,7 +2373,7 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2247
2373
  }
2248
2374
  });
2249
2375
  }, opt_message || '<anonymous wait>');
2250
- },
2376
+ }
2251
2377
 
2252
2378
  /**
2253
2379
  * Executes a function in the next available turn of the JavaScript event
@@ -2285,36 +2411,36 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2285
2411
  * @param {Object=} opt_self The object in whose context to run the function.
2286
2412
  * @param {...*} var_args Any arguments to pass to the function.
2287
2413
  */
2288
- async: function(fn, opt_self, var_args) {
2289
- asyncRun(function() {
2414
+ async(fn, opt_self, var_args) {
2415
+ asyncRun(() => {
2290
2416
  // Clear any lingering queues, forces getActiveQueue_ to create a new one.
2291
2417
  this.activeQueue_ = null;
2292
2418
  var q = this.getActiveQueue_();
2293
2419
  try {
2294
2420
  q.execute_(fn.bind(opt_self, var_args));
2295
2421
  } catch (ex) {
2296
- var cancellationError = promise.CancellationError.wrap(ex,
2422
+ var cancellationError = CancellationError.wrap(ex,
2297
2423
  'Function passed to ControlFlow.async() threw');
2298
2424
  cancellationError.silent_ = true;
2299
2425
  q.abort_(cancellationError);
2300
2426
  } finally {
2301
2427
  this.activeQueue_ = null;
2302
2428
  }
2303
- }, this);
2304
- },
2429
+ });
2430
+ }
2305
2431
 
2306
2432
  /**
2307
2433
  * Event handler for when a task queue is exhausted. This starts the shutdown
2308
2434
  * sequence for this instance if there are no remaining task queues: after
2309
2435
  * one turn of the event loop, this object will emit the
2310
- * {@link webdriver.promise.ControlFlow.EventType.IDLE IDLE} event to signal
2436
+ * {@link ControlFlow.EventType.IDLE IDLE} event to signal
2311
2437
  * listeners that it has completed. During this wait, if another task is
2312
2438
  * scheduled, the shutdown will be aborted.
2313
2439
  *
2314
2440
  * @param {!TaskQueue} q the completed task queue.
2315
2441
  * @private
2316
2442
  */
2317
- onQueueEnd_: function(q) {
2443
+ onQueueEnd_(q) {
2318
2444
  if (!this.taskQueues_) {
2319
2445
  return;
2320
2446
  }
@@ -2324,15 +2450,18 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2324
2450
  vlog(1, () => this.taskQueues_.size + ' queues remain\n' + this, this);
2325
2451
 
2326
2452
  if (!this.taskQueues_.size) {
2327
- asserts.assert(!this.shutdownTask_, 'Already have a shutdown task??');
2328
- this.shutdownTask_ = new MicroTask(this.shutdown_, this);
2453
+ if (this.shutdownTask_) {
2454
+ throw Error('Already have a shutdown task??');
2455
+ }
2456
+ vlog(1, () => 'Scheduling shutdown\n' + this);
2457
+ this.shutdownTask_ = new MicroTask(() => this.shutdown_());
2329
2458
  }
2330
- },
2459
+ }
2331
2460
 
2332
2461
  /**
2333
2462
  * Event handler for when a task queue terminates with an error. This triggers
2334
2463
  * the cancellation of all other task queues and a
2335
- * {@link webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION} event.
2464
+ * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION} event.
2336
2465
  * If there are no error event listeners registered with this instance, the
2337
2466
  * error will be rethrown to the global error handler.
2338
2467
  *
@@ -2340,30 +2469,30 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2340
2469
  * @param {!TaskQueue} q the task queue.
2341
2470
  * @private
2342
2471
  */
2343
- onQueueError_: function(error, q) {
2472
+ onQueueError_(error, q) {
2344
2473
  if (this.taskQueues_) {
2345
2474
  this.taskQueues_.delete(q);
2346
2475
  }
2347
- this.cancelQueues_(promise.CancellationError.wrap(
2476
+ this.cancelQueues_(CancellationError.wrap(
2348
2477
  error, 'There was an uncaught error in the control flow'));
2349
2478
  this.cancelShutdown_();
2350
2479
  this.cancelHold_();
2351
2480
 
2352
2481
  var listeners = this.listeners(
2353
- promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
2354
- if (!listeners.length) {
2355
- throwException(error);
2482
+ ControlFlow.EventType.UNCAUGHT_EXCEPTION);
2483
+ if (!listeners.size) {
2484
+ asyncThrow(/** @type {!Error} */(error));
2356
2485
  } else {
2357
2486
  this.reportUncaughtException_(error);
2358
2487
  }
2359
- },
2488
+ }
2360
2489
 
2361
2490
  /**
2362
2491
  * Cancels all remaining task queues.
2363
- * @param {!promise.CancellationError} reason The cancellation reason.
2492
+ * @param {!CancellationError} reason The cancellation reason.
2364
2493
  * @private
2365
2494
  */
2366
- cancelQueues_: function(reason) {
2495
+ cancelQueues_(reason) {
2367
2496
  reason.silent_ = true;
2368
2497
  if (this.taskQueues_) {
2369
2498
  for (var q of this.taskQueues_) {
@@ -2373,53 +2502,53 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2373
2502
  this.taskQueues_.clear();
2374
2503
  this.taskQueues_ = null;
2375
2504
  }
2376
- },
2505
+ }
2377
2506
 
2378
2507
  /**
2379
2508
  * Reports an uncaught exception using a
2380
- * {@link webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION} event.
2509
+ * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION} event.
2381
2510
  *
2382
2511
  * @param {*} e the error to report.
2383
2512
  * @private
2384
2513
  */
2385
- reportUncaughtException_: function(e) {
2386
- this.emit(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, e);
2387
- },
2514
+ reportUncaughtException_(e) {
2515
+ this.emit(ControlFlow.EventType.UNCAUGHT_EXCEPTION, e);
2516
+ }
2388
2517
 
2389
2518
  /** @private */
2390
- cancelHold_: function() {
2519
+ cancelHold_() {
2391
2520
  if (this.hold_) {
2392
2521
  clearInterval(this.hold_);
2393
2522
  this.hold_ = null;
2394
2523
  }
2395
- },
2524
+ }
2396
2525
 
2397
2526
  /** @private */
2398
- shutdown_: function() {
2527
+ shutdown_() {
2399
2528
  vlog(1, () => 'Going idle: ' + this);
2400
2529
  this.cancelHold_();
2401
2530
  this.shutdownTask_ = null;
2402
- this.emit(promise.ControlFlow.EventType.IDLE);
2403
- },
2531
+ this.emit(ControlFlow.EventType.IDLE);
2532
+ }
2404
2533
 
2405
2534
  /**
2406
2535
  * Cancels the shutdown sequence if it is currently scheduled.
2407
2536
  * @private
2408
2537
  */
2409
- cancelShutdown_: function() {
2538
+ cancelShutdown_() {
2410
2539
  if (this.shutdownTask_) {
2411
2540
  this.shutdownTask_.cancel();
2412
2541
  this.shutdownTask_ = null;
2413
2542
  }
2414
2543
  }
2415
- });
2544
+ }
2416
2545
 
2417
2546
 
2418
2547
  /**
2419
- * Events that may be emitted by an {@link webdriver.promise.ControlFlow}.
2548
+ * Events that may be emitted by an {@link ControlFlow}.
2420
2549
  * @enum {string}
2421
2550
  */
2422
- promise.ControlFlow.EventType = {
2551
+ ControlFlow.EventType = {
2423
2552
 
2424
2553
  /** Emitted when all tasks have been successfully executed. */
2425
2554
  IDLE: 'idle',
@@ -2444,56 +2573,67 @@ promise.ControlFlow.EventType = {
2444
2573
  * Wraps a function to execute as a cancellable micro task.
2445
2574
  * @final
2446
2575
  */
2447
- var MicroTask = goog.defineClass(null, {
2576
+ class MicroTask {
2448
2577
  /**
2449
- * @param {function(this: THIS)} fn The function to run as a micro task.
2450
- * @param {THIS=} opt_scope The scope to run the function in.
2451
- * @template THIS
2578
+ * @param {function()} fn The function to run as a micro task.
2452
2579
  */
2453
- constructor: function(fn, opt_scope) {
2580
+ constructor(fn) {
2454
2581
  /** @private {boolean} */
2455
2582
  this.cancelled_ = false;
2456
- asyncRun(function() {
2583
+ asyncRun(() => {
2457
2584
  if (!this.cancelled_) {
2458
- fn.call(opt_scope);
2585
+ fn();
2459
2586
  }
2460
- }, this);
2461
- },
2587
+ });
2588
+ }
2589
+
2590
+ /**
2591
+ * Runs the given function after a micro-task yield.
2592
+ * @param {function()} fn The function to run.
2593
+ */
2594
+ static run(fn) {
2595
+ NativePromise.resolve().then(function() {
2596
+ try {
2597
+ fn();
2598
+ } catch (ignored) {
2599
+ // Do nothing.
2600
+ }
2601
+ });
2602
+ }
2462
2603
 
2463
2604
  /**
2464
2605
  * Cancels the execution of this task. Note: this will not prevent the task
2465
2606
  * timer from firing, just the invocation of the wrapped function.
2466
2607
  */
2467
- cancel: function() {
2608
+ cancel() {
2468
2609
  this.cancelled_ = true;
2469
2610
  }
2470
- });
2611
+ }
2471
2612
 
2472
2613
 
2473
2614
  /**
2474
- * A task to be executed by a {@link webdriver.promise.ControlFlow}.
2615
+ * A task to be executed by a {@link ControlFlow}.
2475
2616
  *
2617
+ * @template T
2476
2618
  * @final
2477
2619
  */
2478
- var Task = goog.defineClass(promise.Deferred, {
2620
+ class Task extends Deferred {
2479
2621
  /**
2480
- * @param {!promise.ControlFlow} flow The flow this instances belongs
2622
+ * @param {!ControlFlow} flow The flow this instances belongs
2481
2623
  * to.
2482
- * @param {function(): (T|!promise.Promise<T>)} fn The function to
2624
+ * @param {function(): (T|!ManagedPromise<T>)} fn The function to
2483
2625
  * call when the task executes. If it returns a
2484
- * {@link webdriver.promise.Promise}, the flow will wait for it to be
2626
+ * {@link ManagedPromise}, the flow will wait for it to be
2485
2627
  * resolved before starting the next task.
2486
2628
  * @param {string} description A description of the task for debugging.
2487
2629
  * @param {{name: string, top: !Function}=} opt_stackOptions Options to use
2488
2630
  * when capturing the stacktrace for when this task was created.
2489
- * @constructor
2490
- * @extends {promise.Deferred<T>}
2491
- * @template T
2492
2631
  */
2493
- constructor: function(flow, fn, description, opt_stackOptions) {
2494
- Task.base(this, 'constructor', flow);
2632
+ constructor(flow, fn, description, opt_stackOptions) {
2633
+ super(flow);
2634
+ getUid(this);
2495
2635
 
2496
- /** @type {function(): (T|!promise.Promise<T>)} */
2636
+ /** @type {function(): (T|!ManagedPromise<T>)} */
2497
2637
  this.execute = fn;
2498
2638
 
2499
2639
  /** @type {string} */
@@ -2519,20 +2659,20 @@ var Task = goog.defineClass(promise.Deferred, {
2519
2659
  this.blocked = false;
2520
2660
 
2521
2661
  if (opt_stackOptions) {
2522
- this.promise.stack_ = promise.captureStackTrace(
2662
+ this.promise.stack_ = captureStackTrace(
2523
2663
  opt_stackOptions.name, this.description, opt_stackOptions.top);
2524
2664
  }
2525
- },
2665
+ }
2526
2666
 
2527
2667
  /** @override */
2528
- toString: function() {
2529
- return 'Task::' + goog.getUid(this) + '<' + this.description + '>';
2668
+ toString() {
2669
+ return 'Task::' + getUid(this) + '<' + this.description + '>';
2530
2670
  }
2531
- });
2671
+ }
2532
2672
 
2533
2673
 
2534
2674
  /** @enum {string} */
2535
- var TaskQueueState = {
2675
+ const TaskQueueState = {
2536
2676
  NEW: 'new',
2537
2677
  STARTED: 'started',
2538
2678
  FINISHED: 'finished'
@@ -2542,16 +2682,15 @@ var TaskQueueState = {
2542
2682
  /**
2543
2683
  * @final
2544
2684
  */
2545
- var TaskQueue = goog.defineClass(EventEmitter, {
2546
- /** @param {!promise.ControlFlow} flow . */
2547
- constructor: function(flow) {
2548
- TaskQueue.base(this, 'constructor');
2549
- goog.getUid(this);
2685
+ class TaskQueue extends events.EventEmitter {
2686
+ /** @param {!ControlFlow} flow . */
2687
+ constructor(flow) {
2688
+ super();
2550
2689
 
2551
2690
  /** @private {string} */
2552
- this.name_ = 'TaskQueue::' + goog.getUid(this);
2691
+ this.name_ = 'TaskQueue::' + getUid(this);
2553
2692
 
2554
- /** @private {!promise.ControlFlow} */
2693
+ /** @private {!ControlFlow} */
2555
2694
  this.flow_ = flow;
2556
2695
 
2557
2696
  /** @private {!Array<!Task>} */
@@ -2566,41 +2705,41 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2566
2705
  /** @private {TaskQueueState} */
2567
2706
  this.state_ = TaskQueueState.NEW;
2568
2707
 
2569
- /** @private {!Set<!webdriver.promise.Promise>} */
2708
+ /** @private {!Set<!ManagedPromise>} */
2570
2709
  this.unhandledRejections_ = new Set();
2571
- },
2710
+ }
2572
2711
 
2573
2712
  /** @override */
2574
- toString: function() {
2575
- return 'TaskQueue::' + goog.getUid(this);
2576
- },
2713
+ toString() {
2714
+ return 'TaskQueue::' + getUid(this);
2715
+ }
2577
2716
 
2578
2717
  /**
2579
- * @param {!webdriver.promise.Promise} promise .
2718
+ * @param {!ManagedPromise} promise .
2580
2719
  */
2581
- addUnhandledRejection: function(promise) {
2720
+ addUnhandledRejection(promise) {
2582
2721
  // TODO: node 4.0.0+
2583
2722
  vlog(2, () => this + ' registering unhandled rejection: ' + promise, this);
2584
2723
  this.unhandledRejections_.add(promise);
2585
- },
2724
+ }
2586
2725
 
2587
2726
  /**
2588
- * @param {!webdriver.promise.Promise} promise .
2727
+ * @param {!ManagedPromise} promise .
2589
2728
  */
2590
- clearUnhandledRejection: function(promise) {
2729
+ clearUnhandledRejection(promise) {
2591
2730
  var deleted = this.unhandledRejections_.delete(promise);
2592
2731
  if (deleted) {
2593
2732
  // TODO: node 4.0.0+
2594
2733
  vlog(2, () => this + ' clearing unhandled rejection: ' + promise, this);
2595
2734
  }
2596
- },
2735
+ }
2597
2736
 
2598
2737
  /**
2599
2738
  * Enqueues a new task for execution.
2600
2739
  * @param {!Task} task The task to enqueue.
2601
2740
  * @throws {Error} If this instance has already started execution.
2602
2741
  */
2603
- enqueue: function(task) {
2742
+ enqueue(task) {
2604
2743
  if (this.state_ !== TaskQueueState.NEW) {
2605
2744
  throw Error('TaskQueue has started: ' + this);
2606
2745
  }
@@ -2616,16 +2755,16 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2616
2755
 
2617
2756
  vlog(1, () => this + '.enqueue(' + task + ')', this);
2618
2757
  vlog(2, () => this.flow_.toString(), this);
2619
- },
2758
+ }
2620
2759
 
2621
2760
  /**
2622
2761
  * Schedules the callbacks registered on the given promise in this queue.
2623
2762
  *
2624
- * @param {!promise.Promise} promise the promise whose callbacks should be
2763
+ * @param {!ManagedPromise} promise the promise whose callbacks should be
2625
2764
  * registered as interrupts in this task queue.
2626
2765
  * @throws {Error} if this queue has already finished.
2627
2766
  */
2628
- scheduleCallbacks: function(promise) {
2767
+ scheduleCallbacks(promise) {
2629
2768
  if (this.state_ === TaskQueueState.FINISHED) {
2630
2769
  throw new Error('cannot interrupt a finished q(' + this + ')');
2631
2770
  }
@@ -2633,7 +2772,7 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2633
2772
  if (this.pending_ && this.pending_.task.promise === promise) {
2634
2773
  this.pending_.task.promise.queue_ = null;
2635
2774
  this.pending_ = null;
2636
- asyncRun(this.executeNext_, this);
2775
+ asyncRun(() => this.executeNext_());
2637
2776
  }
2638
2777
 
2639
2778
  if (!promise.callbacks_) {
@@ -2663,7 +2802,7 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2663
2802
  }, this);
2664
2803
  promise.callbacks_ = null;
2665
2804
  vlog(2, () => this + ' interrupted\n' + this.flow_, this);
2666
- },
2805
+ }
2667
2806
 
2668
2807
  /**
2669
2808
  * Starts executing tasks in this queue. Once called, no further tasks may
@@ -2671,15 +2810,15 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2671
2810
  *
2672
2811
  * @throws {Error} if this queue has already been started.
2673
2812
  */
2674
- start: function() {
2813
+ start() {
2675
2814
  if (this.state_ !== TaskQueueState.NEW) {
2676
2815
  throw new Error('TaskQueue has already started');
2677
2816
  }
2678
2817
  // Always asynchronously execute next, even if there doesn't look like
2679
2818
  // there is anything in the queue. This will catch pending unhandled
2680
2819
  // rejections that were registered before start was called.
2681
- asyncRun(this.executeNext_, this);
2682
- },
2820
+ asyncRun(() => this.executeNext_());
2821
+ }
2683
2822
 
2684
2823
  /**
2685
2824
  * Aborts this task queue. If there are any scheduled tasks, they are silently
@@ -2690,7 +2829,7 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2690
2829
  * @param {*} error The abortion reason.
2691
2830
  * @private
2692
2831
  */
2693
- abort_: function(error) {
2832
+ abort_(error) {
2694
2833
  var cancellation;
2695
2834
 
2696
2835
  if (error instanceof FlowResetError) {
@@ -2711,23 +2850,22 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2711
2850
 
2712
2851
  if (this.pending_) {
2713
2852
  vlog(2, () => this + '.abort(); cancelling pending task', this);
2714
- this.pending_.task.cancel(
2715
- /** @type {!webdriver.promise.CancellationError} */(error));
2853
+ this.pending_.task.cancel(/** @type {!CancellationError} */(error));
2716
2854
 
2717
2855
  } else {
2718
2856
  vlog(2, () => this + '.abort(); emitting error event', this);
2719
2857
  this.emit('error', error, this);
2720
2858
  }
2721
- },
2859
+ }
2722
2860
 
2723
2861
  /** @private */
2724
- executeNext_: function() {
2862
+ executeNext_() {
2725
2863
  if (this.state_ === TaskQueueState.FINISHED) {
2726
2864
  return;
2727
2865
  }
2728
2866
  this.state_ = TaskQueueState.STARTED;
2729
2867
 
2730
- if (this.pending_ != null || this.processUnhandledRejections_()) {
2868
+ if (this.pending_ !== null || this.processUnhandledRejections_()) {
2731
2869
  return;
2732
2870
  }
2733
2871
 
@@ -2760,8 +2898,7 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2760
2898
  } catch (ex) {
2761
2899
  subQ.abort_(ex);
2762
2900
  }
2763
- },
2764
-
2901
+ }
2765
2902
 
2766
2903
  /**
2767
2904
  * @param {!Function} fn .
@@ -2769,7 +2906,7 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2769
2906
  * @template T
2770
2907
  * @private
2771
2908
  */
2772
- execute_: function(fn) {
2909
+ execute_(fn) {
2773
2910
  try {
2774
2911
  activeFlows.push(this.flow_);
2775
2912
  this.flow_.activeQueue_ = this;
@@ -2778,17 +2915,17 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2778
2915
  this.flow_.activeQueue_ = null;
2779
2916
  activeFlows.pop();
2780
2917
  }
2781
- },
2918
+ }
2782
2919
 
2783
2920
  /**
2784
2921
  * Process any unhandled rejections registered with this task queue. If there
2785
2922
  * is a rejection, this queue will be aborted with the rejection error. If
2786
2923
  * there are multiple rejections registered, this queue will be aborted with
2787
- * a {@link promise.MultipleUnhandledRejectionError}.
2924
+ * a {@link MultipleUnhandledRejectionError}.
2788
2925
  * @return {boolean} whether there was an unhandled rejection.
2789
2926
  * @private
2790
2927
  */
2791
- processUnhandledRejections_: function() {
2928
+ processUnhandledRejections_() {
2792
2929
  if (!this.unhandledRejections_.size) {
2793
2930
  return false;
2794
2931
  }
@@ -2801,7 +2938,7 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2801
2938
 
2802
2939
  var errorToReport = errors.size === 1
2803
2940
  ? errors.values().next().value
2804
- : new promise.MultipleUnhandledRejectionError(errors);
2941
+ : new MultipleUnhandledRejectionError(errors);
2805
2942
 
2806
2943
  vlog(1, () => this + ' aborting due to unhandled rejections', this);
2807
2944
  if (this.flow_.propagateUnhandledRejections_) {
@@ -2812,13 +2949,13 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2812
2949
  this.flow_.reportUncaughtException_(errorToReport);
2813
2950
  return false;
2814
2951
  }
2815
- },
2952
+ }
2816
2953
 
2817
2954
  /**
2818
2955
  * @param {!Task} task The task to drop.
2819
2956
  * @private
2820
2957
  */
2821
- dropTask_: function(task) {
2958
+ dropTask_(task) {
2822
2959
  var index;
2823
2960
  if (this.interrupts_) {
2824
2961
  index = this.interrupts_.indexOf(task);
@@ -2834,49 +2971,49 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2834
2971
  task.queue = null;
2835
2972
  this.tasks_.splice(index, 1);
2836
2973
  }
2837
- },
2974
+ }
2838
2975
 
2839
2976
  /**
2840
2977
  * @param {!Task} task The task that was cancelled.
2841
- * @param {!promise.CancellationError} reason The cancellation reason.
2978
+ * @param {!CancellationError} reason The cancellation reason.
2842
2979
  * @private
2843
2980
  */
2844
- onTaskCancelled_: function(task, reason) {
2981
+ onTaskCancelled_(task, reason) {
2845
2982
  if (this.pending_ && this.pending_.task === task) {
2846
2983
  this.pending_.q.abort_(reason);
2847
2984
  } else {
2848
2985
  this.dropTask_(task);
2849
2986
  }
2850
- },
2987
+ }
2851
2988
 
2852
2989
  /**
2853
2990
  * @param {*} value the value originally returned by the task function.
2854
2991
  * @private
2855
2992
  */
2856
- onTaskComplete_: function(value) {
2993
+ onTaskComplete_(value) {
2857
2994
  if (this.pending_) {
2858
2995
  this.pending_.task.fulfill(value);
2859
2996
  }
2860
- },
2997
+ }
2861
2998
 
2862
2999
  /**
2863
3000
  * @param {*} taskFnResult the value originally returned by the task function.
2864
3001
  * @param {*} error the error that caused the task function to terminate.
2865
3002
  * @private
2866
3003
  */
2867
- onTaskFailure_: function(taskFnResult, error) {
2868
- if (promise.Thenable.isImplementation(taskFnResult)) {
2869
- taskFnResult.cancel(promise.CancellationError.wrap(error));
3004
+ onTaskFailure_(taskFnResult, error) {
3005
+ if (Thenable.isImplementation(taskFnResult)) {
3006
+ taskFnResult.cancel(CancellationError.wrap(error));
2870
3007
  }
2871
3008
  this.pending_.task.reject(error);
2872
- },
3009
+ }
2873
3010
 
2874
3011
  /**
2875
3012
  * @return {(Task|undefined)} the next task scheduled within this queue,
2876
3013
  * if any.
2877
3014
  * @private
2878
3015
  */
2879
- getNextTask_: function() {
3016
+ getNextTask_() {
2880
3017
  var task = undefined;
2881
3018
  while (true) {
2882
3019
  if (this.interrupts_) {
@@ -2896,15 +3033,15 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2896
3033
  }
2897
3034
  return task;
2898
3035
  }
2899
- });
3036
+ };
2900
3037
 
2901
3038
 
2902
3039
 
2903
3040
  /**
2904
3041
  * The default flow to use if no others are active.
2905
- * @type {!promise.ControlFlow}
3042
+ * @type {!ControlFlow}
2906
3043
  */
2907
- var defaultFlow = new promise.ControlFlow();
3044
+ var defaultFlow = new ControlFlow();
2908
3045
 
2909
3046
 
2910
3047
  /**
@@ -2912,48 +3049,48 @@ var defaultFlow = new promise.ControlFlow();
2912
3049
  * commands. When there are multiple flows on the stack, the flow at index N
2913
3050
  * represents a callback triggered within a task owned by the flow at index
2914
3051
  * N-1.
2915
- * @type {!Array<!promise.ControlFlow>}
3052
+ * @type {!Array<!ControlFlow>}
2916
3053
  */
2917
3054
  var activeFlows = [];
2918
3055
 
2919
3056
 
2920
3057
  /**
2921
3058
  * Changes the default flow to use when no others are active.
2922
- * @param {!promise.ControlFlow} flow The new default flow.
3059
+ * @param {!ControlFlow} flow The new default flow.
2923
3060
  * @throws {Error} If the default flow is not currently active.
2924
3061
  */
2925
- promise.setDefaultFlow = function(flow) {
3062
+ function setDefaultFlow(flow) {
2926
3063
  if (activeFlows.length) {
2927
3064
  throw Error('You may only change the default flow while it is active');
2928
3065
  }
2929
3066
  defaultFlow = flow;
2930
- };
3067
+ }
2931
3068
 
2932
3069
 
2933
3070
  /**
2934
- * @return {!promise.ControlFlow} The currently active control flow.
3071
+ * @return {!ControlFlow} The currently active control flow.
2935
3072
  */
2936
- promise.controlFlow = function() {
2937
- return /** @type {!promise.ControlFlow} */ (
2938
- Arrays.peek(activeFlows) || defaultFlow);
2939
- };
3073
+ function controlFlow() {
3074
+ return /** @type {!ControlFlow} */ (
3075
+ activeFlows.length ? activeFlows[activeFlows.length - 1] : defaultFlow);
3076
+ }
2940
3077
 
2941
3078
 
2942
3079
  /**
2943
3080
  * Creates a new control flow. The provided callback will be invoked as the
2944
3081
  * first task within the new flow, with the flow as its sole argument. Returns
2945
3082
  * a promise that resolves to the callback result.
2946
- * @param {function(!promise.ControlFlow)} callback The entry point
3083
+ * @param {function(!ControlFlow)} callback The entry point
2947
3084
  * to the newly created flow.
2948
- * @return {!promise.Promise} A promise that resolves to the callback
3085
+ * @return {!ManagedPromise} A promise that resolves to the callback
2949
3086
  * result.
2950
3087
  */
2951
- promise.createFlow = function(callback) {
2952
- var flow = new promise.ControlFlow;
3088
+ function createFlow(callback) {
3089
+ var flow = new ControlFlow;
2953
3090
  return flow.execute(function() {
2954
3091
  return callback(flow);
2955
3092
  });
2956
- };
3093
+ }
2957
3094
 
2958
3095
 
2959
3096
  /**
@@ -2961,9 +3098,9 @@ promise.createFlow = function(callback) {
2961
3098
  * @param {!Function} fn The function to test.
2962
3099
  * @return {boolean} Whether the function is a generator.
2963
3100
  */
2964
- promise.isGenerator = function(fn) {
3101
+ function isGenerator(fn) {
2965
3102
  return fn.constructor.name === 'GeneratorFunction';
2966
- };
3103
+ }
2967
3104
 
2968
3105
 
2969
3106
  /**
@@ -2992,7 +3129,7 @@ promise.isGenerator = function(fn) {
2992
3129
  * yield promise.delayed(250).then(function() {
2993
3130
  * throw Error('boom');
2994
3131
  * });
2995
- * }).thenCatch(function(e) {
3132
+ * }).catch(function(e) {
2996
3133
  * console.log(e.toString()); // Error: boom
2997
3134
  * });
2998
3135
  *
@@ -3000,18 +3137,19 @@ promise.isGenerator = function(fn) {
3000
3137
  * @param {Object=} opt_self The object to use as "this" when invoking the
3001
3138
  * initial generator.
3002
3139
  * @param {...*} var_args Any arguments to pass to the initial generator.
3003
- * @return {!promise.Promise<?>} A promise that will resolve to the
3140
+ * @return {!ManagedPromise<?>} A promise that will resolve to the
3004
3141
  * generator's final result.
3005
3142
  * @throws {TypeError} If the given function is not a generator.
3006
3143
  */
3007
- promise.consume = function(generatorFn, opt_self, var_args) {
3008
- if (!promise.isGenerator(generatorFn)) {
3144
+ function consume(generatorFn, opt_self, var_args) {
3145
+ if (!isGenerator(generatorFn)) {
3009
3146
  throw new TypeError('Input is not a GeneratorFunction: ' +
3010
3147
  generatorFn.constructor.name);
3011
3148
  }
3012
3149
 
3013
- var deferred = promise.defer();
3014
- var generator = generatorFn.apply(opt_self, Arrays.slice(arguments, 2));
3150
+ var deferred = defer();
3151
+ var generator = generatorFn.apply(
3152
+ opt_self, Array.prototype.slice.call(arguments, 2));
3015
3153
  callNext();
3016
3154
  return deferred.promise;
3017
3155
 
@@ -3044,6 +3182,41 @@ promise.consume = function(generatorFn, opt_self, var_args) {
3044
3182
  return;
3045
3183
  }
3046
3184
 
3047
- promise.asap(result.value, callNext, callThrow);
3185
+ asap(result.value, callNext, callThrow);
3048
3186
  }
3187
+ }
3188
+
3189
+
3190
+ // PUBLIC API
3191
+
3192
+
3193
+ module.exports = {
3194
+ CancellationError: CancellationError,
3195
+ ControlFlow: ControlFlow,
3196
+ Deferred: Deferred,
3197
+ MultipleUnhandledRejectionError: MultipleUnhandledRejectionError,
3198
+ Thenable: Thenable,
3199
+ Promise: ManagedPromise,
3200
+ all: all,
3201
+ asap: asap,
3202
+ captureStackTrace: captureStackTrace,
3203
+ checkedNodeCall: checkedNodeCall,
3204
+ consume: consume,
3205
+ controlFlow: controlFlow,
3206
+ createFlow: createFlow,
3207
+ defer: defer,
3208
+ delayed: delayed,
3209
+ filter: filter,
3210
+ fulfilled: fulfilled,
3211
+ fullyResolved: fullyResolved,
3212
+ isGenerator: isGenerator,
3213
+ isPromise: isPromise,
3214
+ map: map,
3215
+ rejected: rejected,
3216
+ setDefaultFlow: setDefaultFlow,
3217
+ thenFinally: thenFinally,
3218
+ when: when,
3219
+
3220
+ get LONG_STACK_TRACES() { return LONG_STACK_TRACES; },
3221
+ set LONG_STACK_TRACES(v) { LONG_STACK_TRACES = v; },
3049
3222
  };