Create html element explicitly

This commit is contained in:
Taras Kushnir
2026-01-14 09:54:09 +02:00
parent ba1dcb1492
commit 28ba7ed860
3 changed files with 47 additions and 24 deletions

View File

@@ -48,7 +48,6 @@
data-errored-callback="onCaptchaErrored"
data-styles="--border-radius: .75rem; --border: 1px dashed #f00; font-size: 16px; --extra-spacing: 8px; display: block; height: 100%;"
data-display-mode="widget"
data-debug="true"
{{ if .Debug }}data-debug="{{.Debug}}"{{end}}
{{ if .Mode }}data-start-mode="{{.Mode}}"{{end}}>
</div>

View File

@@ -75,9 +75,23 @@ function errorDescription(code, strings) {
export class CaptchaElement extends SafeHTMLElement {
constructor() {
super();
this._state = '';
// create shadow dom root
this._root = this.attachShadow({ mode: 'open' });
this._debug = false;
this._error = null;
this._displayMode = DISPLAY_HIDDEN;
this._lang = 'en';
// Add CSS
const sheet = new CSSStyleSheet();
sheet.replaceSync(styles);
this._root.adoptedStyleSheets = [sheet];
this._overridesSheet = null;
}
connectedCallback() {
this._debug = this.getAttribute('debug');
this._error = null;
this._displayMode = this.getAttribute('display-mode');
@@ -87,19 +101,10 @@ export class CaptchaElement extends SafeHTMLElement {
this._lang = 'en';
}
// add CSS
const sheet = new CSSStyleSheet();
sheet.replaceSync(styles);
this._root.adoptedStyleSheets.push(sheet);
this._overridesSheet = null;
// add CSS overrides
const extraStyles = this.getAttribute('extra-styles');
if (extraStyles) {
this._overridesSheet = new CSSStyleSheet();
const cssText = `@layer custom { :host { ${extraStyles} } }`;
this._overridesSheet.replaceSync(cssText);
this._root.adoptedStyleSheets.push(this._overridesSheet);
}
this.updateStyles(extraStyles);
// init
const canShow = (this._displayMode == DISPLAY_WIDGET);
this.setState(STATE_EMPTY, canShow);
@@ -261,7 +266,7 @@ export class CaptchaElement extends SafeHTMLElement {
} else {
debugText = `[${text}]`;
}
debugElement.innerHTML = debugText;
debugElement.textContent = debugText;
if (error || this._error) {
debugElement.classList.add(DEBUG_ERROR_CLASS);
} else {
@@ -298,15 +303,18 @@ export class CaptchaElement extends SafeHTMLElement {
* @param {string} newValue
*/
attributeChangedCallback(name, oldValue, newValue) {
if ('progress' === name) {
const progressValue = newValue !== null ? parseFloat(newValue) : NaN;
if (!Number.isNaN(progressValue)) {
this.setProgress(progressValue);
}
} else if ('extra-styles' === name) {
if (oldValue !== newValue) {
if (oldValue === newValue) return;
switch (name) {
case 'progress':
const progressValue = newValue !== null ? parseFloat(newValue) : NaN;
if (!Number.isNaN(progressValue)) {
this.setProgress(progressValue);
}
break;
case 'extra-styles':
this.updateStyles(newValue);
}
}
break;
};
}
}

View File

@@ -57,7 +57,7 @@ export class CaptchaWidget {
// NOTE: this does not work on Safari by (Apple) design if we click a button
// "passive" - cannot use preventDefault()
form.addEventListener('focusin', this.onFocusIn.bind(this), { passive: true });
this._element.innerHTML = `<private-captcha display-mode="${this._options.displayMode}" lang="${this._options.lang}" theme="${this._options.theme}" extra-styles="${this._options.styles}"${this._options.debug ? ' debug="true"' : ''}></private-captcha>`;
this._element.replaceChildren(this._createCaptchaElement());
this._element.addEventListener('privatecaptcha:checked', this.onChecked.bind(this));
if (this._options.storeVariable) {
@@ -79,6 +79,22 @@ export class CaptchaWidget {
}
}
_createCaptchaElement() {
const captchaEl = document.createElement('private-captcha');
captchaEl.setAttribute('lang', this._options.lang);
captchaEl.setAttribute('theme', this._options.theme);
captchaEl.setAttribute('extra-styles', this._options.styles);
if (this._options.debug) {
captchaEl.setAttribute('debug', 'true');
}
captchaEl.setAttribute('display-mode', this._options.displayMode);
return captchaEl;
}
/**
* @param {Object} options
*/