blob: be8a633255811c6ba13c47c84d6c9386bf3fe508 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/payments/js_payment_request_manager.h"
#include "base/json/json_writer.h"
#include "base/json/string_escape.h"
#include "base/memory/ptr_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/values.h"
#include "components/payments/core/payment_address.h"
#include "components/payments/core/payment_response.h"
#include "components/payments/core/payment_shipping_option.h"
#include "components/payments/core/web_payment_request.h"
#import "ios/chrome/browser/payments/payment_request_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// Sanitizes |JSON| and wraps it in quotes so it can be injected safely in
// JavaScript.
NSString* JSONEscape(NSString* JSON) {
return base::SysUTF8ToNSString(
base::GetQuotedJSONString(base::SysNSStringToUTF8(JSON)));
}
} // namespace
@interface JSPaymentRequestManager ()
// Executes the JavaScript in |script| and passes a BOOL to |completionHandler|
// indicating whether an error occurred. The resolve and reject functions in the
// Payment Request JavaScript do not return values so the result is ignored.
- (void)executeScript:(NSString*)script
completionHandler:(ProceduralBlockWithBool)completionHandler;
@end
@implementation JSPaymentRequestManager
- (void)executeNoop {
[self executeScript:@"Function.prototype()" completionHandler:nil];
}
- (void)setContextSecure:(BOOL)contextSecure
completionHandler:(ProceduralBlockWithBool)completionHandler {
NSString* script =
[NSString stringWithFormat:
@"__gCrWeb['paymentRequestManager'].isContextSecure = %@;",
contextSecure ? @"true" : @"false"];
[self executeScript:script completionHandler:completionHandler];
}
- (void)throwDOMExceptionWithErrorName:(NSString*)errorName
errorMessage:(NSString*)errorMessage
completionHandler:
(ProceduralBlockWithBool)completionHandler {
NSString* script = [NSString
stringWithFormat:@"throw new DOMException(%@, %@);",
JSONEscape(errorMessage), JSONEscape(errorName)];
[self executeScript:script completionHandler:completionHandler];
}
- (void)resolveRequestPromiseWithPaymentResponse:
(const payments::PaymentResponse&)paymentResponse
completionHandler:
(ProceduralBlockWithBool)completionHandler {
std::unique_ptr<base::DictionaryValue> paymentResponseData =
payment_request_util::PaymentResponseToDictionaryValue(paymentResponse);
std::string paymentResponseDataJSON;
base::JSONWriter::Write(*paymentResponseData, &paymentResponseDataJSON);
NSString* script = [NSString
stringWithFormat:
@"__gCrWeb['paymentRequestManager'].resolveRequestPromise(%@)",
base::SysUTF8ToNSString(paymentResponseDataJSON)];
[self executeScript:script completionHandler:completionHandler];
}
- (void)rejectRequestPromiseWithErrorName:(NSString*)errorName
errorMessage:(NSString*)errorMessage
completionHandler:
(ProceduralBlockWithBool)completionHandler {
NSString* script =
[NSString stringWithFormat:
@"__gCrWeb['paymentRequestManager'].rejectRequestPromise("
@"new DOMException(%@, %@))",
JSONEscape(errorMessage), JSONEscape(errorName)];
[self executeScript:script completionHandler:completionHandler];
}
- (void)resolveCanMakePaymentPromiseWithValue:(bool)value
completionHandler:
(ProceduralBlockWithBool)completionHandler {
NSString* script = [NSString
stringWithFormat:
@"__gCrWeb['paymentRequestManager'].resolveCanMakePaymentPromise(%@)",
value ? @"true" : @"false"];
[self executeScript:script completionHandler:completionHandler];
}
- (void)rejectCanMakePaymentPromiseWithErrorName:(NSString*)errorName
errorMessage:(NSString*)errorMessage
completionHandler:
(ProceduralBlockWithBool)completionHandler {
NSString* script = [NSString
stringWithFormat:
@"__gCrWeb['paymentRequestManager'].rejectCanMakePaymentPromise(new "
@"DOMException(%@, %@))",
JSONEscape(errorMessage), JSONEscape(errorName)];
[self executeScript:script completionHandler:completionHandler];
}
- (void)resolveAbortPromiseWithCompletionHandler:
(ProceduralBlockWithBool)completionHandler {
NSString* script = @"__gCrWeb['paymentRequestManager'].resolveAbortPromise()";
[self executeScript:script completionHandler:completionHandler];
}
- (void)resolveResponsePromiseWithCompletionHandler:
(ProceduralBlockWithBool)completionHandler {
NSString* script =
@"__gCrWeb['paymentRequestManager'].resolveResponsePromise()";
[self executeScript:script completionHandler:completionHandler];
}
- (void)updateShippingAddress:
(const payments::mojom::PaymentAddress&)shippingAddress
completionHandler:(ProceduralBlockWithBool)completionHanlder {
std::unique_ptr<base::DictionaryValue> shippingAddressData =
payments::PaymentAddressToDictionaryValue(shippingAddress);
std::string shippingAddressDataJSON;
base::JSONWriter::Write(*shippingAddressData, &shippingAddressDataJSON);
NSString* script = [NSString
stringWithFormat:@"__gCrWeb['paymentRequestManager']."
@"updateShippingAddressAndDispatchEvent(%@)",
base::SysUTF8ToNSString(shippingAddressDataJSON)];
[self executeScript:script completionHandler:completionHanlder];
}
- (void)updateShippingOption:
(const payments::PaymentShippingOption&)shippingOption
completionHandler:(ProceduralBlockWithBool)completionHanlder {
NSString* script =
[NSString stringWithFormat:
@"__gCrWeb['paymentRequestManager']."
@"updateShippingOptionAndDispatchEvent(%@)",
JSONEscape(base::SysUTF8ToNSString(shippingOption.id))];
[self executeScript:script completionHandler:completionHanlder];
}
- (void)executeScript:(NSString*)script
completionHandler:(ProceduralBlockWithBool)completionHandler {
[self executeJavaScript:script
completionHandler:^(id result, NSError* error) {
if (completionHandler)
completionHandler(!error);
}];
}
#pragma mark - Protected methods
- (NSString*)presenceBeacon {
return @"__gCrWeb.paymentRequestManager";
}
@end