@@ -7,8 +7,12 @@ SPDX-License-Identifier: AGPL-3.0-only
77<div >
88 <span v-if =" !available" >Loading<MkEllipsis /></span >
99 <div v-if =" props.provider == 'mcaptcha'" >
10- <div id =" mcaptcha__widget-container" class =" m-captcha-style" ></div >
11- <div ref =" captchaEl" ></div >
10+ <iframe
11+ v-if =" mCaptchaIframeUrl != null"
12+ ref =" mCaptchaIframe"
13+ :src =" mCaptchaIframeUrl"
14+ style =" border : none ; max-width : 320px ; width : 100% ; height : 100% ; max-height : 80px ;"
15+ ></iframe >
1216 </div >
1317 <div v-if =" props.provider == 'testcaptcha'" style =" background : #eee ; border : solid 1px #888 ; padding : 8px ; color : #000 ; max-width : 320px ; display : flex ; gap : 10px ; align-items : center ; box-shadow : 2px 2px 6px #0004 ; border-radius : 4px ;" >
1418 <img src =" /client-assets/testcaptcha.png" style =" width : 60px ; height : 60px ; " />
@@ -26,7 +30,8 @@ SPDX-License-Identifier: AGPL-3.0-only
2630</template >
2731
2832<script lang="ts" setup>
29- import { ref , useTemplateRef , computed , onMounted , onBeforeUnmount , watch , onUnmounted } from ' vue' ;
33+ import { ref , useTemplateRef , computed , onMounted , onBeforeUnmount , watch , onUnmounted , nextTick } from ' vue' ;
34+ import type Reciever_typeReferenceOnly from ' @mcaptcha/core-glue' ;
3035import { store } from ' @/store.js' ;
3136
3237// APIs provided by Captcha services
@@ -71,6 +76,19 @@ const available = ref(false);
7176
7277const captchaEl = useTemplateRef (' captchaEl' );
7378const captchaWidgetId = ref <string | undefined >(undefined );
79+
80+ let mCaptchaReciever: Reciever_typeReferenceOnly | null = null ;
81+ const mCaptchaIframe = useTemplateRef (' mCaptchaIframe' );
82+ const mCaptchaRemoveState = ref (false );
83+ const mCaptchaIframeUrl = computed (() => {
84+ if (props .provider === ' mcaptcha' && ! mCaptchaRemoveState .value && props .instanceUrl && props .sitekey ) {
85+ const url = new URL (' /widget' , props .instanceUrl );
86+ url .searchParams .set (' sitekey' , props .sitekey );
87+ return url .toString ();
88+ }
89+ return null ;
90+ });
91+
7492const testcaptchaInput = ref (' ' );
7593const testcaptchaPassed = ref (false );
7694
@@ -129,8 +147,14 @@ function reset() {
129147 if (_DEV_ ) console .warn (error );
130148 }
131149 }
150+
132151 testcaptchaPassed .value = false ;
133152 testcaptchaInput .value = ' ' ;
153+
154+ if (mCaptchaReciever != null ) {
155+ mCaptchaReciever .destroy ();
156+ mCaptchaReciever = null ;
157+ }
134158}
135159
136160function remove() {
@@ -143,6 +167,10 @@ function remove() {
143167 if (_DEV_ ) console .warn (error );
144168 }
145169 }
170+
171+ if (props .provider === ' mcaptcha' ) {
172+ mCaptchaRemoveState .value = true ;
173+ }
146174}
147175
148176async function requestRender() {
@@ -160,32 +188,29 @@ async function requestRender() {
160188 ' error-callback' : () => callback (undefined ),
161189 });
162190 } else if (props .provider === ' mcaptcha' && props .instanceUrl && props .sitekey ) {
163- const { default : Widget } = await import (' @mcaptcha/vanilla -glue' );
164- new Widget ({
191+ const { default : Reciever } = await import (' @mcaptcha/core -glue' );
192+ mCaptchaReciever = new Reciever ({
165193 siteKey: {
166- instanceUrl: new URL (props .instanceUrl ),
167194 key: props .sitekey ,
195+ instanceUrl: new URL (props .instanceUrl ),
168196 },
197+ }, (token : string ) => {
198+ callback (token );
169199 });
200+ mCaptchaReciever .listen ();
201+ mCaptchaRemoveState .value = false ;
170202 } else {
171- window .setTimeout (requestRender , 1 );
203+ window .setTimeout (requestRender , 50 );
172204 }
173205}
174206
175207function clearWidget() {
176- if (props .provider === ' mcaptcha' ) {
177- const container = window .document .getElementById (' mcaptcha__widget-container' );
178- if (container ) {
179- container .innerHTML = ' ' ;
180- }
181- } else {
182- reset ();
183- remove ();
208+ reset ();
209+ remove ();
184210
185- if (captchaEl .value ) {
186- // レンダリング先のコンテナの中身を掃除し、フォームが増殖するのを抑止
187- captchaEl .value .innerHTML = ' ' ;
188- }
211+ if (captchaEl .value ) {
212+ // レンダリング先のコンテナの中身を掃除し、フォームが増殖するのを抑止
213+ captchaEl .value .innerHTML = ' ' ;
189214 }
190215}
191216
0 commit comments