forked from mirrors/gecko-dev
		
	# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D35950 --HG-- extra : source : ff6aa88097df9836d93d6aa5554ffcd160f07167 extra : intermediate-source : 2130a9484ece03d835939359c4a07966aa8d790c
		
			
				
	
	
		
			593 lines
		
	
	
	
		
			20 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			593 lines
		
	
	
	
		
			20 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
import HandleEventMixin from "../mixins/HandleEventMixin.js";
 | 
						|
import PaymentStateSubscriberMixin from "../mixins/PaymentStateSubscriberMixin.js";
 | 
						|
import paymentRequest from "../paymentRequest.js";
 | 
						|
 | 
						|
import "../components/currency-amount.js";
 | 
						|
import "../components/payment-request-page.js";
 | 
						|
import "../components/accepted-cards.js";
 | 
						|
import "./address-picker.js";
 | 
						|
import "./address-form.js";
 | 
						|
import "./basic-card-form.js";
 | 
						|
import "./completion-error-page.js";
 | 
						|
import "./order-details.js";
 | 
						|
import "./payment-method-picker.js";
 | 
						|
import "./shipping-option-picker.js";
 | 
						|
 | 
						|
/* import-globals-from ../unprivileged-fallbacks.js */
 | 
						|
 | 
						|
/**
 | 
						|
 * <payment-dialog></payment-dialog>
 | 
						|
 *
 | 
						|
 * Warning: Do not import this module from any other module as it will import
 | 
						|
 * everything else (see above) and ruin element independence. This can stop
 | 
						|
 * being exported once tests stop depending on it.
 | 
						|
 */
 | 
						|
 | 
						|
