mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 10:55:00 +08:00
Merge branch 'trunk' into PCP-1393-update-to-vault-v-3
This commit is contained in:
commit
3e468896b6
18 changed files with 507 additions and 138 deletions
|
@ -279,11 +279,12 @@ document.addEventListener(
|
|||
});
|
||||
|
||||
let bootstrapped = false;
|
||||
let failed = false;
|
||||
|
||||
hideOrderButtonIfPpcpGateway();
|
||||
|
||||
jQuery(document.body).on('updated_checkout payment_method_selected', () => {
|
||||
if (bootstrapped) {
|
||||
if (bootstrapped || failed) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -294,6 +295,12 @@ document.addEventListener(
|
|||
bootstrapped = true;
|
||||
|
||||
bootstrap();
|
||||
}, () => {
|
||||
failed = true;
|
||||
|
||||
setVisibleByClass(ORDER_BUTTON_SELECTOR, true, 'ppcp-hidden');
|
||||
buttonsSpinner.unblock();
|
||||
cardsSpinner.unblock();
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
|
@ -26,7 +26,7 @@ const storeToken = (token) => {
|
|||
sessionStorage.setItem(storageKey, JSON.stringify(token));
|
||||
}
|
||||
|
||||
const dataClientIdAttributeHandler = (scriptOptions, config, callback) => {
|
||||
const dataClientIdAttributeHandler = (scriptOptions, config, callback, errorCallback = null) => {
|
||||
fetch(config.endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
|
@ -51,6 +51,10 @@ const dataClientIdAttributeHandler = (scriptOptions, config, callback) => {
|
|||
if (typeof callback === 'function') {
|
||||
callback(paypal);
|
||||
}
|
||||
}).catch(err => {
|
||||
if (typeof errorCallback === 'function') {
|
||||
errorCallback(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,10 +7,11 @@ import {keysToCamelCase} from "./Utils";
|
|||
// This component may be used by multiple modules. This assures that options are shared between all instances.
|
||||
let options = window.ppcpWidgetBuilder = window.ppcpWidgetBuilder || {
|
||||
isLoading: false,
|
||||
onLoadedCallbacks: []
|
||||
onLoadedCallbacks: [],
|
||||
onErrorCallbacks: [],
|
||||
};
|
||||
|
||||
export const loadPaypalScript = (config, onLoaded) => {
|
||||
export const loadPaypalScript = (config, onLoaded, onError = null) => {
|
||||
// If PayPal is already loaded call the onLoaded callback and return.
|
||||
if (typeof paypal !== 'undefined') {
|
||||
onLoaded();
|
||||
|
@ -19,6 +20,9 @@ export const loadPaypalScript = (config, onLoaded) => {
|
|||
|
||||
// Add the onLoaded callback to the onLoadedCallbacks stack.
|
||||
options.onLoadedCallbacks.push(onLoaded);
|
||||
if (onError) {
|
||||
options.onErrorCallbacks.push(onError);
|
||||
}
|
||||
|
||||
// Return if it's still loading.
|
||||
if (options.isLoading) {
|
||||
|
@ -26,6 +30,12 @@ export const loadPaypalScript = (config, onLoaded) => {
|
|||
}
|
||||
options.isLoading = true;
|
||||
|
||||
const resetState = () => {
|
||||
options.isLoading = false;
|
||||
options.onLoadedCallbacks = [];
|
||||
options.onErrorCallbacks = [];
|
||||
}
|
||||
|
||||
// Callback to be called once the PayPal script is loaded.
|
||||
const callback = (paypal) => {
|
||||
widgetBuilder.setPaypal(paypal);
|
||||
|
@ -34,8 +44,14 @@ export const loadPaypalScript = (config, onLoaded) => {
|
|||
onLoadedCallback();
|
||||
}
|
||||
|
||||
options.isLoading = false;
|
||||
options.onLoadedCallbacks = [];
|
||||
resetState();
|
||||
}
|
||||
const errorCallback = (err) => {
|
||||
for (const onErrorCallback of options.onErrorCallbacks) {
|
||||
onErrorCallback(err);
|
||||
}
|
||||
|
||||
resetState();
|
||||
}
|
||||
|
||||
// Build the PayPal script options.
|
||||
|
@ -44,7 +60,7 @@ export const loadPaypalScript = (config, onLoaded) => {
|
|||
|
||||
// Load PayPal script for special case with data-client-token
|
||||
if (config.data_client_id.set_attribute) {
|
||||
dataClientIdAttributeHandler(scriptOptions, config.data_client_id, callback);
|
||||
dataClientIdAttributeHandler(scriptOptions, config.data_client_id, callback, errorCallback);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -54,8 +70,16 @@ export const loadPaypalScript = (config, onLoaded) => {
|
|||
scriptOptions['data-user-id-token'] = userIdToken;
|
||||
}
|
||||
|
||||
// Load PayPal script.
|
||||
loadScript(scriptOptions).then(callback);
|
||||
// Load PayPal script
|
||||
loadScript(scriptOptions)
|
||||
.then(callback)
|
||||
.catch(errorCallback);
|
||||
}
|
||||
|
||||
export const loadPaypalScriptPromise = (config) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
loadPaypalScript(config, resolve, reject)
|
||||
});
|
||||
}
|
||||
|
||||
export const loadPaypalJsScript = (options, buttons, container) => {
|
||||
|
|
20
modules/ppcp-button/resources/js/modules/Helper/Style.js
Normal file
20
modules/ppcp-button/resources/js/modules/Helper/Style.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
export const normalizeStyleForFundingSource = (style, fundingSource) => {
|
||||
const commonProps = {};
|
||||
['shape', 'height'].forEach(prop => {
|
||||
if (style[prop]) {
|
||||
commonProps[prop] = style[prop];
|
||||
}
|
||||
});
|
||||
|
||||
switch (fundingSource) {
|
||||
case 'paypal':
|
||||
return style;
|
||||
case 'paylater':
|
||||
return {
|
||||
color: style.color,
|
||||
...commonProps
|
||||
};
|
||||
default:
|
||||
return commonProps;
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ import merge from "deepmerge";
|
|||
import {loadScript} from "@paypal/paypal-js";
|
||||
import {keysToCamelCase} from "../Helper/Utils";
|
||||
import widgetBuilder from "./WidgetBuilder";
|
||||
import {normalizeStyleForFundingSource} from "../Helper/Style";
|
||||
|
||||
class Renderer {
|
||||
constructor(creditCardRenderer, defaultSettings, onSmartButtonClick, onSmartButtonsInit) {
|
||||
|
@ -36,16 +37,7 @@ class Renderer {
|
|||
} else {
|
||||
// render each button separately
|
||||
for (const fundingSource of paypal.getFundingSources().filter(s => !(s in enabledSeparateGateways))) {
|
||||
let style = settings.button.style;
|
||||
if (fundingSource !== 'paypal') {
|
||||
style = {
|
||||
shape: style.shape,
|
||||
color: style.color,
|
||||
};
|
||||
if (fundingSource !== 'paylater') {
|
||||
delete style.color;
|
||||
}
|
||||
}
|
||||
const style = normalizeStyleForFundingSource(settings.button.style, fundingSource);
|
||||
|
||||
this.renderButtons(
|
||||
settings.button.wrapper,
|
||||
|
|
|
@ -1049,30 +1049,39 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
'mini_cart_wrapper' => '#ppc-button-minicart',
|
||||
'is_mini_cart_disabled' => $this->is_button_disabled( 'mini-cart' ),
|
||||
'cancel_wrapper' => '#ppcp-cancel',
|
||||
'mini_cart_style' => array(
|
||||
'layout' => $this->style_for_context( 'layout', 'mini-cart' ),
|
||||
'color' => $this->style_for_context( 'color', 'mini-cart' ),
|
||||
'shape' => $this->style_for_context( 'shape', 'mini-cart' ),
|
||||
'label' => $this->style_for_context( 'label', 'mini-cart' ),
|
||||
'tagline' => $this->style_for_context( 'tagline', 'mini-cart' ),
|
||||
'height' => $this->settings->has( 'button_mini-cart_height' ) && $this->settings->get( 'button_mini-cart_height' ) ? $this->normalize_height( (int) $this->settings->get( 'button_mini-cart_height' ) ) : 35,
|
||||
'mini_cart_style' => $this->normalize_style(
|
||||
array(
|
||||
'layout' => $this->style_for_context( 'layout', 'mini-cart' ),
|
||||
'color' => $this->style_for_context( 'color', 'mini-cart' ),
|
||||
'shape' => $this->style_for_context( 'shape', 'mini-cart' ),
|
||||
'label' => $this->style_for_context( 'label', 'mini-cart' ),
|
||||
'tagline' => $this->style_for_context( 'tagline', 'mini-cart' ),
|
||||
'height' => $this->normalize_height( $this->style_for_context( 'height', 'mini-cart', 35 ), 25, 55 ),
|
||||
)
|
||||
),
|
||||
'style' => array(
|
||||
'layout' => $this->style_for_context( 'layout', $this->context() ),
|
||||
'color' => $this->style_for_context( 'color', $this->context() ),
|
||||
'shape' => $this->style_for_context( 'shape', $this->context() ),
|
||||
'label' => $this->style_for_context( 'label', $this->context() ),
|
||||
'tagline' => $this->style_for_context( 'tagline', $this->context() ),
|
||||
'style' => $this->normalize_style(
|
||||
array(
|
||||
'layout' => $this->style_for_context( 'layout', $this->context() ),
|
||||
'color' => $this->style_for_context( 'color', $this->context() ),
|
||||
'shape' => $this->style_for_context( 'shape', $this->context() ),
|
||||
'label' => $this->style_for_context( 'label', $this->context() ),
|
||||
'tagline' => $this->style_for_context( 'tagline', $this->context() ),
|
||||
'height' => in_array( $this->context(), array( 'cart-block', 'checkout-block' ), true )
|
||||
? $this->normalize_height( $this->style_for_context( 'height', $this->context(), 48 ), 40, 55 )
|
||||
: null,
|
||||
)
|
||||
),
|
||||
),
|
||||
'separate_buttons' => array(
|
||||
'card' => array(
|
||||
'id' => CardButtonGateway::ID,
|
||||
'wrapper' => '#ppc-button-' . CardButtonGateway::ID,
|
||||
'style' => array(
|
||||
'shape' => $this->style_for_apm( 'shape', 'card' ),
|
||||
'color' => $this->style_for_apm( 'color', 'card', 'black' ),
|
||||
'layout' => $this->style_for_apm( 'poweredby_tagline', 'card', false ) === $this->normalize_style_value( true ) ? 'vertical' : 'horizontal',
|
||||
'style' => $this->normalize_style(
|
||||
array(
|
||||
'shape' => $this->style_for_apm( 'shape', 'card' ),
|
||||
'color' => $this->style_for_apm( 'color', 'card', 'black' ),
|
||||
'layout' => $this->style_for_apm( 'poweredby_tagline', 'card', false ) === $this->normalize_style_value( true ) ? 'vertical' : 'horizontal',
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -1143,13 +1152,6 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
$localize['pay_now'] = $this->pay_now_script_data();
|
||||
}
|
||||
|
||||
if ( $this->style_for_context( 'layout', 'mini-cart' ) !== 'horizontal' ) {
|
||||
$localize['button']['mini_cart_style']['tagline'] = false;
|
||||
}
|
||||
if ( $this->style_for_context( 'layout', $this->context() ) !== 'horizontal' ) {
|
||||
$localize['button']['style']['tagline'] = false;
|
||||
}
|
||||
|
||||
if ( $this->is_paypal_continuation() ) {
|
||||
$order = $this->session_handler->order();
|
||||
assert( $order !== null );
|
||||
|
@ -1411,12 +1413,14 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
*
|
||||
* @param string $style The name of the style property.
|
||||
* @param string $context The context.
|
||||
* @param ?mixed $default The default value.
|
||||
*
|
||||
* @return string
|
||||
* @return string|int
|
||||
*/
|
||||
private function style_for_context( string $style, string $context ): string {
|
||||
// Use the cart/checkout styles for blocks.
|
||||
$context = str_replace( '-block', '', $context );
|
||||
private function style_for_context( string $style, string $context, $default = null ) {
|
||||
if ( $context === 'checkout-block' ) {
|
||||
$context = 'checkout-block-express';
|
||||
}
|
||||
|
||||
$defaults = array(
|
||||
'layout' => 'vertical',
|
||||
|
@ -1434,6 +1438,7 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
|
||||
return $this->get_style_value( "button_{$context}_${style}" )
|
||||
?? $this->get_style_value( "button_${style}" )
|
||||
?? ( $default ? $this->normalize_style_value( $default ) : null )
|
||||
?? $this->normalize_style_value( $defaults[ $style ] ?? '' );
|
||||
}
|
||||
|
||||
|
@ -1444,9 +1449,9 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
* @param string $apm The APM name, such as 'card'.
|
||||
* @param ?mixed $default The default value.
|
||||
*
|
||||
* @return string
|
||||
* @return string|int
|
||||
*/
|
||||
private function style_for_apm( string $style, string $apm, $default = null ): string {
|
||||
private function style_for_apm( string $style, string $apm, $default = null ) {
|
||||
return $this->get_style_value( "${apm}_button_${style}" )
|
||||
?? ( $default ? $this->normalize_style_value( $default ) : null )
|
||||
?? $this->style_for_context( $style, 'checkout' );
|
||||
|
@ -1456,9 +1461,9 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
* Returns the style property value or null.
|
||||
*
|
||||
* @param string $key The style property key in the settings.
|
||||
* @return string|null
|
||||
* @return string|int|null
|
||||
*/
|
||||
private function get_style_value( string $key ): ?string {
|
||||
private function get_style_value( string $key ) {
|
||||
if ( ! $this->settings->has( $key ) ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1469,27 +1474,49 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
* Converts the style property value to string.
|
||||
*
|
||||
* @param mixed $value The style property value.
|
||||
* @return string
|
||||
* @return string|int
|
||||
*/
|
||||
private function normalize_style_value( $value ): string {
|
||||
private function normalize_style_value( $value ) {
|
||||
if ( is_bool( $value ) ) {
|
||||
$value = $value ? 'true' : 'false';
|
||||
}
|
||||
if ( is_int( $value ) ) {
|
||||
return $value;
|
||||
}
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value between 25 and 55.
|
||||
* Fixes the style.
|
||||
*
|
||||
* @param int $height The input value.
|
||||
* @param array $style The style properties.
|
||||
* @return array
|
||||
*/
|
||||
private function normalize_style( array $style ): array {
|
||||
if ( array_key_exists( 'tagline', $style ) && ( ! array_key_exists( 'layout', $style ) || $style['layout'] !== 'horizontal' ) ) {
|
||||
$style['tagline'] = false;
|
||||
}
|
||||
if ( array_key_exists( 'height', $style ) && ! $style['height'] ) {
|
||||
unset( $style['height'] );
|
||||
}
|
||||
return $style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a number between min and max.
|
||||
*
|
||||
* @param mixed $height The input value.
|
||||
* @param int $min The minimum value.
|
||||
* @param int $max The maximum value.
|
||||
* @return int The normalized output value.
|
||||
*/
|
||||
private function normalize_height( int $height ): int {
|
||||
if ( $height < 25 ) {
|
||||
return 25;
|
||||
private function normalize_height( $height, int $min, int $max ): int {
|
||||
$height = (int) $height;
|
||||
if ( $height < $min ) {
|
||||
return $min;
|
||||
}
|
||||
if ( $height > 55 ) {
|
||||
return 55;
|
||||
if ( $height > $max ) {
|
||||
return $max;
|
||||
}
|
||||
|
||||
return $height;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue