"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Event_js_1 = __importDefault(require("../../event/Event.cjs"));
const PropertySymbol = __importStar(require("../../PropertySymbol.cjs"));
const EventPhaseEnum_js_1 = __importDefault(require("../../event/EventPhaseEnum.cjs"));
const ValidityState_js_1 = __importDefault(require("../../validity-state/ValidityState.cjs"));
const HTMLElement_js_1 = __importDefault(require("../html-element/HTMLElement.cjs"));
const HTMLLabelElementUtility_js_1 = __importDefault(require("../html-label-element/HTMLLabelElementUtility.cjs"));
const url_1 = require("url");
const MouseEvent_js_1 = __importDefault(require("../../event/events/MouseEvent.cjs"));
const BUTTON_TYPES = ['submit', 'reset', 'button', 'menu'];
/**
 * HTML Button Element.
 *
 * Reference:
 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLButtonElement.
 */
class HTMLButtonElement extends HTMLElement_js_1.default {
    [PropertySymbol.validationMessage] = '';
    [PropertySymbol.validity] = new ValidityState_js_1.default(this);
    [PropertySymbol.formNode] = null;
    [PropertySymbol.popoverTargetElement] = null;
    /**
     * Returns validation message.
     *
     * @returns Validation message.
     */
    get validationMessage() {
        return this[PropertySymbol.validationMessage];
    }
    /**
     * Returns validity.
     *
     * @returns Validity.
     */
    get validity() {
        return this[PropertySymbol.validity];
    }
    /**
     * Returns name.
     *
     * @returns Name.
     */
    get name() {
        return this.getAttribute('name') || '';
    }
    /**
     * Sets name.
     *
     * @param name Name.
     */
    set name(name) {
        this.setAttribute('name', name);
    }
    /**
     * Returns value.
     *
     * @returns Value.
     */
    get value() {
        return this.getAttribute('value');
    }
    /**
     * Sets value.
     *
     * @param value Value.
     */
    set value(value) {
        this.setAttribute('value', value);
    }
    /**
     * Returns disabled.
     *
     * @returns Disabled.
     */
    get disabled() {
        return this.getAttribute('disabled') !== null;
    }
    /**
     * Sets disabled.
     *
     * @param disabled Disabled.
     */
    set disabled(disabled) {
        if (!disabled) {
            this.removeAttribute('disabled');
        }
        else {
            this.setAttribute('disabled', '');
        }
    }
    /**
     * Returns type
     *
     * @returns Type
     */
    get type() {
        const type = this.getAttribute('type');
        if (type === null || !BUTTON_TYPES.includes(type)) {
            return 'submit';
        }
        return type;
    }
    /**
     * Sets type
     *
     * @param value Type
     */
    set type(value) {
        this.setAttribute('type', value);
    }
    /**
     * Returns form action.
     *
     * @returns Form action.
     */
    get formAction() {
        if (!this.hasAttribute('formaction')) {
            return this[PropertySymbol.ownerDocument].location.href;
        }
        try {
            return new url_1.URL(this.getAttribute('formaction'), this[PropertySymbol.ownerDocument].location.href).href;
        }
        catch (e) {
            return '';
        }
    }
    /**
     * Sets form action.
     *
     * @param formAction Form action.
     */
    set formAction(formAction) {
        this.setAttribute('formaction', formAction);
    }
    /**
     * Returns form enctype.
     *
     * @returns Form enctype.
     */
    get formEnctype() {
        return this.getAttribute('formenctype') || '';
    }
    /**
     * Sets form enctype.
     *
     * @param formEnctype Form enctype.
     */
    set formEnctype(formEnctype) {
        this.setAttribute('formenctype', formEnctype);
    }
    /**
     * Returns form method.
     *
     * @returns Form method.
     */
    get formMethod() {
        return this.getAttribute('formmethod') || '';
    }
    /**
     * Sets form method.
     *
     * @param formMethod Form method.
     */
    set formMethod(formMethod) {
        this.setAttribute('formmethod', formMethod);
    }
    /**
     * Returns no validate.
     *
     * @returns No validate.
     */
    get formNoValidate() {
        return this.getAttribute('formnovalidate') !== null;
    }
    /**
     * Sets no validate.
     *
     * @param formNoValidate No validate.
     */
    set formNoValidate(formNoValidate) {
        if (!formNoValidate) {
            this.removeAttribute('formnovalidate');
        }
        else {
            this.setAttribute('formnovalidate', '');
        }
    }
    /**
     * Returns form target.
     *
     * @returns Form target.
     */
    get formTarget() {
        return this.getAttribute('formtarget') || '';
    }
    /**
     * Sets form target.
     *
     * @param formTarget Form target.
     */
    set formTarget(formTarget) {
        this.setAttribute('formtarget', formTarget);
    }
    /**
     * Returns the parent form element.
     *
     * @returns Form.
     */
    get form() {
        if (this[PropertySymbol.formNode]) {
            return this[PropertySymbol.formNode];
        }
        const id = this[PropertySymbol.attributes][PropertySymbol.namedItems].get('form')?.[PropertySymbol.value];
        if (!id || !this[PropertySymbol.isConnected]) {
            return null;
        }
        return this[PropertySymbol.ownerDocument].getElementById(id);
    }
    /**
     * Returns the associated label elements.
     *
     * @returns Label elements.
     */
    get labels() {
        return HTMLLabelElementUtility_js_1.default.getAssociatedLabelElements(this);
    }
    /**
     * Returns popover target element.
     *
     * @returns Popover target element.
     */
    get popoverTargetElement() {
        return this[PropertySymbol.popoverTargetElement];
    }
    /**
     * Sets popover target element.
     *
     * @param popoverTargetElement Popover target element.
     */
    set popoverTargetElement(popoverTargetElement) {
        if (popoverTargetElement !== null && !(popoverTargetElement instanceof HTMLElement_js_1.default)) {
            throw new this[PropertySymbol.window].TypeError(`Failed to set the 'popoverTargetElement' property on 'HTMLInputElement': Failed to convert value to 'Element'.`);
        }
        this[PropertySymbol.popoverTargetElement] = popoverTargetElement;
    }
    /**
     * Returns popover target action.
     *
     * @returns Popover target action.
     */
    get popoverTargetAction() {
        const value = this.getAttribute('popovertargetaction');
        if (value === null || (value !== 'hide' && value !== 'show' && value !== 'toggle')) {
            return 'toggle';
        }
        return value;
    }
    /**
     * Sets popover target action.
     *
     * @param value Popover target action.
     */
    set popoverTargetAction(value) {
        this.setAttribute('popovertargetaction', value);
    }
    /**
     * Checks validity.
     *
     * @returns "true" if the field is valid.
     */
    checkValidity() {
        const valid = this.disabled ||
            this.type === 'reset' ||
            this.type === 'button' ||
            this[PropertySymbol.validity].valid;
        if (!valid) {
            this.dispatchEvent(new Event_js_1.default('invalid', { bubbles: true, cancelable: true }));
        }
        return valid;
    }
    /**
     * Reports validity.
     *
     * @returns Validity.
     */
    reportValidity() {
        return this.checkValidity();
    }
    /**
     * Sets validation message.
     *
     * @param message Message.
     */
    setCustomValidity(message) {
        this[PropertySymbol.validationMessage] = String(message);
    }
    /**
     * @override
     */
    dispatchEvent(event) {
        if (event.type === 'click' &&
            event instanceof MouseEvent_js_1.default &&
            event.eventPhase === EventPhaseEnum_js_1.default.none &&
            this.disabled) {
            return false;
        }
        const returnValue = super.dispatchEvent(event);
        if (!event[PropertySymbol.defaultPrevented] &&
            event.type === 'click' &&
            event.eventPhase === EventPhaseEnum_js_1.default.none &&
            event instanceof MouseEvent_js_1.default) {
            const type = this.type;
            if (type === 'submit' || type === 'reset') {
                const form = this.form;
                if (form) {
                    if (type === 'submit' && this[PropertySymbol.isConnected]) {
                        form.requestSubmit(this);
                    }
                    else if (type === 'reset') {
                        form.reset();
                    }
                }
            }
        }
        return returnValue;
    }
}
exports.default = HTMLButtonElement;
//# sourceMappingURL=HTMLButtonElement.cjs.map