export default class PaymentDialog extends HandleEventMixin(
 | 
						|
  PaymentStateSubscriberMixin(HTMLElement)
 | 
						|
) {
 | 
						|
  constructor() {
 | 
						|
    super();
 | 
						|
    this._template = document.getElementById("payment-dialog-template");
 | 
						|
    this._cachedState = {};
 | 
						|
  }
 | 
						|
 | 
						|
  connectedCallback() {
 | 
						|
    let contents = document.importNode(this._template.content, true);
 | 
						|
    this._hostNameEl = contents.querySelector("#host-name");
 | 
						|
 | 
						|
    this._cancelButton = contents.querySelector("#cancel");
 | 
						|
    this._cancelButton.addEventListener("click", this.cancelRequest);
 | 
						|
 | 
						|
    this._payButton = contents.querySelector("#pay");
 | 
						|
    this._payButton.addEventListener("click", this);
 | 
						|
 | 
						|
    this._viewAllButton = contents.querySelector("#view-all");
 | 
						|
    this._viewAllButton.addEventListener("click", this);
 | 
						|
 | 
						|
    this._mainContainer = contents.getElementById("main-container");
 | 
						|
    this._orderDetailsOverlay = contents.querySelector(
 | 
						|
      "#order-details-overlay"
 | 
						|
    );
 | 
						|
 | 
						|
    this._shippingAddressPicker = contents.querySelector(
 | 
						|
      "address-picker.shipping-related"
 | 
						|
    );
 | 
						|
    this._shippingOptionPicker = contents.querySelector(
 | 
						|
      "shipping-option-picker"
 | 
						|
    );
 | 
						|
    this._shippingRelatedEls = contents.querySelectorAll(".shipping-related");
 | 
						|
    this._payerRelatedEls = contents.querySelectorAll(".payer-related");
 | 
						|
    this._payerAddressPicker = contents.querySelector(
 | 
						|
      "address-picker.payer-related"
 | 
						|
    );
 | 
						|
    this._paymentMethodPicker = contents.querySelector("payment-method-picker");
 | 
						|
    this._acceptedCardsList = contents.querySelector("accepted-cards");
 | 
						|
    this._manageText = contents.querySelector(".manage-text");
 | 
						|
    this._manageText.addEventListener("click", this);
 | 
						|
 | 
						|
    this._header = contents.querySelector("header");
 | 
						|
 | 
						|
    this._errorText = contents.querySelector("header > .page-error");
 | 
						|
 | 
						|
    this._disabledOverlay = contents.getElementById("disabled-overlay");
 | 
						|
 | 
						|
    this.appendChild(contents);
 | 
						|
 | 
						|
    super.connectedCallback();
 | 
						|
  }
 | 
						|
 | 
						|
  disconnectedCallback() {
 | 
						|
    this._cancelButton.removeEventListener("click", this.cancelRequest);
 | 
						|
    this._payButton.removeEventListener("click", this.pay);
 | 
						|
    this._viewAllButton.removeEventListener("click", this);
 | 
						|
    super.disconnectedCallback();
 | 
						|
  }
 | 
						|
 | 
						|
  onClick(event) {
 | 
						|
    switch (event.currentTarget) {
 | 
						|
      case this._viewAllButton:
 | 
						|
        let orderDetailsShowing = !this.requestStore.getState()
 | 
						|
          .orderDetailsShowing;
 | 
						|
        this.requestStore.setState({ orderDetailsShowing });
 | 
						|
        break;
 | 
						|
      case this._payButton:
 | 
						|
        this.pay();
 | 
						|
        break;
 | 
						|
      case this._manageText:
 | 
						|
        if (event.target instanceof HTMLAnchorElement) {
 | 
						|
          this.openPreferences(event);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  openPreferences(event) {
 | 
						|
    paymentRequest.openPreferences();
 | 
						|
    event.preventDefault();
 | 
						|
  }
 | 
						|
 | 
						|
  cancelRequest() {
 | 
						|
    paymentRequest.cancel();
 | 
						|
  }
 | 
						|
 | 
						|
  pay() {
 | 
						|
    let state = this.requestStore.getState();
 | 
						|
    let {
 | 
						|
      selectedPayerAddress,
 | 
						|
      selectedPaymentCard,
 | 
						|
      selectedPaymentCardSecurityCode,
 | 
						|
      selectedShippingAddress,
 | 
						|
    } = state;
 | 
						|
 | 
						|
    let data = {
 | 
						|
      selectedPaymentCardGUID: selectedPaymentCard,
 | 
						|
      selectedPaymentCardSecurityCode,
 | 
						|
    };
 | 
						|
 | 
						|
    data.selectedShippingAddressGUID = state.request.paymentOptions
 | 
						|
      .requestShipping
 | 
						|
      ? selectedShippingAddress
 | 
						|
      : null;
 | 
						|
 | 
						|
    data.selectedPayerAddressGUID = this._isPayerRequested(
 | 
						|
      state.request.paymentOptions
 | 
						|
    )
 | 
						|
      ? selectedPayerAddress
 | 
						|
      : null;
 | 
						|
 | 
						|
    paymentRequest.pay(data);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Called when the selectedShippingAddress or its properties are changed.
 | 
						|
   * @param {string} shippingAddressGUID
 | 
						|
   */
 | 
						|
  changeShippingAddress(shippingAddressGUID) {
 | 
						|
    // Clear shipping address merchant errors when the shipping address changes.
 | 
						|
    let request = Object.assign({}, this.requestStore.getState().request);
 | 
						|
    request.paymentDetails = Object.assign({}, request.paymentDetails);
 | 
						|
    request.paymentDetails.shippingAddressErrors = {};
 | 
						|
    this.requestStore.setState({ request });
 | 
						|
 | 
						|
    paymentRequest.changeShippingAddress({
 | 
						|
      shippingAddressGUID,
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  changeShippingOption(optionID) {
 | 
						|
    paymentRequest.changeShippingOption({
 | 
						|
      optionID,
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Called when the selectedPaymentCard or its relevant properties or billingAddress are changed.
 | 
						|
   * @param {string} selectedPaymentCardBillingAddressGUID
 | 
						|
   */
 | 
						|
  changePaymentMethod(selectedPaymentCardBillingAddressGUID) {
 | 
						|
    // Clear paymentMethod merchant errors when the paymentMethod or billingAddress changes.
 | 
						|
    let request = Object.assign({}, this.requestStore.getState().request);
 | 
						|
    request.paymentDetails = Object.assign({}, request.paymentDetails);
 | 
						|
    request.paymentDetails.paymentMethodErrors = null;
 | 
						|
    this.requestStore.setState({ request });
 | 
						|
 | 
						|
    paymentRequest.changePaymentMethod({
 | 
						|
      selectedPaymentCardBillingAddressGUID,
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Called when the selectedPayerAddress or its relevant properties are changed.
 | 
						|
   * @param {string} payerAddressGUID
 | 
						|
   */
 | 
						|
  changePayerAddress(payerAddressGUID) {
 | 
						|
    // Clear payer address merchant errors when the payer address changes.
 | 
						|
    let request = Object.assign({}, this.requestStore.getState().request);
 | 
						|
    request.paymentDetails = Object.assign({}, request.paymentDetails);
 | 
						|
    request.paymentDetails.payerErrors = {};
 | 
						|
    this.requestStore.setState({ request });
 | 
						|
 | 
						|
    paymentRequest.changePayerAddress({
 | 
						|
      payerAddressGUID,
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  _isPayerRequested(paymentOptions) {
 | 
						|
    return (
 | 
						|
      paymentOptions.requestPayerName ||
 | 
						|
      paymentOptions.requestPayerEmail ||
 | 
						|
      paymentOptions.requestPayerPhone
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  _getAdditionalDisplayItems(state) {
 | 
						|
    let methodId = state.selectedPaymentCard;
 | 
						|
    let modifier = paymentRequest.getModifierForPaymentMethod(state, methodId);
 | 
						|
    if (modifier && modifier.additionalDisplayItems) {
 | 
						|
      return modifier.additionalDisplayItems;
 | 
						|
    }
 | 
						|
    return [];
 | 
						|
  }
 | 
						|
 | 
						|
  _updateCompleteStatus(state) {
 | 
						|
    let { completeStatus } = state.request;
 | 
						|
    switch (completeStatus) {
 | 
						|
      case "fail":
 | 
						|
      case "timeout":
 | 
						|
      case "unknown":
 | 
						|
        state.page = {
 | 
						|
          id: `completion-${completeStatus}-error`,
 | 
						|
        };
 | 
						|
        state.changesPrevented = false;
 | 
						|
        break;
 | 
						|
      case "": {
 | 
						|
        // When we get a DOM update for an updateWith() or retry() the completeStatus
 | 
						|
        // is "" when we need to show non-final screens. Don't set the page as we
 | 
						|
        // may be on a form instead of payment-summary
 | 
						|
        state.changesPrevented = false;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return state;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set some state from the privileged parent process.
 | 
						|
   * Other elements that need to set state should use their own `this.requestStore.setState`
 | 
						|
   * method provided by the `PaymentStateSubscriberMixin`.
 | 
						|
   *
 | 
						|
   * @param {object} state - See `PaymentsStore.setState`
 | 
						|
   */
 | 
						|
  // eslint-disable-next-line complexity
 | 
						|
  async setStateFromParent(state) {
 | 
						|
    let oldAddresses = paymentRequest.getAddresses(
 | 
						|
      this.requestStore.getState()
 | 
						|
    );
 | 
						|
    let oldBasicCards = paymentRequest.getBasicCards(
 | 
						|
      this.requestStore.getState()
 | 
						|
    );
 | 
						|
    if (state.request) {
 | 
						|
      state = this._updateCompleteStatus(state);
 | 
						|
    }
 | 
						|
    this.requestStore.setState(state);
 | 
						|
 | 
						|
    // Check if any foreign-key constraints were invalidated.
 | 
						|
    state = this.requestStore.getState();
 | 
						|
    let {
 | 
						|
      selectedPayerAddress,
 | 
						|
      selectedPaymentCard,
 | 
						|
      selectedShippingAddress,
 | 
						|
      selectedShippingOption,
 | 
						|
    } = state;
 | 
						|
    let addresses = paymentRequest.getAddresses(state);
 | 
						|
    let { paymentOptions } = state.request;
 | 
						|
 | 
						|
    if (paymentOptions.requestShipping) {
 | 
						|
      let shippingOptions = state.request.paymentDetails.shippingOptions;
 | 
						|
      let shippingAddress =
 | 
						|
        selectedShippingAddress && addresses[selectedShippingAddress];
 | 
						|
      let oldShippingAddress =
 | 
						|
        selectedShippingAddress && oldAddresses[selectedShippingAddress];
 | 
						|
 | 
						|
      // Ensure `selectedShippingAddress` never refers to a deleted address.
 | 
						|
      // We also compare address timestamps to notify about changes
 | 
						|
      // made outside the payments UI.
 | 
						|
      if (shippingAddress) {
 | 
						|
        // invalidate the cached value if the address was modified
 | 
						|
        if (
 | 
						|
          oldShippingAddress &&
 | 
						|
          shippingAddress.guid == oldShippingAddress.guid &&
 | 
						|
          shippingAddress.timeLastModified !=
 | 
						|
            oldShippingAddress.timeLastModified
 | 
						|
        ) {
 | 
						|
          delete this._cachedState.selectedShippingAddress;
 | 
						|
        }
 | 
						|
      } else if (selectedShippingAddress !== null) {
 | 
						|
        // null out the `selectedShippingAddress` property if it is undefined,
 | 
						|
        // or if the address it pointed to was removed from storage.
 | 
						|
        log.debug("resetting invalid/deleted shipping address");
 | 
						|
        this.requestStore.setState({
 | 
						|
          selectedShippingAddress: null,
 | 
						|
        });
 | 
						|
      }
 | 
						|
 | 
						|
      // Ensure `selectedShippingOption` never refers to a deleted shipping option and
 | 
						|
      // matches the merchant's selected option if the user hasn't made a choice.
 | 
						|
      if (
 | 
						|
        shippingOptions &&
 | 
						|
        (!selectedShippingOption ||
 | 
						|
          !shippingOptions.find(opt => opt.id == selectedShippingOption))
 | 
						|
      ) {
 | 
						|
        this._cachedState.selectedShippingOption = selectedShippingOption;
 | 
						|
        this.requestStore.setState({
 | 
						|
          // Use the DOM's computed selected shipping option:
 | 
						|
          selectedShippingOption: state.request.shippingOption,
 | 
						|
        });
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    let basicCards = paymentRequest.getBasicCards(state);
 | 
						|
    let oldPaymentMethod =
 | 
						|
      selectedPaymentCard && oldBasicCards[selectedPaymentCard];
 | 
						|
    let paymentMethod = selectedPaymentCard && basicCards[selectedPaymentCard];
 | 
						|
    if (
 | 
						|
      oldPaymentMethod &&
 | 
						|
      paymentMethod.guid == oldPaymentMethod.guid &&
 | 
						|
      paymentMethod.timeLastModified != oldPaymentMethod.timeLastModified
 | 
						|
    ) {
 | 
						|
      delete this._cachedState.selectedPaymentCard;
 | 
						|
    } else {
 | 
						|
      // Changes to the billing address record don't change the `timeLastModified`
 | 
						|
      // on the card record so we have to check for changes to the address separately.
 | 
						|
 | 
						|
      let billingAddressGUID =
 | 
						|
        paymentMethod && paymentMethod.billingAddressGUID;
 | 
						|
      let billingAddress = billingAddressGUID && addresses[billingAddressGUID];
 | 
						|
      let oldBillingAddress =
 | 
						|
        billingAddressGUID && oldAddresses[billingAddressGUID];
 | 
						|
 | 
						|
      if (
 | 
						|
        oldBillingAddress &&
 | 
						|
        billingAddress &&
 | 
						|
        billingAddress.timeLastModified != oldBillingAddress.timeLastModified
 | 
						|
      ) {
 | 
						|
        delete this._cachedState.selectedPaymentCard;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    // Ensure `selectedPaymentCard` never refers to a deleted payment card.
 | 
						|
    if (selectedPaymentCard && !basicCards[selectedPaymentCard]) {
 | 
						|
      this.requestStore.setState({
 | 
						|
        selectedPaymentCard: null,
 | 
						|
        selectedPaymentCardSecurityCode: null,
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    if (this._isPayerRequested(state.request.paymentOptions)) {
 | 
						|
      let payerAddress =
 | 
						|
        selectedPayerAddress && addresses[selectedPayerAddress];
 | 
						|
      let oldPayerAddress =
 | 
						|
        selectedPayerAddress && oldAddresses[selectedPayerAddress];
 | 
						|
 | 
						|
      if (
 | 
						|
        oldPayerAddress &&
 | 
						|
        payerAddress &&
 | 
						|
        ((paymentOptions.requestPayerName &&
 | 
						|
          payerAddress.name != oldPayerAddress.name) ||
 | 
						|
          (paymentOptions.requestPayerEmail &&
 | 
						|
            payerAddress.email != oldPayerAddress.email) ||
 | 
						|
          (paymentOptions.requestPayerPhone &&
 | 
						|
            payerAddress.tel != oldPayerAddress.tel))
 | 
						|
      ) {
 | 
						|
        // invalidate the cached value if the payer address fields were modified
 | 
						|
        delete this._cachedState.selectedPayerAddress;
 | 
						|
      }
 | 
						|
 | 
						|
      // Ensure `selectedPayerAddress` never refers to a deleted address and refers
 | 
						|
      // to an address if one exists.
 | 
						|
      if (!addresses[selectedPayerAddress]) {
 | 
						|
        this.requestStore.setState({
 | 
						|
          selectedPayerAddress: Object.keys(addresses)[0] || null,
 | 
						|
        });
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  _renderPayButton(state) {
 | 
						|
    let completeStatus = state.request.completeStatus;
 | 
						|
    switch (completeStatus) {
 | 
						|
      case "processing":
 | 
						|
      case "success":
 | 
						|
      case "unknown": {
 | 
						|
        this._payButton.disabled = true;
 | 
						|
        this._payButton.textContent = this._payButton.dataset[
 | 
						|
          completeStatus + "Label"
 | 
						|
        ];
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      case "": {
 | 
						|
        // initial/default state
 | 
						|
        this._payButton.textContent = this._payButton.dataset.label;
 | 
						|
        const INVALID_CLASS_NAME = "invalid-selected-option";
 | 
						|
        this._payButton.disabled =
 | 
						|
          (state.request.paymentOptions.requestShipping &&
 | 
						|
            (!this._shippingAddressPicker.selectedOption ||
 | 
						|
              this._shippingAddressPicker.classList.contains(
 | 
						|
                INVALID_CLASS_NAME
 | 
						|
              ) ||
 | 
						|
              !this._shippingOptionPicker.selectedOption)) ||
 | 
						|
          (this._isPayerRequested(state.request.paymentOptions) &&
 | 
						|
            (!this._payerAddressPicker.selectedOption ||
 | 
						|
              this._payerAddressPicker.classList.contains(
 | 
						|
                INVALID_CLASS_NAME
 | 
						|
              ))) ||
 | 
						|
          !this._paymentMethodPicker.securityCodeInput.isValid ||
 | 
						|
          !this._paymentMethodPicker.selectedOption ||
 | 
						|
          this._paymentMethodPicker.classList.contains(INVALID_CLASS_NAME) ||
 | 
						|
          state.changesPrevented;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      case "fail":
 | 
						|
      case "timeout": {
 | 
						|
        // pay button is hidden in fail/timeout states.
 | 
						|
        this._payButton.textContent = this._payButton.dataset.label;
 | 
						|
        this._payButton.disabled = true;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      default: {
 | 
						|
        throw new Error(`Invalid completeStatus: ${completeStatus}`);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  _renderPayerFields(state) {
 | 
						|
    let paymentOptions = state.request.paymentOptions;
 | 
						|
    let payerRequested = this._isPayerRequested(paymentOptions);
 | 
						|
    let payerAddressForm = this.querySelector(
 | 
						|
      "address-form[selected-state-key='selectedPayerAddress']"
 | 
						|
    );
 | 
						|
 | 
						|
    for (let element of this._payerRelatedEls) {
 | 
						|
      element.hidden = !payerRequested;
 | 
						|
    }
 | 
						|
 | 
						|
    if (payerRequested) {
 | 
						|
      let fieldNames = new Set();
 | 
						|
      if (paymentOptions.requestPayerName) {
 | 
						|
        fieldNames.add("name");
 | 
						|
      }
 | 
						|
      if (paymentOptions.requestPayerEmail) {
 | 
						|
        fieldNames.add("email");
 | 
						|
      }
 | 
						|
      if (paymentOptions.requestPayerPhone) {
 | 
						|
        fieldNames.add("tel");
 | 
						|
      }
 | 
						|
      let addressFields = [...fieldNames].join(" ");
 | 
						|
      this._payerAddressPicker.setAttribute("address-fields", addressFields);
 | 
						|
      if (payerAddressForm.form) {
 | 
						|
        payerAddressForm.form.dataset.extraRequiredFields = addressFields;
 | 
						|
      }
 | 
						|
 | 
						|
      // For the payer picker we want to have a line break after the name field (#1)
 | 
						|
      // if all three fields are requested.
 | 
						|
      if (fieldNames.size == 3) {
 | 
						|
        this._payerAddressPicker.setAttribute("break-after-nth-field", 1);
 | 
						|
      } else {
 | 
						|
        this._payerAddressPicker.removeAttribute("break-after-nth-field");
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      this._payerAddressPicker.removeAttribute("address-fields");
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  stateChangeCallback(state) {
 | 
						|
    super.stateChangeCallback(state);
 | 
						|
 | 
						|
    // Don't dispatch change events for initial selectedShipping* changes at initialization
 | 
						|
    // if requestShipping is false.
 | 
						|
    if (state.request.paymentOptions.requestShipping) {
 | 
						|
      if (
 | 
						|
        state.selectedShippingAddress !=
 | 
						|
        this._cachedState.selectedShippingAddress
 | 
						|
      ) {
 | 
						|
        this.changeShippingAddress(state.selectedShippingAddress);
 | 
						|
      }
 | 
						|
 | 
						|
      if (
 | 
						|
        state.selectedShippingOption != this._cachedState.selectedShippingOption
 | 
						|
      ) {
 | 
						|
        this.changeShippingOption(state.selectedShippingOption);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    let selectedPaymentCard = state.selectedPaymentCard;
 | 
						|
    let basicCards = paymentRequest.getBasicCards(state);
 | 
						|
    let billingAddressGUID = (basicCards[selectedPaymentCard] || {})
 | 
						|
      .billingAddressGUID;
 | 
						|
    if (
 | 
						|
      selectedPaymentCard != this._cachedState.selectedPaymentCard &&
 | 
						|
      billingAddressGUID
 | 
						|
    ) {
 | 
						|
      // Update _cachedState to prevent an infinite loop when changePaymentMethod updates state.
 | 
						|
      this._cachedState.selectedPaymentCard = state.selectedPaymentCard;
 | 
						|
      this.changePaymentMethod(billingAddressGUID);
 | 
						|
    }
 | 
						|
 | 
						|
    if (this._isPayerRequested(state.request.paymentOptions)) {
 | 
						|
      if (
 | 
						|
        state.selectedPayerAddress != this._cachedState.selectedPayerAddress
 | 
						|
      ) {
 | 
						|
        this.changePayerAddress(state.selectedPayerAddress);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    this._cachedState.selectedShippingAddress = state.selectedShippingAddress;
 | 
						|
    this._cachedState.selectedShippingOption = state.selectedShippingOption;
 | 
						|
    this._cachedState.selectedPayerAddress = state.selectedPayerAddress;
 | 
						|
  }
 | 
						|
 | 
						|
  render(state) {
 | 
						|
    let request = state.request;
 | 
						|
    let paymentDetails = request.paymentDetails;
 | 
						|
    this._hostNameEl.textContent = request.topLevelPrincipal.URI.displayHost;
 | 
						|
 | 
						|
    let displayItems = request.paymentDetails.displayItems || [];
 | 
						|
    let additionalItems = this._getAdditionalDisplayItems(state);
 | 
						|
    this._viewAllButton.hidden =
 | 
						|
      !displayItems.length && !additionalItems.length;
 | 
						|
 | 
						|
    let shippingType = state.request.paymentOptions.shippingType || "shipping";
 | 
						|
    let addressPickerLabel = this._shippingAddressPicker.dataset[
 | 
						|
      shippingType + "AddressLabel"
 | 
						|
    ];
 | 
						|
    this._shippingAddressPicker.setAttribute("label", addressPickerLabel);
 | 
						|
    let optionPickerLabel = this._shippingOptionPicker.dataset[
 | 
						|
      shippingType + "OptionsLabel"
 | 
						|
    ];
 | 
						|
    this._shippingOptionPicker.setAttribute("label", optionPickerLabel);
 | 
						|
 | 
						|
    let shippingAddressForm = this.querySelector(
 | 
						|
      "address-form[selected-state-key='selectedShippingAddress']"
 | 
						|
    );
 | 
						|
    shippingAddressForm.dataset.titleAdd = this.dataset[
 | 
						|
      shippingType + "AddressTitleAdd"
 | 
						|
    ];
 | 
						|
    shippingAddressForm.dataset.titleEdit = this.dataset[
 | 
						|
      shippingType + "AddressTitleEdit"
 | 
						|
    ];
 | 
						|
 | 
						|
    let totalItem = paymentRequest.getTotalItem(state);
 | 
						|
    let totalAmountEl = this.querySelector("#total > currency-amount");
 | 
						|
    totalAmountEl.value = totalItem.amount.value;
 | 
						|
    totalAmountEl.currency = totalItem.amount.currency;
 | 
						|
 | 
						|
    // Show the total header on the address and basic card pages only during
 | 
						|
    // on-boarding(FTU) and on the payment summary page.
 | 
						|
    this._header.hidden =
 | 
						|
      !state.page.onboardingWizard && state.page.id != "payment-summary";
 | 
						|
 | 
						|
    this._orderDetailsOverlay.hidden = !state.orderDetailsShowing;
 | 
						|
    let genericError = "";
 | 
						|
    if (
 | 
						|
      this._shippingAddressPicker.selectedOption &&
 | 
						|
      (!request.paymentDetails.shippingOptions ||
 | 
						|
        !request.paymentDetails.shippingOptions.length)
 | 
						|
    ) {
 | 
						|
      genericError = this._errorText.dataset[shippingType + "GenericError"];
 | 
						|
    }
 | 
						|
    this._errorText.textContent = paymentDetails.error || genericError;
 | 
						|
 | 
						|
    let paymentOptions = request.paymentOptions;
 | 
						|
    for (let element of this._shippingRelatedEls) {
 | 
						|
      element.hidden = !paymentOptions.requestShipping;
 | 
						|
    }
 | 
						|
 | 
						|
    this._renderPayerFields(state);
 | 
						|
 | 
						|
    let isMac = /mac/i.test(navigator.platform);
 | 
						|
    for (let manageTextEl of this._manageText.children) {
 | 
						|
      manageTextEl.hidden = manageTextEl.dataset.os == "mac" ? !isMac : isMac;
 | 
						|
      let link = manageTextEl.querySelector("a");
 | 
						|
      // The href is only set to be exposed to accessibility tools so users know what will open.
 | 
						|
      // The actual opening happens from the click event listener.
 | 
						|
      link.href = "about:preferences#privacy-form-autofill";
 | 
						|
    }
 | 
						|
 | 
						|
    this._renderPayButton(state);
 | 
						|
 | 
						|
    for (let page of this._mainContainer.querySelectorAll(":scope > .page")) {
 | 
						|
      page.hidden = state.page.id != page.id;
 | 
						|
    }
 | 
						|
 | 
						|
    this.toggleAttribute("changes-prevented", state.changesPrevented);
 | 
						|
    this.setAttribute("complete-status", request.completeStatus);
 | 
						|
    this._disabledOverlay.hidden = !state.changesPrevented;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
customElements.define("payment-dialog", PaymentDialog);
 |