slider-captcha-sdk 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +1 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.esm.js +1 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +23 -22
- package/dist/index.min.js.map +1 -0
- package/dist/password-validator.cjs.js +1 -0
- package/dist/password-validator.cjs.js.map +1 -0
- package/dist/password-validator.esm.js +1 -0
- package/dist/password-validator.esm.js.map +1 -0
- package/dist/password-validator.js +1 -0
- package/dist/password-validator.js.map +1 -0
- package/dist/password-validator.min.js +4 -3
- package/dist/password-validator.min.js.map +1 -0
- package/dist/slider-captcha.cjs.js +1 -0
- package/dist/slider-captcha.cjs.js.map +1 -0
- package/dist/slider-captcha.esm.js +1 -0
- package/dist/slider-captcha.esm.js.map +1 -0
- package/dist/slider-captcha.js +1 -0
- package/dist/slider-captcha.js.map +1 -0
- package/dist/slider-captcha.min.js +21 -20
- package/dist/slider-captcha.min.js.map +1 -0
- package/package.json +8 -27
|
@@ -1,42 +1,43 @@
|
|
|
1
|
-
(function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(t="undefined"!=typeof globalThis?globalThis:t||self).SliderCaptcha=i()})(this,function(){"use strict"
|
|
1
|
+
(function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(t="undefined"!=typeof globalThis?globalThis:t||self).SliderCaptcha=i()})(this,(function(){"use strict"
|
|
2
2
|
class PopupSliderCaptcha{static DEFAULTS={width:320,height:155,sliderSize:38,maxRetries:3,timeout:3e4,apiUrl:"/api/captcha",verifyUrl:"/api/captcha/verify",throttleDelay:16,clickMaskClose:!1}
|
|
3
3
|
static CSS_CLASSES={overlay:"slider-captcha-overlay",modal:"slider-captcha-modal",header:"slider-captcha-header",container:"slider-captcha-container",track:"slider-captcha-track",btn:"slider-captcha-btn",hint:"slider-captcha-hint",loading:"slider-captcha-loading",error:"slider-captcha-error"}
|
|
4
|
-
static getStyles(){return":root{--sc-primary:#409eff;--sc-success:#67c23a;--sc-danger:#f56c6c;--sc-border:#e4e7eb;--sc-bg:linear-gradient(90deg, #f7f9fa 0%, #e8f4fd 100%);--sc-text:#333;--sc-text-light:#999;--sc-shadow:0 4px 20px rgba(0,0,0,.3);--sc-radius:8px;--sc-transition:.3s ease}.slider-captcha-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);z-index:9999;display:none;justify-content:center;align-items:center;opacity:0;transition:opacity var(--sc-transition)}.slider-captcha-overlay.show{opacity:1}.slider-captcha-modal{background:#fff;border-radius:var(--sc-radius);padding:20px;box-shadow:var(--sc-shadow);position:relative;max-width:90vw;max-height:90vh;transform:scale(.8) translateY(-20px);opacity:0;transition:all var(--sc-transition)}.slider-captcha-modal.show{transform:scale(1) translateY(0);opacity:1}.slider-captcha-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:15px;padding-bottom:10px;border-bottom:1px solid var(--sc-border)}.slider-captcha-container{display:flex;align-items:center;position:relative;border-radius:4px;overflow:hidden;margin-bottom:15px;background:#837a7a;justify-content:center}.slider-captcha-track{width:100%;height:40px;line-height:40px;background:var(--sc-bg);border:1px solid var(--sc-border);border-radius:20px;position:relative;margin-bottom:15px;overflow:hidden}.slider-captcha-btn{width:38px;height:38px;background:#fff;border:1px solid #ccc;border-radius:50%;position:absolute;top:0;left:0;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 4px rgba(0,0,0,.1);transition:all var(--sc-transition);user-select:none;z-index:1}.slider-captcha-loading{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(255,255,255,.6);display:flex;align-items:center;justify-content:center;flex-direction:column;color:#666;font-size:14px;z-index:10;border-radius:4px}.slider-captcha-error{color:var(--sc-danger);font-size:12px;text-align:center;margin-top:10px;display:none}.slider-captcha-title{margin:0;font-size:16px;color:var(--sc-text)}.slider-captcha-close,.slider-captcha-refresh{background:none;border:none;cursor:pointer;color:var(--sc-text-light);padding:0;width:30px;height:30px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:all var(--sc-transition);position:relative;font-size:0}.slider-captcha-close::before,.slider-captcha-close::after{content:'';position:absolute;width:16px;height:2px;background-color:var(--sc-text-light);border-radius:1px;transition:all var(--sc-transition)}.slider-captcha-close::before{transform:rotate(45deg)}.slider-captcha-close::after{transform:rotate(-45deg)}.slider-captcha-close:hover{background:#f5f5f5;transform:scale(1.1)}.slider-captcha-close:hover::before,.slider-captcha-close:hover::after{background-color:var(--sc-danger)}.slider-captcha-refresh{margin-left:10px}.slider-captcha-refresh svg{width:20px;height:20px;fill:var(--sc-text-light);transition:all var(--sc-transition)}.slider-captcha-refresh:hover{background:#f5f5f5;transform:scale(1.1)}.slider-captcha-refresh:hover svg{fill:var(--sc-primary);transform:rotate(180deg)}.slider-captcha-floating-time{position:absolute;bottom:-40px;left:50%;transform:translateX(-50%);color:#fff;font-size:12px;white-space:nowrap;opacity:0;pointer-events:none;z-index:10;transition:all var(--sc-transition);background:#fff;padding:2px 15px;border-radius:10px}.slider-captcha-floating-time.show{opacity:1;transform:translateX(-50%) translateY(-45px)}.slider-captcha-floating-time.success{color:var(--sc-success)}.slider-captcha-floating-time.fail{color:var(--sc-danger)}.slider-captcha-bg{width:100%;height:100%;object-fit:cover;display:block}.slider-captcha-piece{position:absolute;top:0;left:0;cursor:pointer;transition:none;z-index:2}.slider-captcha-finger{position:absolute;top:50%;left:10px;transform:translateY(-50%);font-size:20px;animation:fingerSlide 2s ease-in-out infinite;pointer-events:none;z-index:1;opacity:.6}.slider-captcha-hint{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:var(--sc-text-light);font-size:14px;pointer-events:none;z-index:1;transition:all var(--sc-transition)}.slider-captcha-header-buttons{display:flex;align-items:center}@keyframes fingerSlide{0%{left:10px;opacity:.6}50%{opacity:1}100%{left:calc(50% - 10px);opacity:.6}}"}constructor(t={}){this.options={...PopupSliderCaptcha.DEFAULTS,...t},this.elements={},this.state=this.createInitialState(),this.captchaData=null,this.times=[],this.startTime=null,this.eventListeners=[],this.timers=new Set,this.rafId=null,this.cachedDimensions=null,this.imageCache=new Map,this.throttledHandleMove=this.throttle(t=>this.handleMove(t),this.options.throttleDelay),this.init()}createInitialState(){return{isVisible:!1,isDragging:!1,currentX:0,startX:0,retryCount:0,isLoading:!1}}init(){this.injectStyles(),this.createElements(),this.bindEvents()}injectStyles(){if(document.querySelector("#slider-captcha-styles"))return
|
|
4
|
+
static getStyles(){return":root{--sc-primary:#409eff;--sc-success:#67c23a;--sc-danger:#f56c6c;--sc-border:#e4e7eb;--sc-bg:linear-gradient(90deg, #f7f9fa 0%, #e8f4fd 100%);--sc-text:#333;--sc-text-light:#999;--sc-shadow:0 4px 20px rgba(0,0,0,.3);--sc-radius:8px;--sc-transition:.3s ease}.slider-captcha-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);z-index:9999;display:none;justify-content:center;align-items:center;opacity:0;transition:opacity var(--sc-transition)}.slider-captcha-overlay.show{opacity:1}.slider-captcha-modal{background:#fff;border-radius:var(--sc-radius);padding:20px;box-shadow:var(--sc-shadow);position:relative;max-width:90vw;max-height:90vh;transform:scale(.8) translateY(-20px);opacity:0;transition:all var(--sc-transition)}.slider-captcha-modal.show{transform:scale(1) translateY(0);opacity:1}.slider-captcha-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:15px;padding-bottom:10px;border-bottom:1px solid var(--sc-border)}.slider-captcha-container{display:flex;align-items:center;position:relative;border-radius:4px;overflow:hidden;margin-bottom:15px;background:#837a7a;justify-content:center}.slider-captcha-track{width:100%;height:40px;line-height:40px;background:var(--sc-bg);border:1px solid var(--sc-border);border-radius:20px;position:relative;margin-bottom:15px;overflow:hidden}.slider-captcha-btn{width:38px;height:38px;background:#fff;border:1px solid #ccc;border-radius:50%;position:absolute;top:0;left:0;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 4px rgba(0,0,0,.1);transition:all var(--sc-transition);user-select:none;z-index:1}.slider-captcha-loading{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(255,255,255,.6);display:flex;align-items:center;justify-content:center;flex-direction:column;color:#666;font-size:14px;z-index:10;border-radius:4px}.slider-captcha-error{color:var(--sc-danger);font-size:12px;text-align:center;margin-top:10px;display:none}.slider-captcha-title{margin:0;font-size:16px;color:var(--sc-text)}.slider-captcha-close,.slider-captcha-refresh{background:none;border:none;cursor:pointer;color:var(--sc-text-light);padding:0;width:30px;height:30px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:all var(--sc-transition);position:relative;font-size:0}.slider-captcha-close::before,.slider-captcha-close::after{content:'';position:absolute;width:16px;height:2px;background-color:var(--sc-text-light);border-radius:1px;transition:all var(--sc-transition)}.slider-captcha-close::before{transform:rotate(45deg)}.slider-captcha-close::after{transform:rotate(-45deg)}.slider-captcha-close:hover{background:#f5f5f5;transform:scale(1.1)}.slider-captcha-close:hover::before,.slider-captcha-close:hover::after{background-color:var(--sc-danger)}.slider-captcha-refresh{margin-left:10px}.slider-captcha-refresh svg{width:20px;height:20px;fill:var(--sc-text-light);transition:all var(--sc-transition)}.slider-captcha-refresh:hover{background:#f5f5f5;transform:scale(1.1)}.slider-captcha-refresh:hover svg{fill:var(--sc-primary);transform:rotate(180deg)}.slider-captcha-floating-time{position:absolute;bottom:-40px;left:50%;transform:translateX(-50%);color:#fff;font-size:12px;white-space:nowrap;opacity:0;pointer-events:none;z-index:10;transition:all var(--sc-transition);background:#fff;padding:2px 15px;border-radius:10px}.slider-captcha-floating-time.show{opacity:1;transform:translateX(-50%) translateY(-45px)}.slider-captcha-floating-time.success{color:var(--sc-success)}.slider-captcha-floating-time.fail{color:var(--sc-danger)}.slider-captcha-bg{width:100%;height:100%;object-fit:cover;display:block}.slider-captcha-piece{position:absolute;top:0;left:0;cursor:pointer;transition:none;z-index:2}.slider-captcha-finger{position:absolute;top:50%;left:10px;transform:translateY(-50%);font-size:20px;animation:fingerSlide 2s ease-in-out infinite;pointer-events:none;z-index:1;opacity:.6}.slider-captcha-hint{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:var(--sc-text-light);font-size:14px;pointer-events:none;z-index:1;transition:all var(--sc-transition)}.slider-captcha-header-buttons{display:flex;align-items:center}@keyframes fingerSlide{0%{left:10px;opacity:.6}50%{opacity:1}100%{left:calc(50% - 10px);opacity:.6}}"}constructor(t={}){this.options={...PopupSliderCaptcha.DEFAULTS,...t},this.elements={},this.state=this.createInitialState(),this.captchaData=null,this.times=[],this.startTime=null,this.eventListeners=[],this.timers=new Set,this.rafId=null,this.cachedDimensions=null,this.imageCache=new Map,this.throttledHandleMove=this.throttle((t=>this.handleMove(t)),this.options.throttleDelay),this.init()}createInitialState(){return{isVisible:!1,isDragging:!1,currentX:0,startX:0,retryCount:0,isLoading:!1}}init(){this.injectStyles(),this.createElements(),this.bindEvents()}injectStyles(){if(document.querySelector("#slider-captcha-styles"))return
|
|
5
5
|
const t=document.createElement("style")
|
|
6
|
-
t.id="slider-captcha-styles",t.textContent=PopupSliderCaptcha.getStyles(),document.head.appendChild(t)}createElements(){const{elements:t,options:i}=this;[["overlay","div",PopupSliderCaptcha.CSS_CLASSES.overlay],["modal","div",PopupSliderCaptcha.CSS_CLASSES.modal],["header","div",PopupSliderCaptcha.CSS_CLASSES.header],["title","h3","slider-captcha-title","安全验证"],["closeBtn","button","slider-captcha-close"],["refreshBtn","button","slider-captcha-refresh"],["container","div",PopupSliderCaptcha.CSS_CLASSES.container],["backgroundImg","img","slider-captcha-bg"],["sliderImg","img","slider-captcha-piece"],["loadingText","div",PopupSliderCaptcha.CSS_CLASSES.loading,"加载中..."],["floatingTime","div","slider-captcha-floating-time"],["track","div",PopupSliderCaptcha.CSS_CLASSES.track],["fingerAnimation","div","slider-captcha-finger","👉"],["btn","div",PopupSliderCaptcha.CSS_CLASSES.btn],["icon","div","","→"],["hint","div",PopupSliderCaptcha.CSS_CLASSES.hint,"向右滑动完成验证"],["error","div",PopupSliderCaptcha.CSS_CLASSES.error]].forEach(([i,e,s,a])=>{t[i]=this.createElement(e,s,a)}),t.container.style.cssText=`width:${i.width}px;height:${i.height}px`,t.refreshBtn.innerHTML='<svg viewBox="0 0 24 24"><path d="M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z"/></svg>',this.assembleDOM(),this.setInitialState()}createElement(t,i="",e=""){const s=document.createElement(t)
|
|
6
|
+
t.id="slider-captcha-styles",t.textContent=PopupSliderCaptcha.getStyles(),document.head.appendChild(t)}createElements(){const{elements:t,options:i}=this;[["overlay","div",PopupSliderCaptcha.CSS_CLASSES.overlay],["modal","div",PopupSliderCaptcha.CSS_CLASSES.modal],["header","div",PopupSliderCaptcha.CSS_CLASSES.header],["title","h3","slider-captcha-title","安全验证"],["closeBtn","button","slider-captcha-close"],["refreshBtn","button","slider-captcha-refresh"],["container","div",PopupSliderCaptcha.CSS_CLASSES.container],["backgroundImg","img","slider-captcha-bg"],["sliderImg","img","slider-captcha-piece"],["loadingText","div",PopupSliderCaptcha.CSS_CLASSES.loading,"加载中..."],["floatingTime","div","slider-captcha-floating-time"],["track","div",PopupSliderCaptcha.CSS_CLASSES.track],["fingerAnimation","div","slider-captcha-finger","👉"],["btn","div",PopupSliderCaptcha.CSS_CLASSES.btn],["icon","div","","→"],["hint","div",PopupSliderCaptcha.CSS_CLASSES.hint,"向右滑动完成验证"],["error","div",PopupSliderCaptcha.CSS_CLASSES.error]].forEach((([i,e,s,a])=>{t[i]=this.createElement(e,s,a)})),t.container.style.cssText=`width:${i.width}px;height:${i.height}px`,t.refreshBtn.innerHTML='<svg viewBox="0 0 24 24"><path d="M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z"/></svg>',this.assembleDOM(),this.setInitialState()}createElement(t,i="",e=""){const s=document.createElement(t)
|
|
7
7
|
return i&&(s.className=i),e&&(s.textContent=e),s}assembleDOM(){const{elements:t}=this,i=this.createElement("div","slider-captcha-header-buttons")
|
|
8
8
|
i.append(t.refreshBtn,t.closeBtn),t.header.append(t.title,i),t.container.append(t.backgroundImg,t.sliderImg,t.loadingText,t.floatingTime),t.btn.appendChild(t.icon),t.track.append(t.fingerAnimation,t.btn,t.hint),t.modal.append(t.header,t.container,t.track,t.error),t.overlay.appendChild(t.modal),document.body.appendChild(t.overlay)}setInitialState(){Object.assign(this.elements.container.style,{display:"none"}),Object.assign(this.elements.track.style,{display:"none"})}bindEvents(){const{elements:t}=this
|
|
9
|
-
this.addEventListener(t.closeBtn,"click",()=>this.hide()),this.addEventListener(t.refreshBtn,"click",()=>this.refresh()),this.addEventListener(t.overlay,"click",i=>{i.target===t.overlay&&this.options.clickMaskClose&&this.hide()}),this.addEventListener(document,"keydown",t=>{"Escape"===t.key&&this.state.isVisible&&this.hide()}),this.addEventListener(document,"visibilitychange",()=>this.handleVisibilityChange()),this.bindSliderEvents()}bindSliderEvents(){const{elements:t}=this,i={start:t=>this.handleStart(t),move:this.throttledHandleMove,end:()=>this.handleEnd()}
|
|
10
|
-
this.addEventListener(t.btn,"mousedown",i.start),this.addEventListener(t.btn,"touchstart",i.start),this.addEventListener(t.sliderImg,"mousedown",i.start),this.addEventListener(t.sliderImg,"touchstart",i.start),this.addEventListener(document,"mousemove",i.move,{passive:!1}),this.addEventListener(document,"touchmove",i.move,{passive:!1}),this.addEventListener(document,"mouseup",i.end),this.addEventListener(document,"touchend",i.end)}addEventListener(t,i,e,s={}){t&&"function"==typeof e&&(t.addEventListener(i,e,s),this.eventListeners.push({element:t,event:i,handler:e,options:s}))}removeAllEventListeners(){this.eventListeners.forEach(({element:t,event:i,handler:e,options:s})=>{try{t?.removeEventListener?.(i,e,s)}catch(t){}}),this.eventListeners.length=0}getDimensions(){if(!this.cachedDimensions){const t=this.elements.track.offsetWidth,i=this.elements.btn.offsetWidth
|
|
9
|
+
this.addEventListener(t.closeBtn,"click",(()=>this.hide())),this.addEventListener(t.refreshBtn,"click",(()=>this.refresh())),this.addEventListener(t.overlay,"click",(i=>{i.target===t.overlay&&this.options.clickMaskClose&&this.hide()})),this.addEventListener(document,"keydown",(t=>{"Escape"===t.key&&this.state.isVisible&&this.hide()})),this.addEventListener(document,"visibilitychange",(()=>this.handleVisibilityChange())),this.bindSliderEvents()}bindSliderEvents(){const{elements:t}=this,i={start:t=>this.handleStart(t),move:this.throttledHandleMove,end:()=>this.handleEnd()}
|
|
10
|
+
this.addEventListener(t.btn,"mousedown",i.start),this.addEventListener(t.btn,"touchstart",i.start),this.addEventListener(t.sliderImg,"mousedown",i.start),this.addEventListener(t.sliderImg,"touchstart",i.start),this.addEventListener(document,"mousemove",i.move,{passive:!1}),this.addEventListener(document,"touchmove",i.move,{passive:!1}),this.addEventListener(document,"mouseup",i.end),this.addEventListener(document,"touchend",i.end)}addEventListener(t,i,e,s={}){t&&"function"==typeof e&&(t.addEventListener(i,e,s),this.eventListeners.push({element:t,event:i,handler:e,options:s}))}removeAllEventListeners(){this.eventListeners.forEach((({element:t,event:i,handler:e,options:s})=>{try{t?.removeEventListener?.(i,e,s)}catch(t){}})),this.eventListeners.length=0}getDimensions(){if(!this.cachedDimensions){const t=this.elements.track.offsetWidth,i=this.elements.btn.offsetWidth
|
|
11
11
|
this.cachedDimensions={trackWidth:t,btnWidth:i,maxX:t-i}}return this.cachedDimensions}getPosition(){const{maxX:t}=this.getDimensions(),i=this.state.currentX/t
|
|
12
12
|
return Math.round(i*(this.options.width-this.options.sliderSize))}handleStart(t){!this.captchaData||this.state.isDragging||this.state.isLoading||(t.preventDefault(),this.state.isDragging=!0,this.state.startX=this.getClientX(t)-this.state.currentX,this.startTime=this.startTime||Date.now(),this.times=[{time:Date.now(),position:this.getPosition()}],this.setTransition(!1),this.updateUIState("dragging"),this.cachedDimensions=null)}handleMove(t){if(!this.state.isDragging)return
|
|
13
13
|
t.preventDefault()
|
|
14
14
|
const i=this.getClientX(t)-this.state.startX,{maxX:e}=this.getDimensions()
|
|
15
|
-
this.state.currentX=Math.max(0,Math.min(i,e)),this.times.push({time:Date.now(),position:this.getPosition()}),this.rafId&&cancelAnimationFrame(this.rafId),this.rafId=requestAnimationFrame(()=>this.updateSliderPosition())}handleEnd(){this.state.isDragging&&(this.times.push({time:Date.now(),position:this.getPosition()}),this.state.isDragging=!1,this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.verify())}handleVisibilityChange(){const t=document.hidden?"paused":"running"
|
|
15
|
+
this.state.currentX=Math.max(0,Math.min(i,e)),this.times.push({time:Date.now(),position:this.getPosition()}),this.rafId&&cancelAnimationFrame(this.rafId),this.rafId=requestAnimationFrame((()=>this.updateSliderPosition()))}handleEnd(){this.state.isDragging&&(this.times.push({time:Date.now(),position:this.getPosition()}),this.state.isDragging=!1,this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.verify())}handleVisibilityChange(){const t=document.hidden?"paused":"running"
|
|
16
16
|
this.elements.fingerAnimation&&(this.elements.fingerAnimation.style.animationPlayState=t)}getClientX(t){return t.type.includes("touch")?t.touches[0].clientX:t.clientX}setTransition(t){const i=t?"all 0.3s ease":"none"
|
|
17
|
-
requestAnimationFrame(()=>{this.elements.btn.style.transition=i,this.elements.sliderImg.style.transition=i})}updateUIState(t){const{elements:i}=this,e={dragging:()=>{i.hint.style.opacity="0",i.fingerAnimation.style.display="none"},success:()=>{Object.assign(i.btn.style,{background:"var(--sc-success)"}),Object.assign(i.icon.style,{innerHTML:"✓",color:"white"}),i.icon.innerHTML="✓"},fail:()=>{Object.assign(i.btn.style,{background:"var(--sc-danger)"}),Object.assign(i.icon.style,{innerHTML:"✗",color:"white"}),i.icon.innerHTML="✗"},reset:()=>{Object.assign(i.btn.style,{background:"white"}),Object.assign(i.icon.style,{color:"#666"}),i.icon.innerHTML="→",i.fingerAnimation.style.display="block",this.updateHintText("向右滑动完成验证","var(--sc-text-light)")},loading:()=>{i.hint.style.opacity="0",i.fingerAnimation.style.display="none",Object.assign(i.track.style,{pointerEvents:"none",opacity:"0.6"})}}
|
|
18
|
-
e[t]&&requestAnimationFrame(()=>{e[t](),"loading"!==t&&Object.assign(i.track.style,{pointerEvents:"auto",opacity:"1"})})}updateHintText(t,i){requestAnimationFrame(()=>{Object.assign(this.elements.hint,{textContent:t}),Object.assign(this.elements.hint.style,{color:i,opacity:"1"})})}updateSliderPosition(){const{elements:t,options:i,state:e}=this,{maxX:s}=this.getDimensions(),a=e.currentX/s*(i.width-i.sliderSize),n=e.currentX/s
|
|
19
|
-
requestAnimationFrame(()=>{t.btn.style.transform=`translateX(${e.currentX}px)`,t.sliderImg.style.transform=`translateX(${a}px)`,t.fingerAnimation.style.opacity=.8>n?"0.6":"0"})}show(){this.state.isVisible=!0,this.elements.overlay.style.display="flex",this.elements.overlay.offsetHeight,requestAnimationFrame(()=>{this.elements.overlay.classList.add("show"),this.elements.modal.classList.add("show")}),this.loadCaptcha()}hide(){this.state.isVisible=!1,this.elements.overlay.classList.remove("show"),this.elements.modal.classList.remove("show"),this.safeSetTimeout(()=>{this.elements.overlay.style.display="none",document.body.removeChild(this.elements.overlay),this.reset(),this.options.onClose?.(),this.elements.overlay=null},300)}async loadCaptcha(){try{this.showLoading(),this.startTime=Date.now()
|
|
20
|
-
const t=new AbortController,i=this.safeSetTimeout(()=>t.abort(),this.options.timeout),e=await fetch(this.options.apiUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({place:2,timestamp:Date.now()}),signal:t.signal})
|
|
17
|
+
requestAnimationFrame((()=>{this.elements.btn.style.transition=i,this.elements.sliderImg.style.transition=i}))}updateUIState(t){const{elements:i}=this,e={dragging:()=>{i.hint.style.opacity="0",i.fingerAnimation.style.display="none"},success:()=>{Object.assign(i.btn.style,{background:"var(--sc-success)"}),Object.assign(i.icon.style,{innerHTML:"✓",color:"white"}),i.icon.innerHTML="✓"},fail:()=>{Object.assign(i.btn.style,{background:"var(--sc-danger)"}),Object.assign(i.icon.style,{innerHTML:"✗",color:"white"}),i.icon.innerHTML="✗"},reset:()=>{Object.assign(i.btn.style,{background:"white"}),Object.assign(i.icon.style,{color:"#666"}),i.icon.innerHTML="→",i.fingerAnimation.style.display="block",this.updateHintText("向右滑动完成验证","var(--sc-text-light)")},loading:()=>{i.hint.style.opacity="0",i.fingerAnimation.style.display="none",Object.assign(i.track.style,{pointerEvents:"none",opacity:"0.6"})}}
|
|
18
|
+
e[t]&&requestAnimationFrame((()=>{e[t](),"loading"!==t&&Object.assign(i.track.style,{pointerEvents:"auto",opacity:"1"})}))}updateHintText(t,i){requestAnimationFrame((()=>{Object.assign(this.elements.hint,{textContent:t}),Object.assign(this.elements.hint.style,{color:i,opacity:"1"})}))}updateSliderPosition(){const{elements:t,options:i,state:e}=this,{maxX:s}=this.getDimensions(),a=e.currentX/s*(i.width-i.sliderSize),n=e.currentX/s
|
|
19
|
+
requestAnimationFrame((()=>{t.btn.style.transform=`translateX(${e.currentX}px)`,t.sliderImg.style.transform=`translateX(${a}px)`,t.fingerAnimation.style.opacity=.8>n?"0.6":"0"}))}show(){this.state.isVisible=!0,this.elements.overlay.style.display="flex",this.elements.overlay.offsetHeight,requestAnimationFrame((()=>{this.elements.overlay.classList.add("show"),this.elements.modal.classList.add("show")})),this.loadCaptcha()}hide(){this.state.isVisible=!1,this.elements.overlay.classList.remove("show"),this.elements.modal.classList.remove("show"),this.safeSetTimeout((()=>{this.elements.overlay.style.display="none",document.body.removeChild(this.elements.overlay),this.reset(),this.options.onClose?.(),this.elements.overlay=null}),300)}async loadCaptcha(){try{this.showLoading(),this.startTime=Date.now()
|
|
20
|
+
const t=new AbortController,i=this.safeSetTimeout((()=>t.abort()),this.options.timeout),e=await fetch(this.options.apiUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({place:2,timestamp:Date.now()}),signal:t.signal})
|
|
21
21
|
if(this.safeClearTimeout(i),!e.ok)throw Error("HTTP "+e.status)
|
|
22
22
|
const s=await e.json()
|
|
23
23
|
if(!s.data?.canvasSrc||!s.data?.blockSrc)throw Error("验证码数据格式错误")
|
|
24
24
|
this.captchaData=s.data,this.showCaptcha(),await this.renderCaptcha()}catch(t){const i="AbortError"===t.name?"请求超时,请重试":"加载验证码失败: "+t.message
|
|
25
|
-
this.showError(i)}}async renderCaptcha(){return new Promise((t,i)=>{let e=0
|
|
25
|
+
this.showError(i)}}async renderCaptcha(){return new Promise(((t,i)=>{let e=0
|
|
26
26
|
const s=()=>2===++e&&(this.hideLoading(),t()),a=()=>i(Error("图片加载失败"))
|
|
27
|
-
this.loadImage(this.elements.backgroundImg,this.captchaData.canvasSrc,{width:this.captchaData.canvasWidth,height:this.captchaData.canvasHeight},s,a),this.loadImage(this.elements.sliderImg,this.captchaData.blockSrc,{width:this.captchaData.blockWidth,height:this.captchaData.blockHeight,top:this.captchaData.blockY},s,a)})}loadImage(t,i,e,s,a){if(this.imageCache.has(i)){const a=this.imageCache.get(i)
|
|
28
|
-
return t.src=a.src,this.applyStyles(t,e),void s()}t.onload=()=>{this.imageCache.set(i,t.cloneNode()),s()},t.onerror=a,t.src=i,this.applyStyles(t,e)}applyStyles(t,i){Object.entries(i).forEach(([i,e])=>{t.style[i]="number"==typeof e?e+"px":e})}showLoading(){this.state.isLoading=!0,this.batchUpdateStyles({container:{display:"block"},loadingText:{display:"flex"},error:{display:"none"}}),this.updateUIState("loading")}hideLoading(){this.state.isLoading=!1,this.batchUpdateStyles({loadingText:{display:"none"}}),this.updateUIState("reset")}showCaptcha(){this.batchUpdateStyles({container:{display:"block"},track:{display:"block"},error:{display:"none"}})}showError(t){this.hideLoading(),this.batchUpdateStyles({error:{display:"block",textContent:t}})}batchUpdateStyles(t){requestAnimationFrame(()=>{Object.entries(t).forEach(([t,i])=>{const e=this.elements[t]
|
|
29
|
-
e&&Object.entries(i).forEach(([t,i])=>{"textContent"===t?e.textContent=i:e.style[t]=i})})})}async verify(){if(this.captchaData)try{const t=new AbortController,i=this.safeSetTimeout(()=>t.abort(),this.options.timeout),e=await fetch(this.options.verifyUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({loginVo:{nonceStr:this.captchaData.nonceStr,value:this.getPosition()},dragEventList:[...this.times]}),signal:t.signal})
|
|
27
|
+
this.loadImage(this.elements.backgroundImg,this.captchaData.canvasSrc,{width:this.captchaData.canvasWidth,height:this.captchaData.canvasHeight},s,a),this.loadImage(this.elements.sliderImg,this.captchaData.blockSrc,{width:this.captchaData.blockWidth,height:this.captchaData.blockHeight,top:this.captchaData.blockY},s,a)}))}loadImage(t,i,e,s,a){if(this.imageCache.has(i)){const a=this.imageCache.get(i)
|
|
28
|
+
return t.src=a.src,this.applyStyles(t,e),void s()}t.onload=()=>{this.imageCache.set(i,t.cloneNode()),s()},t.onerror=a,t.src=i,this.applyStyles(t,e)}applyStyles(t,i){Object.entries(i).forEach((([i,e])=>{t.style[i]="number"==typeof e?e+"px":e}))}showLoading(){this.state.isLoading=!0,this.batchUpdateStyles({container:{display:"block"},loadingText:{display:"flex"},error:{display:"none"}}),this.updateUIState("loading")}hideLoading(){this.state.isLoading=!1,this.batchUpdateStyles({loadingText:{display:"none"}}),this.updateUIState("reset")}showCaptcha(){this.batchUpdateStyles({container:{display:"block"},track:{display:"block"},error:{display:"none"}})}showError(t){this.hideLoading(),this.batchUpdateStyles({error:{display:"block",textContent:t}})}batchUpdateStyles(t){requestAnimationFrame((()=>{Object.entries(t).forEach((([t,i])=>{const e=this.elements[t]
|
|
29
|
+
e&&Object.entries(i).forEach((([t,i])=>{"textContent"===t?e.textContent=i:e.style[t]=i}))}))}))}async verify(){if(this.captchaData)try{const t=new AbortController,i=this.safeSetTimeout((()=>t.abort()),this.options.timeout),e=await fetch(this.options.verifyUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({loginVo:{nonceStr:this.captchaData.nonceStr,value:this.getPosition()},dragEventList:[...this.times]}),signal:t.signal})
|
|
30
30
|
if(this.safeClearTimeout(i),!e.ok)throw Error("HTTP "+e.status)
|
|
31
31
|
const s=await e.json()
|
|
32
32
|
"0"===s.code||!0===s.success?this.onVerifySuccess():this.onVerifyFail(s.message||"验证失败,请重试!")}catch(t){const i="AbortError"===t.name?"验证超时,请重试":"网络错误"
|
|
33
33
|
this.onVerifyFail(i)}else this.onVerifyFail("验证码数据丢失")}onVerifySuccess(){const t=Date.now()-this.startTime,i=`验证成功!耗时:${(t/1e3).toFixed(2)}s`
|
|
34
|
-
this.updateUIState("success"),this.showFloatingTime(i,"success"),this.safeSetTimeout(()=>{this.options.onSuccess?.({captchaId:this.captchaData.captchaId,timestamp:Date.now(),duration:t}),this.hide()},2e3)}showFloatingTime(t,i="success"){const{elements:e}=this
|
|
35
|
-
e.floatingTime.textContent=t,e.floatingTime.className="slider-captcha-floating-time "+i,this.safeSetTimeout(()=>e.floatingTime.classList.add("show"),100),this.safeSetTimeout(()=>{e.floatingTime.className="slider-captcha-floating-time"},2500)}onVerifyFail(t){this.state.retryCount++,this.updateUIState("fail"),this.showFloatingTime(t,"fail"),this.safeSetTimeout(()=>{this.state.retryCount<this.options.maxRetries?this.reset():this.refresh()},2500)}reset(){this.clearAllTimers(),Object.assign(this.state,{isDragging:!1,currentX:0,startX:0,isLoading:!1}),this.times=[],this.startTime=null,this.cachedDimensions=null,requestAnimationFrame(()=>{this.setTransition(!0),this.elements.btn.style.transform="translateX(0px)",this.elements.sliderImg.style.transform="translateX(0px)",this.updateUIState("reset"),this.elements.error.style.display="none"})}refresh(){this.reset(),this.state.retryCount=0,this.loadCaptcha()}safeSetTimeout(t,i){const e=setTimeout(()=>{this.timers.delete(e),t()},i)
|
|
36
|
-
return this.timers.add(e),e}safeClearTimeout(t){t&&(clearTimeout(t),this.timers.delete(t))}clearAllTimers(){this.timers.forEach(t=>{clearTimeout(t),clearInterval(t)}),this.timers.clear(),this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=null)}cleanupImages(){this.elements.backgroundImg&&(this.elements.backgroundImg.src="",this.elements.backgroundImg.onload=null,this.elements.backgroundImg.onerror=null),this.elements.sliderImg&&(this.elements.sliderImg.src="",this.elements.sliderImg.onload=null,this.elements.sliderImg.onerror=null),this.imageCache.clear()}throttle(t,i){let e=0
|
|
34
|
+
this.updateUIState("success"),this.showFloatingTime(i,"success"),this.safeSetTimeout((()=>{this.options.onSuccess?.({captchaId:this.captchaData.captchaId,timestamp:Date.now(),duration:t}),this.hide()}),2e3)}showFloatingTime(t,i="success"){const{elements:e}=this
|
|
35
|
+
e.floatingTime.textContent=t,e.floatingTime.className="slider-captcha-floating-time "+i,this.safeSetTimeout((()=>e.floatingTime.classList.add("show")),100),this.safeSetTimeout((()=>{e.floatingTime.className="slider-captcha-floating-time"}),2500)}onVerifyFail(t){this.state.retryCount++,this.updateUIState("fail"),this.showFloatingTime(t,"fail"),this.safeSetTimeout((()=>{this.state.retryCount<this.options.maxRetries?this.reset():this.refresh()}),2500)}reset(){this.clearAllTimers(),Object.assign(this.state,{isDragging:!1,currentX:0,startX:0,isLoading:!1}),this.times=[],this.startTime=null,this.cachedDimensions=null,requestAnimationFrame((()=>{this.setTransition(!0),this.elements.btn.style.transform="translateX(0px)",this.elements.sliderImg.style.transform="translateX(0px)",this.updateUIState("reset"),this.elements.error.style.display="none"}))}refresh(){this.reset(),this.state.retryCount=0,this.loadCaptcha()}safeSetTimeout(t,i){const e=setTimeout((()=>{this.timers.delete(e),t()}),i)
|
|
36
|
+
return this.timers.add(e),e}safeClearTimeout(t){t&&(clearTimeout(t),this.timers.delete(t))}clearAllTimers(){this.timers.forEach((t=>{clearTimeout(t),clearInterval(t)})),this.timers.clear(),this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=null)}cleanupImages(){this.elements.backgroundImg&&(this.elements.backgroundImg.src="",this.elements.backgroundImg.onload=null,this.elements.backgroundImg.onerror=null),this.elements.sliderImg&&(this.elements.sliderImg.src="",this.elements.sliderImg.onload=null,this.elements.sliderImg.onerror=null),this.imageCache.clear()}throttle(t,i){let e=0
|
|
37
37
|
return function(...s){const a=Date.now()
|
|
38
38
|
if(a-e>=i)return e=a,t.apply(this,s)}}debounce(t,i){let e
|
|
39
|
-
return function(...s){clearTimeout(e),e=setTimeout(()=>t.apply(this,s),i)}}destroy(){document.body.style.userSelect="",document.body.style.cursor="",this.clearAllTimers(),this.removeAllEventListeners(),this.cleanupImages(),this.elements.overlay?.parentNode&&this.elements.overlay.parentNode.removeChild(this.elements.overlay)
|
|
39
|
+
return function(...s){clearTimeout(e),e=setTimeout((()=>t.apply(this,s)),i)}}destroy(){document.body.style.userSelect="",document.body.style.cursor="",this.clearAllTimers(),this.removeAllEventListeners(),this.cleanupImages(),this.elements.overlay?.parentNode&&this.elements.overlay.parentNode.removeChild(this.elements.overlay)
|
|
40
40
|
const t=document.getElementById("slider-captcha-styles")
|
|
41
|
-
t&&t.remove(),Object.keys(this).forEach(t=>{"constructor"!==t&&(this[t]=null)})}static create(t){return new PopupSliderCaptcha(t)}static show(t){const i=new PopupSliderCaptcha(t)
|
|
42
|
-
return i.show(),i}}return"undefined"!=typeof module&&module.exports?(module.exports=PopupSliderCaptcha,module.exports.default=PopupSliderCaptcha):"function"==typeof define&&define.amd?define([],()=>PopupSliderCaptcha):"undefined"!=typeof window&&(window.PopupSliderCaptcha=PopupSliderCaptcha,window.SliderCaptcha=PopupSliderCaptcha),PopupSliderCaptcha})
|
|
41
|
+
t&&t.remove(),Object.keys(this).forEach((t=>{"constructor"!==t&&(this[t]=null)}))}static create(t){return new PopupSliderCaptcha(t)}static show(t){const i=new PopupSliderCaptcha(t)
|
|
42
|
+
return i.show(),i}}return"undefined"!=typeof module&&module.exports?(module.exports=PopupSliderCaptcha,module.exports.default=PopupSliderCaptcha):"function"==typeof define&&define.amd?define([],(()=>PopupSliderCaptcha)):"undefined"!=typeof window&&(window.PopupSliderCaptcha=PopupSliderCaptcha,window.SliderCaptcha=PopupSliderCaptcha),PopupSliderCaptcha}))
|
|
43
|
+
//# sourceMappingURL=slider-captcha.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slider-captcha.min.js","sources":["../src/slider-captcha.js"],"sourcesContent":["/**\n * 纯JavaScript弹窗滑块验证码组件\n */\nclass PopupSliderCaptcha {\n static DEFAULTS = {\n width: 320,\n height: 155,\n sliderSize: 38,\n maxRetries: 3,\n timeout: 30000,\n apiUrl: \"/api/captcha\",\n verifyUrl: \"/api/captcha/verify\",\n throttleDelay: 16,\n clickMaskClose: false\n }\n\n static CSS_CLASSES = {\n overlay: \"slider-captcha-overlay\",\n modal: \"slider-captcha-modal\",\n header: \"slider-captcha-header\",\n container: \"slider-captcha-container\",\n track: \"slider-captcha-track\",\n btn: \"slider-captcha-btn\",\n hint: \"slider-captcha-hint\",\n loading: \"slider-captcha-loading\",\n error: \"slider-captcha-error\"\n }\n\n // 优化:提取CSS样式为独立方法,减少主体代码长度\n static getStyles() {\n return `:root{--sc-primary:#409eff;--sc-success:#67c23a;--sc-danger:#f56c6c;--sc-border:#e4e7eb;--sc-bg:linear-gradient(90deg, #f7f9fa 0%, #e8f4fd 100%);--sc-text:#333;--sc-text-light:#999;--sc-shadow:0 4px 20px rgba(0,0,0,.3);--sc-radius:8px;--sc-transition:.3s ease}.slider-captcha-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);z-index:9999;display:none;justify-content:center;align-items:center;opacity:0;transition:opacity var(--sc-transition)}.slider-captcha-overlay.show{opacity:1}.slider-captcha-modal{background:#fff;border-radius:var(--sc-radius);padding:20px;box-shadow:var(--sc-shadow);position:relative;max-width:90vw;max-height:90vh;transform:scale(.8) translateY(-20px);opacity:0;transition:all var(--sc-transition)}.slider-captcha-modal.show{transform:scale(1) translateY(0);opacity:1}.slider-captcha-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:15px;padding-bottom:10px;border-bottom:1px solid var(--sc-border)}.slider-captcha-container{display:flex;align-items:center;position:relative;border-radius:4px;overflow:hidden;margin-bottom:15px;background:#837a7a;justify-content:center}.slider-captcha-track{width:100%;height:40px;line-height:40px;background:var(--sc-bg);border:1px solid var(--sc-border);border-radius:20px;position:relative;margin-bottom:15px;overflow:hidden}.slider-captcha-btn{width:38px;height:38px;background:#fff;border:1px solid #ccc;border-radius:50%;position:absolute;top:0;left:0;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 4px rgba(0,0,0,.1);transition:all var(--sc-transition);user-select:none;z-index:1}.slider-captcha-loading{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(255,255,255,.6);display:flex;align-items:center;justify-content:center;flex-direction:column;color:#666;font-size:14px;z-index:10;border-radius:4px}.slider-captcha-error{color:var(--sc-danger);font-size:12px;text-align:center;margin-top:10px;display:none}.slider-captcha-title{margin:0;font-size:16px;color:var(--sc-text)}.slider-captcha-close,.slider-captcha-refresh{background:none;border:none;cursor:pointer;color:var(--sc-text-light);padding:0;width:30px;height:30px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:all var(--sc-transition);position:relative;font-size:0}.slider-captcha-close::before,.slider-captcha-close::after{content:'';position:absolute;width:16px;height:2px;background-color:var(--sc-text-light);border-radius:1px;transition:all var(--sc-transition)}.slider-captcha-close::before{transform:rotate(45deg)}.slider-captcha-close::after{transform:rotate(-45deg)}.slider-captcha-close:hover{background:#f5f5f5;transform:scale(1.1)}.slider-captcha-close:hover::before,.slider-captcha-close:hover::after{background-color:var(--sc-danger)}.slider-captcha-refresh{margin-left:10px}.slider-captcha-refresh svg{width:20px;height:20px;fill:var(--sc-text-light);transition:all var(--sc-transition)}.slider-captcha-refresh:hover{background:#f5f5f5;transform:scale(1.1)}.slider-captcha-refresh:hover svg{fill:var(--sc-primary);transform:rotate(180deg)}.slider-captcha-floating-time{position:absolute;bottom:-40px;left:50%;transform:translateX(-50%);color:#fff;font-size:12px;white-space:nowrap;opacity:0;pointer-events:none;z-index:10;transition:all var(--sc-transition);background:#fff;padding:2px 15px;border-radius:10px}.slider-captcha-floating-time.show{opacity:1;transform:translateX(-50%) translateY(-45px)}.slider-captcha-floating-time.success{color:var(--sc-success)}.slider-captcha-floating-time.fail{color:var(--sc-danger)}.slider-captcha-bg{width:100%;height:100%;object-fit:cover;display:block}.slider-captcha-piece{position:absolute;top:0;left:0;cursor:pointer;transition:none;z-index:2}.slider-captcha-finger{position:absolute;top:50%;left:10px;transform:translateY(-50%);font-size:20px;animation:fingerSlide 2s ease-in-out infinite;pointer-events:none;z-index:1;opacity:.6}.slider-captcha-hint{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:var(--sc-text-light);font-size:14px;pointer-events:none;z-index:1;transition:all var(--sc-transition)}.slider-captcha-header-buttons{display:flex;align-items:center}@keyframes fingerSlide{0%{left:10px;opacity:.6}50%{opacity:1}100%{left:calc(50% - 10px);opacity:.6}}`\n }\n\n constructor(options = {}) {\n this.options = { ...PopupSliderCaptcha.DEFAULTS, ...options }\n this.elements = {}\n this.state = this.createInitialState()\n this.captchaData = null\n this.times = []\n this.startTime = null\n this.eventListeners = []\n this.timers = new Set()\n this.rafId = null\n this.cachedDimensions = null\n this.imageCache = new Map()\n\n // 优化:使用箭头函数绑定this,避免重复bind调用\n this.throttledHandleMove = this.throttle((e) => this.handleMove(e), this.options.throttleDelay)\n\n this.init()\n }\n\n // 优化:提取初始状态创建为独立方法\n createInitialState() {\n return {\n isVisible: false,\n isDragging: false,\n currentX: 0,\n startX: 0,\n retryCount: 0,\n isLoading: false\n }\n }\n\n init() {\n this.injectStyles()\n this.createElements()\n this.bindEvents()\n }\n\n injectStyles() {\n if (document.querySelector(\"#slider-captcha-styles\")) return\n\n const style = document.createElement(\"style\")\n style.id = \"slider-captcha-styles\"\n style.textContent = PopupSliderCaptcha.getStyles()\n document.head.appendChild(style)\n }\n\n // 优化:简化元素创建逻辑\n createElements() {\n const { elements, options } = this\n\n // 批量创建元素配置\n const elementConfigs = [\n ['overlay', 'div', PopupSliderCaptcha.CSS_CLASSES.overlay],\n ['modal', 'div', PopupSliderCaptcha.CSS_CLASSES.modal],\n ['header', 'div', PopupSliderCaptcha.CSS_CLASSES.header],\n ['title', 'h3', 'slider-captcha-title', '安全验证'],\n ['closeBtn', 'button', 'slider-captcha-close'],\n ['refreshBtn', 'button', 'slider-captcha-refresh'],\n ['container', 'div', PopupSliderCaptcha.CSS_CLASSES.container],\n ['backgroundImg', 'img', 'slider-captcha-bg'],\n ['sliderImg', 'img', 'slider-captcha-piece'],\n ['loadingText', 'div', PopupSliderCaptcha.CSS_CLASSES.loading, '加载中...'],\n ['floatingTime', 'div', 'slider-captcha-floating-time'],\n ['track', 'div', PopupSliderCaptcha.CSS_CLASSES.track],\n ['fingerAnimation', 'div', 'slider-captcha-finger', '👉'],\n ['btn', 'div', PopupSliderCaptcha.CSS_CLASSES.btn],\n ['icon', 'div', '', '→'],\n ['hint', 'div', PopupSliderCaptcha.CSS_CLASSES.hint, '向右滑动完成验证'],\n ['error', 'div', PopupSliderCaptcha.CSS_CLASSES.error]\n ]\n\n // 批量创建元素\n elementConfigs.forEach(([key, tag, className, textContent]) => {\n elements[key] = this.createElement(tag, className, textContent)\n })\n\n // 设置容器尺寸\n elements.container.style.cssText = `width:${options.width}px;height:${options.height}px`\n\n // 添加刷新按钮图标\n elements.refreshBtn.innerHTML = `<svg viewBox=\"0 0 24 24\"><path d=\"M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z\"/></svg>`\n\n this.assembleDOM()\n this.setInitialState()\n }\n\n createElement(tag, className = \"\", textContent = \"\") {\n const element = document.createElement(tag)\n if (className) element.className = className\n if (textContent) element.textContent = textContent\n return element\n }\n\n // 优化:简化DOM组装逻辑\n assembleDOM() {\n const { elements } = this\n\n // 组装头部\n const headerButtons = this.createElement(\"div\", \"slider-captcha-header-buttons\")\n headerButtons.append(elements.refreshBtn, elements.closeBtn)\n elements.header.append(elements.title, headerButtons)\n\n // 组装验证码容器\n elements.container.append(\n elements.backgroundImg,\n elements.sliderImg,\n elements.loadingText,\n elements.floatingTime\n )\n\n // 组装滑块轨道\n elements.btn.appendChild(elements.icon)\n elements.track.append(\n elements.fingerAnimation,\n elements.btn,\n elements.hint\n )\n\n // 组装模态框\n elements.modal.append(\n elements.header,\n elements.container,\n elements.track,\n elements.error\n )\n\n // 组装到覆盖层\n elements.overlay.appendChild(elements.modal)\n document.body.appendChild(elements.overlay)\n }\n\n setInitialState() {\n // 批量设置初始状态\n Object.assign(this.elements.container.style, { display: \"none\" })\n Object.assign(this.elements.track.style, { display: \"none\" })\n }\n\n // 优化:简化事件绑定\n bindEvents() {\n const { elements } = this\n\n // 基础事件\n this.addEventListener(elements.closeBtn, \"click\", () => this.hide())\n this.addEventListener(elements.refreshBtn, \"click\", () => this.refresh())\n this.addEventListener(elements.overlay, \"click\", (e) => {\n if (e.target === elements.overlay && this.options.clickMaskClose) this.hide()\n })\n this.addEventListener(document, \"keydown\", (e) => {\n if (e.key === \"Escape\" && this.state.isVisible) this.hide()\n })\n this.addEventListener(document, \"visibilitychange\", () => this.handleVisibilityChange())\n\n this.bindSliderEvents()\n }\n\n bindSliderEvents() {\n const { elements } = this\n const handlers = {\n start: (e) => this.handleStart(e),\n move: this.throttledHandleMove,\n end: () => this.handleEnd()\n }\n\n // 滑块事件\n this.addEventListener(elements.btn, \"mousedown\", handlers.start)\n this.addEventListener(elements.btn, \"touchstart\", handlers.start)\n this.addEventListener(elements.sliderImg, \"mousedown\", handlers.start)\n this.addEventListener(elements.sliderImg, \"touchstart\", handlers.start)\n this.addEventListener(document, \"mousemove\", handlers.move, { passive: false })\n this.addEventListener(document, \"touchmove\", handlers.move, { passive: false })\n this.addEventListener(document, \"mouseup\", handlers.end)\n this.addEventListener(document, \"touchend\", handlers.end)\n }\n\n // 优化:改进事件管理\n addEventListener(element, event, handler, options = {}) {\n if (!element || typeof handler !== 'function') return\n\n element.addEventListener(event, handler, options)\n this.eventListeners.push({ element, event, handler, options })\n }\n\n removeAllEventListeners() {\n this.eventListeners.forEach(({ element, event, handler, options }) => {\n try {\n element?.removeEventListener?.(event, handler, options)\n } catch (error) {\n console.warn('Failed to remove event listener:', error)\n }\n })\n this.eventListeners.length = 0\n }\n\n // 优化:缓存尺寸计算\n getDimensions() {\n if (!this.cachedDimensions) {\n const trackWidth = this.elements.track.offsetWidth\n const btnWidth = this.elements.btn.offsetWidth\n this.cachedDimensions = {\n trackWidth,\n btnWidth,\n maxX: trackWidth - btnWidth\n }\n }\n return this.cachedDimensions\n }\n\n getPosition() {\n const { maxX } = this.getDimensions()\n const percentage = this.state.currentX / maxX\n return Math.round(percentage * (this.options.width - this.options.sliderSize))\n }\n\n // 优化:简化拖拽处理\n handleStart(e) {\n if (!this.captchaData || this.state.isDragging || this.state.isLoading) return\n\n e.preventDefault()\n this.state.isDragging = true\n this.state.startX = this.getClientX(e) - this.state.currentX\n this.startTime = this.startTime || Date.now()\n this.times = [{ time: Date.now(), position: this.getPosition() }]\n\n this.setTransition(false)\n this.updateUIState(\"dragging\")\n this.cachedDimensions = null // 清除缓存\n }\n\n handleMove(e) {\n if (!this.state.isDragging) return\n e.preventDefault()\n\n const clientX = this.getClientX(e)\n const deltaX = clientX - this.state.startX\n const { maxX } = this.getDimensions()\n\n this.state.currentX = Math.max(0, Math.min(deltaX, maxX))\n this.times.push({ time: Date.now(), position: this.getPosition() })\n\n // 优化:使用RAF批量更新\n this.rafId && cancelAnimationFrame(this.rafId)\n this.rafId = requestAnimationFrame(() => this.updateSliderPosition())\n }\n\n handleEnd() {\n if (!this.state.isDragging) return\n\n this.times.push({ time: Date.now(), position: this.getPosition() })\n this.state.isDragging = false\n\n if (this.rafId) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n\n this.verify()\n }\n\n handleVisibilityChange() {\n const animationState = document.hidden ? 'paused' : 'running'\n if (this.elements.fingerAnimation) {\n this.elements.fingerAnimation.style.animationPlayState = animationState\n }\n }\n\n getClientX(e) {\n return e.type.includes(\"touch\") ? e.touches[0].clientX : e.clientX\n }\n\n setTransition(enabled) {\n const transition = enabled ? \"all 0.3s ease\" : \"none\"\n requestAnimationFrame(() => {\n this.elements.btn.style.transition = transition\n this.elements.sliderImg.style.transition = transition\n })\n }\n\n // 优化:简化UI状态更新\n updateUIState(state) {\n const { elements } = this\n const updates = {\n dragging: () => {\n elements.hint.style.opacity = \"0\"\n elements.fingerAnimation.style.display = \"none\"\n },\n success: () => {\n Object.assign(elements.btn.style, { background: \"var(--sc-success)\" })\n Object.assign(elements.icon.style, { innerHTML: \"✓\", color: \"white\" })\n elements.icon.innerHTML = \"✓\"\n },\n fail: () => {\n Object.assign(elements.btn.style, { background: \"var(--sc-danger)\" })\n Object.assign(elements.icon.style, { innerHTML: \"✗\", color: \"white\" })\n elements.icon.innerHTML = \"✗\"\n },\n reset: () => {\n Object.assign(elements.btn.style, { background: \"white\" })\n Object.assign(elements.icon.style, { color: \"#666\" })\n elements.icon.innerHTML = \"→\"\n elements.fingerAnimation.style.display = \"block\"\n this.updateHintText(\"向右滑动完成验证\", \"var(--sc-text-light)\")\n },\n loading: () => {\n elements.hint.style.opacity = \"0\"\n elements.fingerAnimation.style.display = \"none\"\n Object.assign(elements.track.style, { pointerEvents: \"none\", opacity: \"0.6\" })\n }\n }\n\n if (updates[state]) {\n requestAnimationFrame(() => {\n updates[state]()\n if (state !== \"loading\") {\n Object.assign(elements.track.style, { pointerEvents: \"auto\", opacity: \"1\" })\n }\n })\n }\n }\n\n updateHintText(text, color) {\n requestAnimationFrame(() => {\n Object.assign(this.elements.hint, { textContent: text })\n Object.assign(this.elements.hint.style, { color, opacity: \"1\" })\n })\n }\n\n updateSliderPosition() {\n const { elements, options, state } = this\n const { maxX } = this.getDimensions()\n const pieceX = (state.currentX / maxX) * (options.width - options.sliderSize)\n const progress = state.currentX / maxX\n\n requestAnimationFrame(() => {\n elements.btn.style.transform = `translateX(${state.currentX}px)`\n elements.sliderImg.style.transform = `translateX(${pieceX}px)`\n elements.fingerAnimation.style.opacity = progress >= 0.8 ? \"0\" : \"0.6\"\n })\n }\n\n // 优化:简化显示/隐藏逻辑\n show() {\n this.state.isVisible = true\n this.elements.overlay.style.display = \"flex\"\n this.elements.overlay.offsetHeight // 强制重绘\n\n requestAnimationFrame(() => {\n this.elements.overlay.classList.add(\"show\")\n this.elements.modal.classList.add(\"show\")\n })\n\n this.loadCaptcha()\n }\n\n hide() {\n this.state.isVisible = false\n this.elements.overlay.classList.remove(\"show\")\n this.elements.modal.classList.remove(\"show\")\n\n this.safeSetTimeout(() => {\n this.elements.overlay.style.display = \"none\"\n document.body.removeChild(this.elements.overlay)\n this.reset()\n this.options.onClose?.()\n this.elements.overlay = null\n }, 300)\n }\n\n // 优化:简化加载逻辑\n async loadCaptcha() {\n try {\n this.showLoading()\n this.startTime = Date.now()\n\n const controller = new AbortController()\n const timeoutId = this.safeSetTimeout(() => controller.abort(), this.options.timeout)\n\n const response = await fetch(this.options.apiUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ place: 2, timestamp: Date.now() }),\n signal: controller.signal\n })\n\n this.safeClearTimeout(timeoutId)\n\n if (!response.ok) throw new Error(`HTTP ${response.status}`)\n const data = await response.json()\n\n if (data.data?.canvasSrc && data.data?.blockSrc) {\n this.captchaData = data.data\n this.showCaptcha()\n await this.renderCaptcha()\n } else {\n throw new Error(\"验证码数据格式错误\")\n }\n } catch (error) {\n const message = error.name === 'AbortError' ? \"请求超时,请重试\" : `加载验证码失败: ${error.message}`\n this.showError(message)\n }\n }\n\n async renderCaptcha() {\n return new Promise((resolve, reject) => {\n let loadedCount = 0\n const onLoad = () => ++loadedCount === 2 && (this.hideLoading(), resolve())\n const onError = () => reject(new Error(\"图片加载失败\"))\n\n this.loadImage(this.elements.backgroundImg, this.captchaData.canvasSrc, {\n width: this.captchaData.canvasWidth,\n height: this.captchaData.canvasHeight\n }, onLoad, onError)\n\n this.loadImage(this.elements.sliderImg, this.captchaData.blockSrc, {\n width: this.captchaData.blockWidth,\n height: this.captchaData.blockHeight,\n top: this.captchaData.blockY\n }, onLoad, onError)\n })\n }\n\n loadImage(imgElement, src, styles, onLoad, onError) {\n // 检查缓存\n if (this.imageCache.has(src)) {\n const cachedImg = this.imageCache.get(src)\n imgElement.src = cachedImg.src\n this.applyStyles(imgElement, styles)\n onLoad()\n return\n }\n\n imgElement.onload = () => {\n this.imageCache.set(src, imgElement.cloneNode())\n onLoad()\n }\n imgElement.onerror = onError\n imgElement.src = src\n this.applyStyles(imgElement, styles)\n }\n\n // 优化:提取样式应用逻辑\n applyStyles(element, styles) {\n Object.entries(styles).forEach(([key, value]) => {\n element.style[key] = typeof value === \"number\" ? value + \"px\" : value\n })\n }\n\n // 优化:简化状态显示方法\n showLoading() {\n this.state.isLoading = true\n this.batchUpdateStyles({\n container: { display: \"block\" },\n loadingText: { display: \"flex\" },\n error: { display: \"none\" }\n })\n this.updateUIState(\"loading\")\n }\n\n hideLoading() {\n this.state.isLoading = false\n this.batchUpdateStyles({ loadingText: { display: \"none\" } })\n this.updateUIState(\"reset\")\n }\n\n showCaptcha() {\n this.batchUpdateStyles({\n container: { display: \"block\" },\n track: { display: \"block\" },\n error: { display: \"none\" }\n })\n }\n\n showError(message) {\n this.hideLoading()\n this.batchUpdateStyles({\n error: { display: \"block\", textContent: message }\n })\n }\n\n // 优化:批量样式更新\n batchUpdateStyles(updates) {\n requestAnimationFrame(() => {\n Object.entries(updates).forEach(([elementKey, styles]) => {\n const element = this.elements[elementKey]\n if (element) {\n Object.entries(styles).forEach(([prop, value]) => {\n if (prop === 'textContent') {\n element.textContent = value\n } else {\n element.style[prop] = value\n }\n })\n }\n })\n })\n }\n\n async verify() {\n if (!this.captchaData) {\n this.onVerifyFail(\"验证码数据丢失\")\n return\n }\n\n try {\n const controller = new AbortController()\n const timeoutId = this.safeSetTimeout(() => controller.abort(), this.options.timeout)\n\n const response = await fetch(this.options.verifyUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n loginVo: {\n nonceStr: this.captchaData.nonceStr,\n value: this.getPosition()\n },\n dragEventList: [...this.times]\n }),\n signal: controller.signal\n })\n\n this.safeClearTimeout(timeoutId)\n\n if (!response.ok) throw new Error(`HTTP ${response.status}`)\n const data = await response.json()\n\n if (data.code === \"0\" || data.success === true) {\n this.onVerifySuccess()\n } else {\n this.onVerifyFail(data.message || \"验证失败,请重试!\")\n }\n } catch (error) {\n const message = error.name === 'AbortError' ? \"验证超时,请重试\" : \"网络错误\"\n this.onVerifyFail(message)\n }\n }\n\n onVerifySuccess() {\n const duration = Date.now() - this.startTime\n const durationText = `验证成功!耗时:${(duration / 1000).toFixed(2)}s`\n\n this.updateUIState(\"success\")\n this.showFloatingTime(durationText, \"success\")\n\n this.safeSetTimeout(() => {\n this.options.onSuccess?.({\n captchaId: this.captchaData.captchaId,\n timestamp: Date.now(),\n duration\n })\n this.hide()\n }, 2000)\n }\n\n showFloatingTime(text, type = \"success\") {\n const { elements } = this\n elements.floatingTime.textContent = text\n elements.floatingTime.className = `slider-captcha-floating-time ${type}`\n\n this.safeSetTimeout(() => elements.floatingTime.classList.add(\"show\"), 100)\n this.safeSetTimeout(() => {\n elements.floatingTime.className = \"slider-captcha-floating-time\"\n }, 2500) // 优化:延长显示时间,避免被reset清除\n }\n\n onVerifyFail(message) {\n this.state.retryCount++\n this.updateUIState(\"fail\")\n this.showFloatingTime(message, \"fail\")\n\n this.safeSetTimeout(() => {\n if (this.state.retryCount >= this.options.maxRetries) {\n this.refresh()\n } else {\n this.reset()\n }\n }, 2500) // 优化:延长等待时间,确保浮动提示完整显示\n }\n\n reset() {\n this.clearAllTimers()\n\n // 重置状态\n Object.assign(this.state, {\n isDragging: false,\n currentX: 0,\n startX: 0,\n isLoading: false\n })\n\n this.times = []\n this.startTime = null\n this.cachedDimensions = null\n\n // 重置UI\n requestAnimationFrame(() => {\n this.setTransition(true)\n this.elements.btn.style.transform = \"translateX(0px)\"\n this.elements.sliderImg.style.transform = \"translateX(0px)\"\n this.updateUIState(\"reset\")\n this.elements.error.style.display = \"none\"\n })\n }\n\n refresh() {\n this.reset()\n this.state.retryCount = 0\n this.loadCaptcha()\n }\n\n // 安全的定时器管理\n safeSetTimeout(callback, delay) {\n const timerId = setTimeout(() => {\n this.timers.delete(timerId)\n callback()\n }, delay)\n this.timers.add(timerId)\n return timerId\n }\n\n safeClearTimeout(timerId) {\n if (timerId) {\n clearTimeout(timerId)\n this.timers.delete(timerId)\n }\n }\n\n clearAllTimers() {\n this.timers.forEach(timer => {\n clearTimeout(timer)\n clearInterval(timer)\n })\n this.timers.clear()\n\n if (this.rafId) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n }\n\n // 清理图片资源\n cleanupImages() {\n if (this.elements.backgroundImg) {\n this.elements.backgroundImg.src = ''\n this.elements.backgroundImg.onload = null\n this.elements.backgroundImg.onerror = null\n }\n if (this.elements.sliderImg) {\n this.elements.sliderImg.src = ''\n this.elements.sliderImg.onload = null\n this.elements.sliderImg.onerror = null\n }\n this.imageCache.clear()\n }\n\n // 工具函数:节流\n throttle(func, delay) {\n let lastCall = 0\n return function (...args) {\n const now = Date.now()\n if (now - lastCall >= delay) {\n lastCall = now\n return func.apply(this, args)\n }\n }\n }\n\n // 工具函数:防抖\n debounce(func, delay) {\n let timeoutId\n return function (...args) {\n clearTimeout(timeoutId)\n timeoutId = setTimeout(() => func.apply(this, args), delay)\n }\n }\n\n destroy() {\n // 恢复body样式\n document.body.style.userSelect = \"\"\n document.body.style.cursor = \"\"\n\n // 清理所有定时器\n this.clearAllTimers()\n\n // 移除所有事件监听器\n this.removeAllEventListeners()\n\n // 清理图片资源\n this.cleanupImages()\n\n // 移除DOM元素\n if (this.elements.overlay?.parentNode) {\n this.elements.overlay.parentNode.removeChild(this.elements.overlay)\n }\n\n // 清理样式表\n const styleElement = document.getElementById('slider-captcha-styles')\n if (styleElement) {\n styleElement.remove()\n }\n\n // 清空所有属性\n Object.keys(this).forEach(key => {\n if (key !== 'constructor') {\n this[key] = null\n }\n })\n }\n\n static create(options) {\n return new PopupSliderCaptcha(options)\n }\n\n static show(options) {\n const instance = new PopupSliderCaptcha(options)\n instance.show()\n return instance\n }\n}\n\n// 模块导出\nif (typeof module !== \"undefined\" && module.exports) {\n module.exports = PopupSliderCaptcha\n module.exports.default = PopupSliderCaptcha\n} else if (typeof define === \"function\" && define.amd) {\n define([], () => PopupSliderCaptcha)\n} else if (typeof window !== \"undefined\") {\n window.PopupSliderCaptcha = PopupSliderCaptcha\n window.SliderCaptcha = PopupSliderCaptcha\n}\n\n// Add ES6 export for modern module systems\nexport default PopupSliderCaptcha\n"],"names":["PopupSliderCaptcha","static","width","height","sliderSize","maxRetries","timeout","apiUrl","verifyUrl","throttleDelay","clickMaskClose","overlay","modal","header","container","track","btn","hint","loading","error","getStyles","constructor","options","this","DEFAULTS","elements","state","createInitialState","captchaData","times","startTime","eventListeners","timers","Set","rafId","cachedDimensions","imageCache","Map","throttledHandleMove","throttle","e","handleMove","init","isVisible","isDragging","currentX","startX","retryCount","isLoading","injectStyles","createElements","bindEvents","document","querySelector","style","createElement","id","textContent","head","appendChild","CSS_CLASSES","forEach","key","tag","className","cssText","refreshBtn","innerHTML","assembleDOM","setInitialState","element","headerButtons","append","closeBtn","title","backgroundImg","sliderImg","loadingText","floatingTime","icon","fingerAnimation","body","Object","assign","display","addEventListener","hide","refresh","target","handleVisibilityChange","bindSliderEvents","handlers","start","handleStart","move","end","handleEnd","passive","event","handler","push","removeAllEventListeners","removeEventListener","length","getDimensions","trackWidth","offsetWidth","btnWidth","maxX","getPosition","percentage","Math","round","preventDefault","getClientX","Date","now","time","position","setTransition","updateUIState","deltaX","max","min","cancelAnimationFrame","requestAnimationFrame","updateSliderPosition","verify","animationState","hidden","animationPlayState","type","includes","touches","clientX","enabled","transition","updates","dragging","opacity","success","background","color","fail","reset","updateHintText","pointerEvents","text","pieceX","progress","transform","show","offsetHeight","classList","add","loadCaptcha","remove","safeSetTimeout","removeChild","onClose","showLoading","controller","AbortController","timeoutId","abort","response","fetch","method","headers","JSON","stringify","place","timestamp","signal","safeClearTimeout","ok","Error","status","data","json","canvasSrc","blockSrc","showCaptcha","renderCaptcha","message","name","showError","Promise","resolve","reject","loadedCount","onLoad","hideLoading","onError","loadImage","canvasWidth","canvasHeight","blockWidth","blockHeight","top","blockY","imgElement","src","styles","has","cachedImg","get","applyStyles","onload","set","cloneNode","onerror","entries","value","batchUpdateStyles","elementKey","prop","loginVo","nonceStr","dragEventList","code","onVerifySuccess","onVerifyFail","duration","durationText","toFixed","showFloatingTime","onSuccess","captchaId","clearAllTimers","callback","delay","timerId","setTimeout","delete","clearTimeout","timer","clearInterval","clear","cleanupImages","func","lastCall","args","apply","debounce","destroy","userSelect","cursor","parentNode","styleElement","getElementById","keys","create","instance","module","exports","default","define","amd","window","SliderCaptcha"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slider-captcha-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "纯JavaScript滑块验证码SDK和密码校验工具,无依赖,支持多种模块格式",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs.js",
|
|
@@ -33,17 +33,14 @@
|
|
|
33
33
|
"LICENSE"
|
|
34
34
|
],
|
|
35
35
|
"scripts": {
|
|
36
|
-
"build": "
|
|
37
|
-
"build:dev": "
|
|
38
|
-
"build:prod": "
|
|
39
|
-
"
|
|
40
|
-
"dev": "rollup -c -w --environment NODE_ENV:development",
|
|
36
|
+
"build": "rollup -c",
|
|
37
|
+
"build:dev": "rollup -c --environment NODE_ENV:development",
|
|
38
|
+
"build:prod": "rollup -c --environment NODE_ENV:production",
|
|
39
|
+
"dev": "rollup -c -w",
|
|
41
40
|
"prepublishOnly": "npm run build:prod",
|
|
42
41
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
43
42
|
"lint": "eslint src --ext .js --fix",
|
|
44
|
-
"clean": "rm -rf dist"
|
|
45
|
-
"analyze": "npx rollup-plugin-visualizer dist/stats.html --open",
|
|
46
|
-
"size": "npm run build:prod && bundlesize"
|
|
43
|
+
"clean": "rm -rf dist"
|
|
47
44
|
},
|
|
48
45
|
"keywords": [
|
|
49
46
|
"captcha",
|
|
@@ -71,12 +68,10 @@
|
|
|
71
68
|
"devDependencies": {
|
|
72
69
|
"@rollup/plugin-node-resolve": "^15.0.0",
|
|
73
70
|
"@rollup/plugin-terser": "^0.4.0",
|
|
74
|
-
"bundlesize": "^0.18.2",
|
|
75
71
|
"eslint": "^8.0.0",
|
|
76
72
|
"eslint-plugin-vue": "^9.0.0",
|
|
77
73
|
"rollup": "^3.0.0",
|
|
78
|
-
"rollup-plugin-copy": "^3.4.0"
|
|
79
|
-
"rollup-plugin-visualizer": "^5.14.0"
|
|
74
|
+
"rollup-plugin-copy": "^3.4.0"
|
|
80
75
|
},
|
|
81
76
|
"dependencies": {
|
|
82
77
|
"jsencrypt": "^3.3.2"
|
|
@@ -87,19 +82,5 @@
|
|
|
87
82
|
},
|
|
88
83
|
"publishConfig": {
|
|
89
84
|
"registry": "https://registry.npmjs.org/"
|
|
90
|
-
}
|
|
91
|
-
"bundlesize": [
|
|
92
|
-
{
|
|
93
|
-
"path": "dist/index.min.js",
|
|
94
|
-
"maxSize": "50 kB"
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
"path": "dist/slider-captcha.min.js",
|
|
98
|
-
"maxSize": "30 kB"
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
"path": "dist/password-validator.min.js",
|
|
102
|
-
"maxSize": "20 kB"
|
|
103
|
-
}
|
|
104
|
-
]
|
|
85
|
+
}
|
|
105
86
|
}
|