| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview JavaScript implementation of the Payment Request API. Conforms | 6 * @fileoverview JavaScript implementation of the Payment Request API. Conforms |
| 7 * to the 18 July 2016 editor's draft at | 7 * to the 18 July 2016 editor's draft at |
| 8 * https://w3c.github.io/browser-payment-api/. | 8 * https://w3c.github.io/browser-payment-api/. |
| 9 * | 9 * |
| 10 * This is a minimal implementation that sends data to the app side to present | 10 * This is a minimal implementation that sends data to the app side to present |
| 11 * the user interface. When loaded, installs the API onto the window object. | 11 * the user interface. When loaded, installs the API onto the window object. |
| 12 */ | 12 */ |
| 13 | 13 |
| 14 // Namespace for all PaymentRequest implementations. __gCrWeb must have already | 14 // Namespace for all PaymentRequest implementations. __gCrWeb must have already |
| 15 // been defined. | 15 // been defined. |
| 16 __gCrWeb.paymentRequestManager = { | 16 __gCrWeb.paymentRequestManager = { |
| 17 /** | 17 /** |
| 18 * The pending PaymentRequest, if any. Used by the app side to invoke the | 18 * The pending PaymentRequest, if any. Used by the app side to invoke the |
| 19 * associated resolve or reject function. | 19 * associated resolve or reject function. |
| 20 * @type {window.PaymentRequest} | 20 * @type {window.PaymentRequest} |
| 21 */ | 21 */ |
| 22 pendingRequest: null, | 22 pendingRequest: null, |
| 23 | 23 |
| 24 /** | 24 /** |
| 25 * The pending PaymentResponse, if any. Used by the app side to invoke the | 25 * The pending PaymentResponse, if any. Used by the app side to invoke the |
| 26 * associated resolve or reject function. | 26 * associated resolve function. |
| 27 * @type {window.PaymentResponse} | 27 * @type {window.PaymentResponse} |
| 28 */ | 28 */ |
| 29 pendingResponse: null | 29 pendingResponse: null |
| 30 }; | 30 }; |
| 31 __gCrWeb['paymentRequestManager'] = __gCrWeb.paymentRequestManager; | 31 __gCrWeb['paymentRequestManager'] = __gCrWeb.paymentRequestManager; |
| 32 | 32 |
| 33 /** @typedef {{ | 33 /** @typedef {{ |
| 34 * methodData: !Array.<window.PaymentMethodData>, | 34 * methodData: !Array.<window.PaymentMethodData>, |
| 35 * details: !window.PaymentDetails, | 35 * details: !window.PaymentDetails, |
| 36 * options: (window.PaymentOptions|undefined) | 36 * options: (window.PaymentOptions|undefined) |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 paymentResponse = window.PaymentResponse.parse(paymentResponseData); | 180 paymentResponse = window.PaymentResponse.parse(paymentResponseData); |
| 181 } catch (e) { | 181 } catch (e) { |
| 182 throw new Error( | 182 throw new Error( |
| 183 "Internal PaymentRequest error: failed to parse PaymentResponse data."); | 183 "Internal PaymentRequest error: failed to parse PaymentResponse data."); |
| 184 } | 184 } |
| 185 this.resolve_(paymentResponse); | 185 this.resolve_(paymentResponse); |
| 186 | 186 |
| 187 this.resolve_ = null; | 187 this.resolve_ = null; |
| 188 this.reject_ = null; | 188 this.reject_ = null; |
| 189 __gCrWeb['paymentRequestManager'].pendingRequest = null; | 189 __gCrWeb['paymentRequestManager'].pendingRequest = null; |
| 190 __gCrWeb['paymentRequestManager'].pendingResponse = paymentResponse; |
| 190 } | 191 } |
| 191 | 192 |
| 192 /** | 193 /** |
| 193 * Rejects the pending Promise. Should only be called by the app-side logic. | 194 * Rejects the pending Promise. Should only be called by the app-side logic. |
| 194 * @param {!string} message An error message explaining why the Promise is being | 195 * @param {!string} message An error message explaining why the Promise is being |
| 195 * rejected. | 196 * rejected. |
| 196 */ | 197 */ |
| 197 window.PaymentRequest.prototype.reject = function(message) { | 198 window.PaymentRequest.prototype.reject = function(message) { |
| 198 if (!this.reject_) { | 199 if (!this.reject_) { |
| 199 throw new Error("Internal PaymentRequest error: reject function missing."); | 200 throw new Error("Internal PaymentRequest error: reject function missing."); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 */ | 318 */ |
| 318 this.details = details; | 319 this.details = details; |
| 319 | 320 |
| 320 /** | 321 /** |
| 321 * The pending resolve function provided to the Promise returned by | 322 * The pending resolve function provided to the Promise returned by |
| 322 * complete(). | 323 * complete(). |
| 323 * @type {?function()} | 324 * @type {?function()} |
| 324 * @private | 325 * @private |
| 325 */ | 326 */ |
| 326 this.resolve_ = null; | 327 this.resolve_ = null; |
| 327 | |
| 328 /** | |
| 329 * The pending reject function provided to the Promise returned by complete(). | |
| 330 * @type {?function(string)} | |
| 331 * @private | |
| 332 */ | |
| 333 this.reject_ = null; | |
| 334 }; | 328 }; |
| 335 | 329 |
| 336 /** | 330 /** |
| 337 * Communicates the result of processing the payment. | 331 * Communicates the result of processing the payment. |
| 338 * @param {boolean} success Indicates whether processing succeeded. | 332 * @param {boolean} success Indicates whether processing succeeded. |
| 339 * @return {!Promise} A promise to notify the caller when the user interface has | 333 * @return {!Promise} A promise to notify the caller when the user interface has |
| 340 * been closed. | 334 * been closed. |
| 341 */ | 335 */ |
| 342 window.PaymentResponse.prototype.complete = function(success) { | 336 window.PaymentResponse.prototype.complete = function(success) { |
| 343 if (__gCrWeb['paymentRequestManager'].pendingResponse) { | |
| 344 throw new Error( | |
| 345 'Internal PaymentRequest error: A response is already pending.'); | |
| 346 } | |
| 347 __gCrWeb['paymentRequestManager'].pendingResponse = this; | |
| 348 | |
| 349 var message = { | 337 var message = { |
| 350 'command': 'paymentRequest.responseComplete' | 338 'command': 'paymentRequest.responseComplete' |
| 351 }; | 339 }; |
| 352 __gCrWeb.message.invokeOnHost(message); | 340 __gCrWeb.message.invokeOnHost(message); |
| 353 | 341 |
| 354 var self = this; | 342 var self = this; |
| 355 return new Promise(function(resolve, reject) { | 343 return new Promise(function(resolve, reject) { |
| 356 self.resolve_ = resolve; | 344 self.resolve_ = resolve; |
| 357 self.reject_ = reject; | 345 // Any reject function provided is ignored because the spec includes no |
| 346 // provision for rejecting the response promise. User agents are directed to |
| 347 // always resolve the promise. |
| 358 }); | 348 }); |
| 359 }; | 349 }; |
| 360 | 350 |
| 361 /** | 351 /** |
| 362 * Resolves the pending Promise. Should only be called by the app-side logic. | 352 * Resolves the pending Promise. Should only be called by the app-side logic. |
| 363 */ | 353 */ |
| 364 window.PaymentResponse.prototype.resolve = function() { | 354 window.PaymentResponse.prototype.resolve = function() { |
| 355 // If the page has not yet provided a resolve function, do nothing. This can |
| 356 // happen in the case where the UI times out while waiting for the page to |
| 357 // call complete(). |
| 365 if (!this.resolve_) { | 358 if (!this.resolve_) { |
| 366 throw new Error("Internal PaymentRequest error: resolve function missing."); | 359 return; |
| 367 } | 360 } |
| 368 | 361 |
| 369 this.resolve_(); | 362 this.resolve_(); |
| 370 | 363 |
| 371 this.resolve_ = null; | 364 this.resolve_ = null; |
| 372 this.reject_ = null; | |
| 373 __gCrWeb['paymentRequestManager'].pendingResponse = null; | 365 __gCrWeb['paymentRequestManager'].pendingResponse = null; |
| 374 } | 366 } |
| 375 | 367 |
| 376 /** | |
| 377 * Rejects the pending Promise. Should only be called by the app-side logic. | |
| 378 * @param {!string} message An error message explaining why the Promise is being | |
| 379 * rejected. | |
| 380 */ | |
| 381 window.PaymentResponse.prototype.reject = function(message) { | |
| 382 if (!this.reject_) { | |
| 383 throw new Error("Internal PaymentRequest error: reject function missing."); | |
| 384 } | |
| 385 | |
| 386 this.reject_(message); | |
| 387 | |
| 388 this.resolve_ = null; | |
| 389 this.reject_ = null; | |
| 390 __gCrWeb['paymentRequestManager'].pendingResponse = null; | |
| 391 } | |
| 392 | |
| 393 /** | 368 /** |
| 394 * Parses |paymentResponseData| into a PaymentResponse object. | 369 * Parses |paymentResponseData| into a PaymentResponse object. |
| 395 * @param {!__gCrWeb.paymentRequestManager.SerializedPaymentResponse} | 370 * @param {!__gCrWeb.paymentRequestManager.SerializedPaymentResponse} |
| 396 * paymentResponseData A simple object representation of a PaymentResponse. | 371 * paymentResponseData A simple object representation of a PaymentResponse. |
| 397 * @return {window.PaymentResponse} A PaymentResponse object. | 372 * @return {window.PaymentResponse} A PaymentResponse object. |
| 398 */ | 373 */ |
| 399 window.PaymentResponse.parse = function(paymentResponseData) { | 374 window.PaymentResponse.parse = function(paymentResponseData) { |
| 400 return new window.PaymentResponse(paymentResponseData['methodName'], | 375 return new window.PaymentResponse(paymentResponseData['methodName'], |
| 401 paymentResponseData['details']); | 376 paymentResponseData['details']); |
| 402 }; | 377 }; |
| OLD | NEW |