mi-float-robot 1.0.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mi-float-robot.js","sources":["../src/styles.js","../src/default-avatar.js","../src/adapter.js","../src/element.js","../src/index.js"],"sourcesContent":["/**\n * Shadow DOM 样式(由原 FloatPopupChat.vue 的 scoped SCSS 扁平化而来)。\n * 使用 Shadow DOM 隔离,避免与宿主页面样式冲突。\n */\nexport const styles = `\n:host {\n all: initial;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;\n}\n\n.robot-icon-box {\n user-select: none;\n touch-action: none;\n position: fixed;\n z-index: 4000;\n transition: transform 0.3s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 8px;\n box-sizing: border-box;\n}\n\n.robot-icon-image {\n display: block;\n max-width: 100%;\n height: auto;\n object-fit: contain;\n}\n\n.robot-drag-mask {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.3);\n z-index: 3999;\n}\n\n.robot-trash-icon {\n position: fixed;\n right: 20px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 40px;\n padding: 10px;\n background: rgba(0, 0, 0, 0.6);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n z-index: 4000;\n}\n\n.robot-trash-icon.active {\n transform: translateY(-50%) scale(1.2);\n background: #ff0000;\n}\n\n.robot-drawer-container {\n position: fixed;\n left: 0;\n top: 0;\n display: flex;\n flex-direction: column;\n background-color: #ffffff;\n z-index: 4000;\n box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n border-radius: 8px;\n transition: width 0.3s ease, height 0.3s ease;\n}\n\n.robot-drawer-container.drawer-dragging {\n transition: none !important;\n}\n\n.drawer-header {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 40px;\n padding: 0 10px 0 14px;\n background: #f5f7fa;\n border-bottom: 1px solid #e4e7ed;\n cursor: move;\n user-select: none;\n touch-action: none;\n z-index: 10001;\n}\n\n.drawer-header-title {\n font-size: 14px;\n font-weight: 600;\n color: #303133;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.drawer-controls {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.drawer-control-btn {\n width: 26px;\n height: 26px;\n border: none;\n background: rgba(255, 255, 255, 0.92);\n color: #606266;\n font-size: 16px;\n line-height: 1;\n cursor: pointer;\n border-radius: 4px;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);\n transition: background 0.2s ease, color 0.2s ease;\n}\n\n.drawer-control-btn:hover {\n background: #e4e7ed;\n}\n\n.drawer-control-btn--close:hover {\n background: #f56c6c;\n color: #fff;\n}\n\n.drawer-body {\n position: relative;\n flex: 1;\n min-height: 0;\n width: 100%;\n}\n\n.robot-iframe {\n width: 100%;\n height: 100%;\n border: none;\n display: block;\n}\n\n.robot-drawer-container.drawer-dragging .robot-iframe {\n pointer-events: none;\n}\n\n.robot-loading-mask {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #ffffff;\n z-index: 9000;\n}\n\n.robot-loading-spinner {\n width: 28px;\n height: 28px;\n border: 3px solid #dce6f0;\n border-top-color: #409eff;\n border-radius: 50%;\n animation: float-robot-spin 0.8s linear infinite;\n}\n\n@keyframes float-robot-spin {\n to { transform: rotate(360deg); }\n}\n\n.drawer-resize {\n position: absolute;\n z-index: 10000;\n touch-action: none;\n}\n\n.drawer-resize-w { left: 0; top: 0; bottom: 0; width: 6px; cursor: ew-resize; }\n.drawer-resize-e { right: 0; top: 0; bottom: 0; width: 6px; cursor: ew-resize; }\n.drawer-resize-h { left: 0; right: 0; bottom: 0; height: 6px; cursor: ns-resize; }\n.drawer-resize-sw { left: 0; bottom: 0; width: 16px; height: 16px; cursor: nesw-resize; }\n.drawer-resize-se { right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; }\n\n.minimized-chat {\n position: fixed;\n right: 24px;\n bottom: 24px;\n z-index: 4001;\n display: inline-flex;\n align-items: center;\n height: 40px;\n padding: 0 14px;\n border: 1px solid #d9e6ff;\n border-radius: 20px;\n background: #ffffff;\n color: #315b9d;\n box-shadow: 0 6px 18px rgba(28, 67, 128, 0.2);\n cursor: pointer;\n font-size: 14px;\n font-family: inherit;\n transition: box-shadow 0.2s ease, transform 0.2s ease;\n}\n\n.minimized-chat:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 22px rgba(28, 67, 128, 0.28);\n}\n\n.minimized-chat:focus {\n outline: none;\n box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.25), 0 6px 18px rgba(28, 67, 128, 0.2);\n}\n`\n","/**\n * 默认头像:内联 SVG(data URI),避免额外资源文件依赖。\n * 使用方可通过 configure({ avatar }) 或 <x-float-robot avatar=\"...\"> 覆盖。\n */\nconst svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\">\n <rect width=\"64\" height=\"64\" rx=\"14\" fill=\"#409eff\"/>\n <rect x=\"27\" y=\"10\" width=\"10\" height=\"6\" rx=\"3\" fill=\"#c7ddf5\"/>\n <circle cx=\"23\" cy=\"30\" r=\"5\" fill=\"#ffffff\"/>\n <circle cx=\"41\" cy=\"30\" r=\"5\" fill=\"#ffffff\"/>\n <rect x=\"24\" y=\"42\" width=\"16\" height=\"5\" rx=\"2.5\" fill=\"#ffffff\"/>\n</svg>`\n\nexport const defaultAvatar = `data:image/svg+xml,${encodeURIComponent(svg)}`\n","/**\n * 适配器基类:组件通过它获取「是否显示」与「头像/样式配置」。\n * 使用方可以继承本类实现自定义逻辑(例如对接公司内部 RPC 接口),\n * 再通过 configure({ adapter }) 或 <x-float-robot> 的属性注入。\n */\nexport class FloatRobotAdapter {\n /**\n * 是否显示机器人图标。\n * @returns {Promise<boolean>|boolean}\n */\n async getSwitch() {\n return true\n }\n\n /**\n * 获取机器人配置;返回 null 表示没有可用配置(不显示)。\n * @returns {Promise<Object|null>|Object|null}\n *\n * 约定返回结构:\n * {\n * showRobot: true, // 是否显示机器人图标\n * avatar: 'https://...', // 头像完整 URL(可选,缺省用默认头像)\n * style: { // 图标样式(全部可选)\n * scale: 1,\n * width: 80,\n * height: 100,\n * opacity: 1,\n * border: 'none',\n * shadowLevel: 'light', // none | light | medium | strong\n * borderRadius: 0,\n * borderRadiusUnit: 'px'\n * }\n * }\n */\n async getConfig() {\n return null\n }\n}\n\n/**\n * 默认 fetch 适配器:通过 GET 请求约定的配置接口。\n * 适合没有内部 RPC 基础设施、愿意提供一个简单 JSON 接口的项目。\n */\nexport class FetchFloatRobotAdapter extends FloatRobotAdapter {\n constructor(options = {}) {\n super()\n this.switchUrl = options.switchUrl || options.switch_url || ''\n this.configUrl = options.configUrl || options.config_url || ''\n this.fetchImpl = options.fetch || ((url) => window.fetch(url, { credentials: 'include' }))\n }\n\n async getSwitch() {\n if (!this.switchUrl) return true\n const res = await this.fetchImpl(this.switchUrl)\n const json = await this._toJson(res)\n return this._normalizeSwitch(json)\n }\n\n async getConfig() {\n if (!this.configUrl) return null\n const res = await this.fetchImpl(this.configUrl)\n const json = await this._toJson(res)\n return this._normalizeConfig(json)\n }\n\n async _toJson(res) {\n if (res && typeof res.json === 'function') return res.json()\n return res\n }\n\n _normalizeSwitch(json) {\n if (typeof json === 'boolean') return json\n if (json && typeof json === 'object') {\n if (typeof json.showRobot === 'boolean') return json.showRobot\n if (typeof json.enabled === 'boolean') return json.enabled\n // 兼容 { value: '{\"smi-idb\":1}' } 这类字符串配置\n if (json.value != null) {\n const parsed = this._parseValue(json.value)\n if (parsed && typeof parsed === 'object') {\n const vals = Object.values(parsed)\n return vals.length > 0 && vals.every(v => Number(v) === 1)\n }\n return Boolean(parsed)\n }\n }\n return true\n }\n\n _normalizeConfig(json) {\n if (!json) return null\n // 允许返回被 { data: ... } / { result: { data: ... } } 包裹一层\n let data = json\n if (Array.isArray(data)) data = data[0]\n while (data && typeof data === 'object' && !Object.prototype.hasOwnProperty.call(data, 'avatar') && !Object.prototype.hasOwnProperty.call(data, 'style') && !Object.prototype.hasOwnProperty.call(data, 'showRobot')) {\n if (Array.isArray(data.data)) { data = data.data[0]; continue }\n if (data.data && typeof data.data === 'object') { data = data.data; continue }\n if (data.result && typeof data.result === 'object') { data = data.result; continue }\n break\n }\n if (!data || typeof data !== 'object') return null\n return data\n }\n\n _parseValue(value) {\n if (value == null) return value\n const str = String(value)\n try {\n return JSON.parse(str.replace(/'/g, '\"'))\n } catch (e) {\n return value\n }\n }\n}\n","import { styles } from './styles.js'\nimport { defaultAvatar } from './default-avatar.js'\nimport { FetchFloatRobotAdapter } from './adapter.js'\n\nconst DRAWER_MIN_WIDTH = 560\nconst DRAWER_MIN_HEIGHT = 400\nconst GLOBAL_KEY = '__FLOAT_ROBOT_CONFIG__'\n\nfunction getGlobalConfig() {\n return (typeof window !== 'undefined' && window[GLOBAL_KEY]) || {}\n}\n\n/**\n * 浮窗智能问答机器人 Web Component。\n * 通过 <x-float-robot> 使用,配置可由 HTML 属性或 configure() 注入。\n */\nexport class FloatRobotElement extends HTMLElement {\n constructor() {\n super()\n this.attachShadow({ mode: 'open' })\n\n // 图标尺寸\n this.imgWidth = 80\n this.imgHeight = 100\n this.imageAspectRatio = 1.25\n\n // 抽屉状态\n this.drawerVisible = false\n this.drawerMinimized = false\n this.drawerLeft = null\n this.drawerTop = null\n this.drawerWidth = null\n this.drawerHeight = null\n this.drawerDrag = null\n\n // 图标拖拽状态\n this.posX = 0\n this.posY = 0\n this.isDragging = false\n this.dragPointerId = null\n this.startX = 0\n this.startY = 0\n this.initialX = 0\n this.initialY = 0\n this.hasDragged = false\n this.hasMoved = false\n this.dragMaskVisible = false\n this.isHidden = false\n this.isOverTrash = false\n this.windowWidth = 0\n this.windowHeight = 0\n this.originalPosX = 0\n this.originalPosY = 0\n\n // 配置与可见性\n this.showRobot = false\n this.robotAvatar = ''\n this.robotStyleConfig = null\n this.robotShowEnabled = true\n this._switchEnabled = true\n this._configAvailable = true\n this._adapter = null\n\n // loading 与定时器\n this.chatLoading = false\n this.chatLoadingTimer = null\n this.resizeTimer = null\n\n // 需要反复绑定/解绑的监听器,用箭头函数字段保证引用一致\n this._onIconDrag = (e) => this.onIconDrag(e)\n this._stopIconDrag = (e) => this.stopIconDrag(e)\n this._onDrawerDrag = (e) => this.onDrawerDrag(e)\n this._stopDrawerDrag = () => this.stopDrawerDrag()\n this._handleResize = () => this.handleResize()\n this._handleStorageChange = (e) => this.handleStorageChange(e)\n this._handleWindowBlur = () => this.handleWindowBlur()\n this._chatReadyHandler = (e) => this.chatReadyHandler(e)\n }\n\n // ==================== 生命周期 ====================\n\n connectedCallback() {\n this.render()\n window.addEventListener('message', this._chatReadyHandler)\n this.initRobot()\n }\n\n disconnectedCallback() {\n this.removeIconDragListeners()\n this.removeDrawerDragListeners()\n window.removeEventListener('resize', this._handleResize)\n window.removeEventListener('storage', this._handleStorageChange)\n window.removeEventListener('blur', this._handleWindowBlur)\n window.removeEventListener('message', this._chatReadyHandler)\n if (this.chatLoadingTimer) {\n clearTimeout(this.chatLoadingTimer)\n this.chatLoadingTimer = null\n }\n if (this.resizeTimer) {\n clearTimeout(this.resizeTimer)\n this.resizeTimer = null\n }\n }\n\n // ==================== 配置解析 ====================\n\n getAttr(name) {\n return this.getAttribute(name) || ''\n }\n\n resolveChatUrl() {\n const global = getGlobalConfig()\n return this.getAttr('chat-url') || global.chatUrl || ''\n }\n\n resolveAvatar() {\n const global = getGlobalConfig()\n return this.getAttr('avatar') || global.avatar || defaultAvatar\n }\n\n resolveAdapter() {\n const global = getGlobalConfig()\n if (global.adapter) return global.adapter\n const switchUrl = this.getAttr('switch-url') || global.switchUrl || ''\n const configUrl = this.getAttr('config-url') || global.configUrl || ''\n if (switchUrl || configUrl) {\n return new FetchFloatRobotAdapter({ switchUrl, configUrl, fetch: global.fetch })\n }\n return null\n }\n\n async initRobot() {\n const adapter = this.resolveAdapter()\n this._adapter = adapter\n\n if (adapter) {\n try {\n this._switchEnabled = !!(await adapter.getSwitch())\n } catch (e) {\n console.warn('[mi-float-robot] 获取机器人开关失败', e)\n this._switchEnabled = false\n }\n if (!this._switchEnabled) return\n\n try {\n const config = await adapter.getConfig()\n if (config) {\n this.applyConfig(config)\n } else {\n this._configAvailable = false\n }\n } catch (e) {\n console.warn('[mi-float-robot] 获取机器人配置失败', e)\n }\n }\n\n // 静态头像兜底(config 未提供 avatar 时使用 attribute / configure / 默认值)\n if (!this.robotAvatar) {\n this.robotAvatar = this.resolveAvatar()\n this.loadImageAspectRatio(this.robotAvatar)\n }\n\n let savedPos = null\n try {\n savedPos = JSON.parse(localStorage.getItem('robotPosition'))\n } catch (e) {\n savedPos = null\n }\n\n if (savedPos) {\n this.posX = savedPos.x * window.innerWidth\n this.posY = savedPos.y * window.innerHeight\n this.isHidden = savedPos.isHidden\n } else {\n this.setInitialPosition()\n }\n\n this.restoreDrawerPosition(savedPos)\n this.windowWidth = window.innerWidth\n this.windowHeight = window.innerHeight\n this.originalPosX = this.posX\n this.originalPosY = this.posY\n\n window.addEventListener('resize', this._handleResize)\n window.addEventListener('storage', this._handleStorageChange)\n window.addEventListener('blur', this._handleWindowBlur)\n\n this.updateRobotVisibility()\n this.applyIconStyle()\n }\n\n applyConfig(config) {\n if (!config) return\n if (config.avatar) {\n this.robotAvatar = config.avatar\n this.loadImageAspectRatio(config.avatar)\n }\n if (config.style) {\n this.robotStyleConfig = config.style\n }\n if (config.showRobot !== undefined) {\n this.robotShowEnabled = config.showRobot\n }\n // 兼容 style 直接平铺在顶层的情况\n if (config.width) this.imgWidth = config.width\n if (config.height) this.imgHeight = config.height\n if (config.scale) this.robotStyleConfig = { ...(this.robotStyleConfig || {}), scale: config.scale }\n }\n\n loadImageAspectRatio(url) {\n const img = new Image()\n img.onload = () => {\n if (img.width > 0 && img.height > 0) {\n this.imageAspectRatio = img.height / img.width\n }\n }\n img.onerror = () => {}\n img.src = url\n }\n\n handleStorageChange(e) {\n if (e.key !== 'robotConfigLive') return\n try {\n const config = JSON.parse(e.newValue)\n this.applyConfig(config)\n if (config.showRobot !== undefined) {\n this._configAvailable = true\n this.robotShowEnabled = config.showRobot\n this.updateRobotVisibility()\n this.applyIconStyle()\n }\n } catch (err) {\n console.warn('[mi-float-robot] 解析配置失败', err)\n }\n }\n\n updateRobotVisibility() {\n this.showRobot = this._switchEnabled && this._configAvailable && this.robotShowEnabled\n }\n\n // ==================== 样式计算 ====================\n\n currentScale() {\n return (this.robotStyleConfig && this.robotStyleConfig.scale) || 1\n }\n\n baseWidth() {\n return (this.robotStyleConfig && this.robotStyleConfig.width) || this.imgWidth\n }\n\n currentWidth() {\n return this.baseWidth() * this.currentScale()\n }\n\n currentHeight() {\n return this.baseWidth() * this.imageAspectRatio * this.currentScale()\n }\n\n applyIconStyle() {\n const config = this.robotStyleConfig || {}\n const shadowMap = {\n none: 'none',\n light: '0 2px 8px rgba(0, 0, 0, 0.08)',\n medium: '0 4px 16px rgba(0, 0, 0, 0.12)',\n strong: '0 6px 24px rgba(0, 0, 0, 0.18)'\n }\n const width = config.width || this.imgWidth\n const scale = config.scale || 1\n\n this.$icon.style.display = this.showRobot ? 'flex' : 'none'\n this.$icon.style.left = this.posX + 'px'\n this.$icon.style.top = this.posY + 'px'\n this.$icon.style.width = width + 'px'\n this.$icon.style.height = 'auto'\n this.$icon.style.border = config.border || 'none'\n this.$icon.style.boxShadow = shadowMap[config.shadowLevel] || 'none'\n this.$icon.style.opacity = config.opacity != null ? config.opacity : 1\n this.$icon.style.transform = (this.isHidden ? 'rotate(-90deg) ' : '') + 'scale(' + scale + ')'\n this.$icon.style.cursor = 'move'\n\n let borderRadius = '0'\n if (config.borderRadius !== undefined) {\n borderRadius = typeof config.borderRadius === 'string'\n ? config.borderRadius\n : (config.borderRadius || 0) + (config.borderRadiusUnit || 'px')\n }\n this.$iconImage.style.width = width + 'px'\n this.$iconImage.style.height = 'auto'\n this.$iconImage.style.objectFit = 'contain'\n this.$iconImage.style.borderRadius = borderRadius\n this.$iconImage.src = this.robotAvatar || defaultAvatar\n }\n\n defaultDrawerWidth() {\n return Math.round(window.innerWidth * 0.8)\n }\n\n defaultDrawerHeight() {\n return window.innerHeight\n }\n\n applyDrawerStyle() {\n const width = this.drawerWidth != null ? this.drawerWidth : this.defaultDrawerWidth()\n const height = this.drawerHeight != null ? this.drawerHeight : this.defaultDrawerHeight()\n const left = this.drawerLeft != null ? this.drawerLeft : window.innerWidth - width\n const top = this.drawerTop != null ? this.drawerTop : 0\n this.$drawer.style.left = left + 'px'\n this.$drawer.style.top = top + 'px'\n this.$drawer.style.width = width + 'px'\n this.$drawer.style.height = height + 'px'\n }\n\n applyDrawerVisibility() {\n this.$drawer.style.display = this.drawerVisible && !this.drawerMinimized ? 'flex' : 'none'\n this.$minimized.style.display = this.drawerVisible && this.drawerMinimized ? 'inline-flex' : 'none'\n }\n\n // ==================== 抽屉交互 ====================\n\n openDrawer() {\n if (this.hasMoved) return\n if (this.isHidden) {\n this.setInitialPosition()\n this.isHidden = false\n this.applyIconStyle()\n return\n }\n if (!this.drawerVisible) {\n this.chatLoading = true\n this.$loadingMask.style.display = 'flex'\n this.chatLoadingTimer = setTimeout(() => this.finishChatLoading(), 30000)\n }\n this.drawerVisible = true\n this.drawerMinimized = false\n if (!this.$iframe.src) {\n this.$iframe.src = this.resolveChatUrl()\n }\n this.applyDrawerStyle()\n this.applyDrawerVisibility()\n }\n\n closeDrawer() {\n this.drawerVisible = false\n this.drawerMinimized = false\n this.applyDrawerVisibility()\n this.finishChatLoading()\n }\n\n minimizeDrawer() {\n this.drawerMinimized = true\n this.applyDrawerVisibility()\n }\n\n restoreDrawer() {\n this.drawerMinimized = false\n this.drawerVisible = true\n this.applyDrawerVisibility()\n }\n\n finishChatLoading() {\n this.chatLoading = false\n this.$loadingMask.style.display = 'none'\n if (this.chatLoadingTimer) {\n clearTimeout(this.chatLoadingTimer)\n this.chatLoadingTimer = null\n }\n }\n\n chatReadyHandler(event) {\n if (!event || !event.data || event.data.type !== 'SMI_CHAT_READY') return\n if (this.$iframe && event.source !== this.$iframe.contentWindow) return\n this.finishChatLoading()\n }\n\n // ==================== 图标拖拽 ====================\n\n setInitialPosition() {\n this.originalPosX = window.innerWidth - (window.innerWidth * 0.02) - this.currentWidth()\n this.originalPosY = window.innerHeight - (window.innerHeight * 0.08) - this.currentHeight()\n this.posX = this.originalPosX\n this.posY = this.originalPosY\n }\n\n handleResize() {\n clearTimeout(this.resizeTimer)\n this.resizeTimer = setTimeout(() => {\n if (this.isHidden) {\n const rect = this.$icon.getBoundingClientRect()\n this.posX = window.innerWidth - Math.max(40, rect.width * 0.3)\n this.posY = (window.innerHeight - rect.height) / 2\n this.applyIconStyle()\n return\n }\n\n const newWidth = window.innerWidth\n const newHeight = window.innerHeight\n if (!this.hasDragged) {\n const widthRatio = newWidth / this.windowWidth\n const heightRatio = newHeight / this.windowHeight\n this.posX = this.originalPosX * widthRatio\n this.posY = this.originalPosY * heightRatio\n } else {\n const relativeX = this.posX / this.windowWidth\n const relativeY = this.posY / this.windowHeight\n this.posX = newWidth * relativeX\n this.posY = newHeight * relativeY\n }\n\n const iconWidth = this.$icon.offsetWidth || this.currentWidth()\n this.posX = Math.max(0, Math.min(newWidth - iconWidth, this.posX))\n this.posY = Math.min(newHeight - this.currentHeight(), Math.max(0, this.posY))\n\n this.windowWidth = newWidth\n this.windowHeight = newHeight\n this.originalPosX = this.posX\n this.originalPosY = this.posY\n this.applyIconStyle()\n }, 100)\n }\n\n getEventPoint(event) {\n return event.touches && event.touches.length\n ? event.touches[0]\n : event.changedTouches && event.changedTouches.length\n ? event.changedTouches[0]\n : event\n }\n\n getEventPointerId(event) {\n return event.pointerId !== undefined ? event.pointerId : 'touch'\n }\n\n startIconDrag(event) {\n if (this.isHidden || this.isDragging) return\n const point = this.getEventPoint(event)\n event.preventDefault()\n if (event.pointerId !== undefined && event.currentTarget && event.currentTarget.setPointerCapture) {\n try { event.currentTarget.setPointerCapture(event.pointerId) } catch (e) {}\n }\n this.isDragging = true\n this.dragPointerId = this.getEventPointerId(event)\n this.startX = point.clientX\n this.startY = point.clientY\n this.initialX = this.posX\n this.initialY = this.posY\n this.dragMaskVisible = true\n this.$mask.style.display = 'block'\n document.addEventListener('pointermove', this._onIconDrag, { passive: false })\n document.addEventListener('pointerup', this._stopIconDrag)\n document.addEventListener('pointercancel', this._stopIconDrag)\n document.addEventListener('touchmove', this._onIconDrag, { passive: false })\n document.addEventListener('touchend', this._stopIconDrag)\n document.addEventListener('touchcancel', this._stopIconDrag)\n }\n\n onIconDrag(event) {\n if (!this.isDragging || this.getEventPointerId(event) !== this.dragPointerId) return\n const point = this.getEventPoint(event)\n event.preventDefault()\n\n const deltaX = point.clientX - this.startX\n const deltaY = point.clientY - this.startY\n const maxX = window.innerWidth - this.currentWidth()\n const maxY = window.innerHeight - this.currentHeight()\n\n this.posX = Math.min(maxX, Math.max(0, this.initialX + deltaX))\n this.posY = Math.min(maxY, Math.max(0, this.initialY + deltaY))\n\n if (deltaX !== 0 || deltaY !== 0) this.hasMoved = true\n\n const trashRect = this.$trash.getBoundingClientRect()\n this.isOverTrash = (\n point.clientX >= trashRect.left &&\n point.clientX <= trashRect.right &&\n point.clientY >= trashRect.top &&\n point.clientY <= trashRect.bottom\n )\n this.$trash.classList.toggle('active', this.isOverTrash)\n\n this.applyIconStyle()\n }\n\n stopIconDrag(event) {\n if (!this.isDragging || this.getEventPointerId(event) !== this.dragPointerId) return\n const point = this.getEventPoint(event)\n this.isDragging = false\n this.dragPointerId = null\n this.hasDragged = true\n this.removeIconDragListeners()\n\n const trashRect = this.$trash.getBoundingClientRect()\n if (\n point.clientX >= trashRect.left &&\n point.clientX <= trashRect.right &&\n point.clientY >= trashRect.top &&\n point.clientY <= trashRect.bottom\n ) {\n this.isHidden = true\n const rect = this.$icon.getBoundingClientRect()\n this.posY = (window.innerHeight - rect.height) / 2\n this.posX = window.innerWidth - Math.max(40, rect.width * 0.3)\n }\n\n this.dragMaskVisible = false\n this.isOverTrash = false\n this.$mask.style.display = 'none'\n this.$trash.classList.remove('active')\n setTimeout(() => { this.hasMoved = false }, 100)\n this.saveIconPosition()\n this.applyIconStyle()\n }\n\n removeIconDragListeners() {\n document.removeEventListener('pointermove', this._onIconDrag)\n document.removeEventListener('pointerup', this._stopIconDrag)\n document.removeEventListener('pointercancel', this._stopIconDrag)\n document.removeEventListener('touchmove', this._onIconDrag)\n document.removeEventListener('touchend', this._stopIconDrag)\n document.removeEventListener('touchcancel', this._stopIconDrag)\n }\n\n saveIconPosition() {\n try {\n const saved = JSON.parse(localStorage.getItem('robotPosition') || '{}')\n saved.x = this.posX / window.innerWidth\n saved.y = this.posY / window.innerHeight\n saved.isHidden = this.isHidden\n localStorage.setItem('robotPosition', JSON.stringify(saved))\n } catch (e) {\n console.warn('[mi-float-robot] 保存图标位置失败', e)\n }\n }\n\n // ==================== 抽屉拖拽 / 缩放 ====================\n\n restoreDrawerPosition(savedPos) {\n if (!savedPos || !savedPos.drawer) return\n const d = savedPos.drawer\n const width = Math.max(DRAWER_MIN_WIDTH, Math.min(window.innerWidth, Number(d.width) || this.defaultDrawerWidth()))\n const height = Math.max(DRAWER_MIN_HEIGHT, Math.min(window.innerHeight, Number(d.height) || this.defaultDrawerHeight()))\n const left = Math.max(0, Math.min(window.innerWidth - width, (Number(d.x) || 0) * window.innerWidth))\n const top = Math.max(0, Math.min(window.innerHeight - height, (Number(d.y) || 0) * window.innerHeight))\n this.drawerWidth = width\n this.drawerHeight = height\n this.drawerLeft = left\n this.drawerTop = top\n }\n\n startDrawerDrag(event, mode) {\n event.preventDefault()\n event.stopPropagation()\n if (event.pointerId !== undefined && event.currentTarget && event.currentTarget.setPointerCapture) {\n try { event.currentTarget.setPointerCapture(event.pointerId) } catch (e) {}\n }\n const width = this.drawerWidth != null ? this.drawerWidth : this.defaultDrawerWidth()\n const height = this.drawerHeight != null ? this.drawerHeight : this.defaultDrawerHeight()\n const left = this.drawerLeft != null ? this.drawerLeft : window.innerWidth - width\n const top = this.drawerTop != null ? this.drawerTop : 0\n this.drawerDrag = { mode, startX: event.clientX, startY: event.clientY, left, top, width, height }\n this.$drawer.classList.add('drawer-dragging')\n document.addEventListener('pointermove', this._onDrawerDrag)\n document.addEventListener('pointerup', this._stopDrawerDrag)\n document.addEventListener('pointercancel', this._stopDrawerDrag)\n }\n\n onDrawerDrag(event) {\n if (!this.drawerDrag) return\n event.preventDefault()\n const d = this.drawerDrag\n const deltaX = event.clientX - d.startX\n const deltaY = event.clientY - d.startY\n const minW = DRAWER_MIN_WIDTH\n const minH = DRAWER_MIN_HEIGHT\n\n if (d.mode === 'move') {\n const left = Math.max(0, Math.min(window.innerWidth - d.width, d.left + deltaX))\n const top = Math.max(0, Math.min(window.innerHeight - d.height, d.top + deltaY))\n this.drawerLeft = left\n this.drawerTop = top\n } else if (d.mode === 'resize-w') {\n const right = d.left + d.width\n let left = Math.max(0, d.left + deltaX)\n let width = right - left\n if (width < minW) { width = minW; left = right - minW }\n this.drawerLeft = left\n this.drawerWidth = width\n } else if (d.mode === 'resize-h') {\n this.drawerHeight = Math.max(minH, Math.min(window.innerHeight, d.height + deltaY))\n } else if (d.mode === 'resize-e') {\n this.drawerWidth = Math.max(minW, Math.min(window.innerWidth - d.left, d.width + deltaX))\n } else if (d.mode === 'resize-sw') {\n const right = d.left + d.width\n let left = Math.max(0, d.left + deltaX)\n let width = right - left\n if (width < minW) { width = minW; left = right - minW }\n const height = Math.max(minH, Math.min(window.innerHeight, d.height + deltaY))\n this.drawerLeft = left\n this.drawerWidth = width\n this.drawerHeight = height\n } else if (d.mode === 'resize-se') {\n this.drawerWidth = Math.max(minW, Math.min(window.innerWidth - d.left, d.width + deltaX))\n this.drawerHeight = Math.max(minH, Math.min(window.innerHeight, d.height + deltaY))\n }\n\n this.applyDrawerStyle()\n }\n\n stopDrawerDrag() {\n if (!this.drawerDrag) return\n this.drawerDrag = null\n this.$drawer.classList.remove('drawer-dragging')\n this.removeDrawerDragListeners()\n this.saveDrawerPosition()\n }\n\n removeDrawerDragListeners() {\n document.removeEventListener('pointermove', this._onDrawerDrag)\n document.removeEventListener('pointerup', this._stopDrawerDrag)\n document.removeEventListener('pointercancel', this._stopDrawerDrag)\n }\n\n handleWindowBlur() {\n if (this.drawerDrag) {\n this.drawerDrag = null\n this.$drawer.classList.remove('drawer-dragging')\n this.removeDrawerDragListeners()\n }\n if (this.isDragging) {\n this.isDragging = false\n this.dragPointerId = null\n this.removeIconDragListeners()\n this.dragMaskVisible = false\n this.isOverTrash = false\n this.$mask.style.display = 'none'\n this.$trash.classList.remove('active')\n }\n }\n\n saveDrawerPosition() {\n const width = this.drawerWidth != null ? this.drawerWidth : this.defaultDrawerWidth()\n const height = this.drawerHeight != null ? this.drawerHeight : this.defaultDrawerHeight()\n const left = this.drawerLeft != null ? this.drawerLeft : window.innerWidth - width\n const top = this.drawerTop != null ? this.drawerTop : 0\n try {\n const saved = JSON.parse(localStorage.getItem('robotPosition') || '{}')\n saved.drawer = { x: left / window.innerWidth, y: top / window.innerHeight, width, height }\n localStorage.setItem('robotPosition', JSON.stringify(saved))\n } catch (e) {\n console.warn('[mi-float-robot] 保存抽屉位置失败', e)\n }\n }\n\n // ==================== 渲染 ====================\n\n render() {\n const style = document.createElement('style')\n style.textContent = styles\n this.shadowRoot.appendChild(style)\n\n const root = document.createElement('div')\n root.innerHTML = `\n <div class=\"robot-icon-box\" title=\"智能助手\" style=\"display:none\">\n <img class=\"robot-icon-image\" alt=\"智能助手\" />\n </div>\n <div class=\"robot-drag-mask\" style=\"display:none\">\n <div class=\"robot-trash-icon\">🗑️</div>\n </div>\n <div class=\"robot-drawer-container\" style=\"display:none\">\n <div class=\"drawer-header\">\n <span class=\"drawer-header-title\">智能问答</span>\n <div class=\"drawer-controls\">\n <button type=\"button\" class=\"drawer-control-btn\" title=\"最小化\" aria-label=\"最小化\">—</button>\n <button type=\"button\" class=\"drawer-control-btn drawer-control-btn--close\" title=\"关闭\" aria-label=\"关闭\">×</button>\n </div>\n </div>\n <div class=\"drawer-body\">\n <iframe class=\"robot-iframe\" title=\"智能问答\"></iframe>\n <div class=\"robot-loading-mask\" style=\"display:none\"><span class=\"robot-loading-spinner\"></span></div>\n </div>\n <div class=\"drawer-resize drawer-resize-w\"></div>\n <div class=\"drawer-resize drawer-resize-e\"></div>\n <div class=\"drawer-resize drawer-resize-h\"></div>\n <div class=\"drawer-resize drawer-resize-sw\"></div>\n <div class=\"drawer-resize drawer-resize-se\"></div>\n </div>\n <button type=\"button\" class=\"minimized-chat\" title=\"恢复智能问答\" style=\"display:none\">\n <span>智能问答</span>\n </button>\n `\n this.shadowRoot.appendChild(root)\n\n this.$icon = root.querySelector('.robot-icon-box')\n this.$iconImage = root.querySelector('.robot-icon-image')\n this.$mask = root.querySelector('.robot-drag-mask')\n this.$trash = root.querySelector('.robot-trash-icon')\n this.$drawer = root.querySelector('.robot-drawer-container')\n this.$drawerHeader = root.querySelector('.drawer-header')\n this.$minimizeBtn = root.querySelector('.drawer-control-btn[title=\"最小化\"]')\n this.$closeBtn = root.querySelector('.drawer-control-btn--close')\n this.$iframe = root.querySelector('.robot-iframe')\n this.$loadingMask = root.querySelector('.robot-loading-mask')\n this.$minimized = root.querySelector('.minimized-chat')\n\n this.bindEvents()\n }\n\n bindEvents() {\n this.$icon.addEventListener('pointerdown', (e) => this.startIconDrag(e))\n this.$icon.addEventListener('touchstart', (e) => this.startIconDrag(e))\n this.$icon.addEventListener('click', () => this.openDrawer())\n\n this.$drawerHeader.addEventListener('pointerdown', (e) => this.startDrawerDrag(e, 'move'))\n this.$minimizeBtn.addEventListener('pointerdown', (e) => e.stopPropagation())\n this.$minimizeBtn.addEventListener('click', () => this.minimizeDrawer())\n this.$closeBtn.addEventListener('pointerdown', (e) => e.stopPropagation())\n this.$closeBtn.addEventListener('click', () => this.closeDrawer())\n\n this.$drawer.querySelector('.drawer-resize-w').addEventListener('pointerdown', (e) => this.startDrawerDrag(e, 'resize-w'))\n this.$drawer.querySelector('.drawer-resize-e').addEventListener('pointerdown', (e) => this.startDrawerDrag(e, 'resize-e'))\n this.$drawer.querySelector('.drawer-resize-h').addEventListener('pointerdown', (e) => this.startDrawerDrag(e, 'resize-h'))\n this.$drawer.querySelector('.drawer-resize-sw').addEventListener('pointerdown', (e) => this.startDrawerDrag(e, 'resize-sw'))\n this.$drawer.querySelector('.drawer-resize-se').addEventListener('pointerdown', (e) => this.startDrawerDrag(e, 'resize-se'))\n\n this.$minimized.addEventListener('click', () => this.restoreDrawer())\n }\n}\n","import { FloatRobotElement } from './element.js'\nimport { FloatRobotAdapter, FetchFloatRobotAdapter } from './adapter.js'\n\nconst GLOBAL_KEY = '__FLOAT_ROBOT_CONFIG__'\nconst DEFAULT_TAG_NAME = 'x-float-robot'\n\n/**\n * 全局配置。组件初始化时会读取这里的配置与 <x-float-robot> 上的属性。\n * @param {Object} options\n * @param {string} [options.chatUrl] 聊天页地址(iframe src)\n * @param {string} [options.avatar] 头像完整 URL\n * @param {Object} [options.adapter] 配置适配器实例\n * @param {string} [options.switchUrl] 开关接口地址(未传 adapter 时生效)\n * @param {string} [options.configUrl] 配置接口地址(未传 adapter 时生效)\n * @param {Function} [options.fetch] 自定义 fetch 函数\n */\nexport function configure(options = {}) {\n if (typeof window === 'undefined') return\n const prev = window[GLOBAL_KEY] || {}\n window[GLOBAL_KEY] = { ...prev, ...options }\n}\n\n/**\n * 读取当前全局配置。\n * @returns {Object}\n */\nexport function getConfig() {\n return (typeof window !== 'undefined' && window[GLOBAL_KEY]) || {}\n}\n\n/**\n * 注册自定义元素(默认标签名 x-float-robot,可自定义避免冲突)。\n * @param {string} tagName 自定义标签名,必须包含连字符\n */\nexport function defineFloatRobot(tagName = DEFAULT_TAG_NAME) {\n if (typeof window === 'undefined') return\n if (!window.customElements.get(tagName)) {\n window.customElements.define(tagName, FloatRobotElement)\n }\n}\n\n// 默认自动注册 <x-float-robot>\ndefineFloatRobot()\n\nexport { FloatRobotElement, FloatRobotAdapter, FetchFloatRobotAdapter }\n"],"names":["styles","svg","defaultAvatar","FloatRobotAdapter","FetchFloatRobotAdapter","options","url","res","json","parsed","vals","v","data","value","str","e","DRAWER_MIN_WIDTH","DRAWER_MIN_HEIGHT","GLOBAL_KEY","getGlobalConfig","FloatRobotElement","name","global","switchUrl","configUrl","adapter","config","savedPos","__spreadProps","__spreadValues","img","err","shadowMap","width","scale","borderRadius","height","left","top","event","rect","newWidth","newHeight","relativeX","relativeY","widthRatio","heightRatio","iconWidth","point","deltaX","deltaY","maxX","maxY","trashRect","saved","d","mode","minW","minH","right","style","root","DEFAULT_TAG_NAME","configure","prev","getConfig","defineFloatRobot","tagName"],"mappings":"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"}
@@ -0,0 +1,247 @@
1
+ (function(o,n){typeof exports=="object"&&typeof module!="undefined"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(o=typeof globalThis!="undefined"?globalThis:o||self,n(o.FloatRobot={}))})(this,function(o){"use strict";var W=Object.defineProperty,R=Object.defineProperties;var M=Object.getOwnPropertyDescriptors;var L=Object.getOwnPropertySymbols;var T=Object.prototype.hasOwnProperty,P=Object.prototype.propertyIsEnumerable;var z=(o,n,h)=>n in o?W(o,n,{enumerable:!0,configurable:!0,writable:!0,value:h}):o[n]=h,g=(o,n)=>{for(var h in n||(n={}))T.call(n,h)&&z(o,h,n[h]);if(L)for(var h of L(n))P.call(n,h)&&z(o,h,n[h]);return o},I=(o,n)=>R(o,M(n));const n=`
2
+ :host {
3
+ all: initial;
4
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
5
+ }
6
+
7
+ .robot-icon-box {
8
+ user-select: none;
9
+ touch-action: none;
10
+ position: fixed;
11
+ z-index: 4000;
12
+ transition: transform 0.3s ease;
13
+ display: flex;
14
+ align-items: center;
15
+ justify-content: center;
16
+ padding: 8px;
17
+ box-sizing: border-box;
18
+ }
19
+
20
+ .robot-icon-image {
21
+ display: block;
22
+ max-width: 100%;
23
+ height: auto;
24
+ object-fit: contain;
25
+ }
26
+
27
+ .robot-drag-mask {
28
+ position: fixed;
29
+ top: 0;
30
+ left: 0;
31
+ width: 100%;
32
+ height: 100%;
33
+ background: rgba(0, 0, 0, 0.3);
34
+ z-index: 3999;
35
+ }
36
+
37
+ .robot-trash-icon {
38
+ position: fixed;
39
+ right: 20px;
40
+ top: 50%;
41
+ transform: translateY(-50%);
42
+ font-size: 40px;
43
+ padding: 10px;
44
+ background: rgba(0, 0, 0, 0.6);
45
+ border-radius: 8px;
46
+ cursor: pointer;
47
+ transition: all 0.2s;
48
+ z-index: 4000;
49
+ }
50
+
51
+ .robot-trash-icon.active {
52
+ transform: translateY(-50%) scale(1.2);
53
+ background: #ff0000;
54
+ }
55
+
56
+ .robot-drawer-container {
57
+ position: fixed;
58
+ left: 0;
59
+ top: 0;
60
+ display: flex;
61
+ flex-direction: column;
62
+ background-color: #ffffff;
63
+ z-index: 4000;
64
+ box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
65
+ overflow: hidden;
66
+ border-radius: 8px;
67
+ transition: width 0.3s ease, height 0.3s ease;
68
+ }
69
+
70
+ .robot-drawer-container.drawer-dragging {
71
+ transition: none !important;
72
+ }
73
+
74
+ .drawer-header {
75
+ flex: none;
76
+ display: flex;
77
+ align-items: center;
78
+ justify-content: space-between;
79
+ height: 40px;
80
+ padding: 0 10px 0 14px;
81
+ background: #f5f7fa;
82
+ border-bottom: 1px solid #e4e7ed;
83
+ cursor: move;
84
+ user-select: none;
85
+ touch-action: none;
86
+ z-index: 10001;
87
+ }
88
+
89
+ .drawer-header-title {
90
+ font-size: 14px;
91
+ font-weight: 600;
92
+ color: #303133;
93
+ white-space: nowrap;
94
+ overflow: hidden;
95
+ text-overflow: ellipsis;
96
+ }
97
+
98
+ .drawer-controls {
99
+ display: flex;
100
+ align-items: center;
101
+ gap: 4px;
102
+ }
103
+
104
+ .drawer-control-btn {
105
+ width: 26px;
106
+ height: 26px;
107
+ border: none;
108
+ background: rgba(255, 255, 255, 0.92);
109
+ color: #606266;
110
+ font-size: 16px;
111
+ line-height: 1;
112
+ cursor: pointer;
113
+ border-radius: 4px;
114
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
115
+ transition: background 0.2s ease, color 0.2s ease;
116
+ }
117
+
118
+ .drawer-control-btn:hover {
119
+ background: #e4e7ed;
120
+ }
121
+
122
+ .drawer-control-btn--close:hover {
123
+ background: #f56c6c;
124
+ color: #fff;
125
+ }
126
+
127
+ .drawer-body {
128
+ position: relative;
129
+ flex: 1;
130
+ min-height: 0;
131
+ width: 100%;
132
+ }
133
+
134
+ .robot-iframe {
135
+ width: 100%;
136
+ height: 100%;
137
+ border: none;
138
+ display: block;
139
+ }
140
+
141
+ .robot-drawer-container.drawer-dragging .robot-iframe {
142
+ pointer-events: none;
143
+ }
144
+
145
+ .robot-loading-mask {
146
+ position: absolute;
147
+ top: 0;
148
+ left: 0;
149
+ right: 0;
150
+ bottom: 0;
151
+ display: flex;
152
+ align-items: center;
153
+ justify-content: center;
154
+ background: #ffffff;
155
+ z-index: 9000;
156
+ }
157
+
158
+ .robot-loading-spinner {
159
+ width: 28px;
160
+ height: 28px;
161
+ border: 3px solid #dce6f0;
162
+ border-top-color: #409eff;
163
+ border-radius: 50%;
164
+ animation: float-robot-spin 0.8s linear infinite;
165
+ }
166
+
167
+ @keyframes float-robot-spin {
168
+ to { transform: rotate(360deg); }
169
+ }
170
+
171
+ .drawer-resize {
172
+ position: absolute;
173
+ z-index: 10000;
174
+ touch-action: none;
175
+ }
176
+
177
+ .drawer-resize-w { left: 0; top: 0; bottom: 0; width: 6px; cursor: ew-resize; }
178
+ .drawer-resize-e { right: 0; top: 0; bottom: 0; width: 6px; cursor: ew-resize; }
179
+ .drawer-resize-h { left: 0; right: 0; bottom: 0; height: 6px; cursor: ns-resize; }
180
+ .drawer-resize-sw { left: 0; bottom: 0; width: 16px; height: 16px; cursor: nesw-resize; }
181
+ .drawer-resize-se { right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; }
182
+
183
+ .minimized-chat {
184
+ position: fixed;
185
+ right: 24px;
186
+ bottom: 24px;
187
+ z-index: 4001;
188
+ display: inline-flex;
189
+ align-items: center;
190
+ height: 40px;
191
+ padding: 0 14px;
192
+ border: 1px solid #d9e6ff;
193
+ border-radius: 20px;
194
+ background: #ffffff;
195
+ color: #315b9d;
196
+ box-shadow: 0 6px 18px rgba(28, 67, 128, 0.2);
197
+ cursor: pointer;
198
+ font-size: 14px;
199
+ font-family: inherit;
200
+ transition: box-shadow 0.2s ease, transform 0.2s ease;
201
+ }
202
+
203
+ .minimized-chat:hover {
204
+ transform: translateY(-2px);
205
+ box-shadow: 0 8px 22px rgba(28, 67, 128, 0.28);
206
+ }
207
+
208
+ .minimized-chat:focus {
209
+ outline: none;
210
+ box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.25), 0 6px 18px rgba(28, 67, 128, 0.2);
211
+ }
212
+ `,u=`data:image/svg+xml,${encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
213
+ <rect width="64" height="64" rx="14" fill="#409eff"/>
214
+ <rect x="27" y="10" width="10" height="6" rx="3" fill="#c7ddf5"/>
215
+ <circle cx="23" cy="30" r="5" fill="#ffffff"/>
216
+ <circle cx="41" cy="30" r="5" fill="#ffffff"/>
217
+ <rect x="24" y="42" width="16" height="5" rx="2.5" fill="#ffffff"/>
218
+ </svg>`)}`;class m{async getSwitch(){return!0}async getConfig(){return null}}class b extends m{constructor(t={}){super(),this.switchUrl=t.switchUrl||t.switch_url||"",this.configUrl=t.configUrl||t.config_url||"",this.fetchImpl=t.fetch||(e=>window.fetch(e,{credentials:"include"}))}async getSwitch(){if(!this.switchUrl)return!0;const t=await this.fetchImpl(this.switchUrl),e=await this._toJson(t);return this._normalizeSwitch(e)}async getConfig(){if(!this.configUrl)return null;const t=await this.fetchImpl(this.configUrl),e=await this._toJson(t);return this._normalizeConfig(e)}async _toJson(t){return t&&typeof t.json=="function"?t.json():t}_normalizeSwitch(t){if(typeof t=="boolean")return t;if(t&&typeof t=="object"){if(typeof t.showRobot=="boolean")return t.showRobot;if(typeof t.enabled=="boolean")return t.enabled;if(t.value!=null){const e=this._parseValue(t.value);if(e&&typeof e=="object"){const i=Object.values(e);return i.length>0&&i.every(r=>Number(r)===1)}return!!e}}return!0}_normalizeConfig(t){if(!t)return null;let e=t;for(Array.isArray(e)&&(e=e[0]);e&&typeof e=="object"&&!Object.prototype.hasOwnProperty.call(e,"avatar")&&!Object.prototype.hasOwnProperty.call(e,"style")&&!Object.prototype.hasOwnProperty.call(e,"showRobot");){if(Array.isArray(e.data)){e=e.data[0];continue}if(e.data&&typeof e.data=="object"){e=e.data;continue}if(e.result&&typeof e.result=="object"){e=e.result;continue}break}return!e||typeof e!="object"?null:e}_parseValue(t){if(t==null)return t;const e=String(t);try{return JSON.parse(e.replace(/'/g,'"'))}catch(i){return t}}}const y=560,v=400,_="__FLOAT_ROBOT_CONFIG__";function f(){return typeof window!="undefined"&&window[_]||{}}class x extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this.imgWidth=80,this.imgHeight=100,this.imageAspectRatio=1.25,this.drawerVisible=!1,this.drawerMinimized=!1,this.drawerLeft=null,this.drawerTop=null,this.drawerWidth=null,this.drawerHeight=null,this.drawerDrag=null,this.posX=0,this.posY=0,this.isDragging=!1,this.dragPointerId=null,this.startX=0,this.startY=0,this.initialX=0,this.initialY=0,this.hasDragged=!1,this.hasMoved=!1,this.dragMaskVisible=!1,this.isHidden=!1,this.isOverTrash=!1,this.windowWidth=0,this.windowHeight=0,this.originalPosX=0,this.originalPosY=0,this.showRobot=!1,this.robotAvatar="",this.robotStyleConfig=null,this.robotShowEnabled=!0,this._switchEnabled=!0,this._configAvailable=!0,this._adapter=null,this.chatLoading=!1,this.chatLoadingTimer=null,this.resizeTimer=null,this._onIconDrag=t=>this.onIconDrag(t),this._stopIconDrag=t=>this.stopIconDrag(t),this._onDrawerDrag=t=>this.onDrawerDrag(t),this._stopDrawerDrag=()=>this.stopDrawerDrag(),this._handleResize=()=>this.handleResize(),this._handleStorageChange=t=>this.handleStorageChange(t),this._handleWindowBlur=()=>this.handleWindowBlur(),this._chatReadyHandler=t=>this.chatReadyHandler(t)}connectedCallback(){this.render(),window.addEventListener("message",this._chatReadyHandler),this.initRobot()}disconnectedCallback(){this.removeIconDragListeners(),this.removeDrawerDragListeners(),window.removeEventListener("resize",this._handleResize),window.removeEventListener("storage",this._handleStorageChange),window.removeEventListener("blur",this._handleWindowBlur),window.removeEventListener("message",this._chatReadyHandler),this.chatLoadingTimer&&(clearTimeout(this.chatLoadingTimer),this.chatLoadingTimer=null),this.resizeTimer&&(clearTimeout(this.resizeTimer),this.resizeTimer=null)}getAttr(t){return this.getAttribute(t)||""}resolveChatUrl(){const t=f();return this.getAttr("chat-url")||t.chatUrl||""}resolveAvatar(){const t=f();return this.getAttr("avatar")||t.avatar||u}resolveAdapter(){const t=f();if(t.adapter)return t.adapter;const e=this.getAttr("switch-url")||t.switchUrl||"",i=this.getAttr("config-url")||t.configUrl||"";return e||i?new b({switchUrl:e,configUrl:i,fetch:t.fetch}):null}async initRobot(){const t=this.resolveAdapter();if(this._adapter=t,t){try{this._switchEnabled=!!await t.getSwitch()}catch(i){console.warn("[mi-float-robot] 获取机器人开关失败",i),this._switchEnabled=!1}if(!this._switchEnabled)return;try{const i=await t.getConfig();i?this.applyConfig(i):this._configAvailable=!1}catch(i){console.warn("[mi-float-robot] 获取机器人配置失败",i)}}this.robotAvatar||(this.robotAvatar=this.resolveAvatar(),this.loadImageAspectRatio(this.robotAvatar));let e=null;try{e=JSON.parse(localStorage.getItem("robotPosition"))}catch(i){e=null}e?(this.posX=e.x*window.innerWidth,this.posY=e.y*window.innerHeight,this.isHidden=e.isHidden):this.setInitialPosition(),this.restoreDrawerPosition(e),this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight,this.originalPosX=this.posX,this.originalPosY=this.posY,window.addEventListener("resize",this._handleResize),window.addEventListener("storage",this._handleStorageChange),window.addEventListener("blur",this._handleWindowBlur),this.updateRobotVisibility(),this.applyIconStyle()}applyConfig(t){t&&(t.avatar&&(this.robotAvatar=t.avatar,this.loadImageAspectRatio(t.avatar)),t.style&&(this.robotStyleConfig=t.style),t.showRobot!==void 0&&(this.robotShowEnabled=t.showRobot),t.width&&(this.imgWidth=t.width),t.height&&(this.imgHeight=t.height),t.scale&&(this.robotStyleConfig=I(g({},this.robotStyleConfig||{}),{scale:t.scale})))}loadImageAspectRatio(t){const e=new Image;e.onload=()=>{e.width>0&&e.height>0&&(this.imageAspectRatio=e.height/e.width)},e.onerror=()=>{},e.src=t}handleStorageChange(t){if(t.key==="robotConfigLive")try{const e=JSON.parse(t.newValue);this.applyConfig(e),e.showRobot!==void 0&&(this._configAvailable=!0,this.robotShowEnabled=e.showRobot,this.updateRobotVisibility(),this.applyIconStyle())}catch(e){console.warn("[mi-float-robot] 解析配置失败",e)}}updateRobotVisibility(){this.showRobot=this._switchEnabled&&this._configAvailable&&this.robotShowEnabled}currentScale(){return this.robotStyleConfig&&this.robotStyleConfig.scale||1}baseWidth(){return this.robotStyleConfig&&this.robotStyleConfig.width||this.imgWidth}currentWidth(){return this.baseWidth()*this.currentScale()}currentHeight(){return this.baseWidth()*this.imageAspectRatio*this.currentScale()}applyIconStyle(){const t=this.robotStyleConfig||{},e={none:"none",light:"0 2px 8px rgba(0, 0, 0, 0.08)",medium:"0 4px 16px rgba(0, 0, 0, 0.12)",strong:"0 6px 24px rgba(0, 0, 0, 0.18)"},i=t.width||this.imgWidth,r=t.scale||1;this.$icon.style.display=this.showRobot?"flex":"none",this.$icon.style.left=this.posX+"px",this.$icon.style.top=this.posY+"px",this.$icon.style.width=i+"px",this.$icon.style.height="auto",this.$icon.style.border=t.border||"none",this.$icon.style.boxShadow=e[t.shadowLevel]||"none",this.$icon.style.opacity=t.opacity!=null?t.opacity:1,this.$icon.style.transform=(this.isHidden?"rotate(-90deg) ":"")+"scale("+r+")",this.$icon.style.cursor="move";let s="0";t.borderRadius!==void 0&&(s=typeof t.borderRadius=="string"?t.borderRadius:(t.borderRadius||0)+(t.borderRadiusUnit||"px")),this.$iconImage.style.width=i+"px",this.$iconImage.style.height="auto",this.$iconImage.style.objectFit="contain",this.$iconImage.style.borderRadius=s,this.$iconImage.src=this.robotAvatar||u}defaultDrawerWidth(){return Math.round(window.innerWidth*.8)}defaultDrawerHeight(){return window.innerHeight}applyDrawerStyle(){const t=this.drawerWidth!=null?this.drawerWidth:this.defaultDrawerWidth(),e=this.drawerHeight!=null?this.drawerHeight:this.defaultDrawerHeight(),i=this.drawerLeft!=null?this.drawerLeft:window.innerWidth-t,r=this.drawerTop!=null?this.drawerTop:0;this.$drawer.style.left=i+"px",this.$drawer.style.top=r+"px",this.$drawer.style.width=t+"px",this.$drawer.style.height=e+"px"}applyDrawerVisibility(){this.$drawer.style.display=this.drawerVisible&&!this.drawerMinimized?"flex":"none",this.$minimized.style.display=this.drawerVisible&&this.drawerMinimized?"inline-flex":"none"}openDrawer(){if(!this.hasMoved){if(this.isHidden){this.setInitialPosition(),this.isHidden=!1,this.applyIconStyle();return}this.drawerVisible||(this.chatLoading=!0,this.$loadingMask.style.display="flex",this.chatLoadingTimer=setTimeout(()=>this.finishChatLoading(),3e4)),this.drawerVisible=!0,this.drawerMinimized=!1,this.$iframe.src||(this.$iframe.src=this.resolveChatUrl()),this.applyDrawerStyle(),this.applyDrawerVisibility()}}closeDrawer(){this.drawerVisible=!1,this.drawerMinimized=!1,this.applyDrawerVisibility(),this.finishChatLoading()}minimizeDrawer(){this.drawerMinimized=!0,this.applyDrawerVisibility()}restoreDrawer(){this.drawerMinimized=!1,this.drawerVisible=!0,this.applyDrawerVisibility()}finishChatLoading(){this.chatLoading=!1,this.$loadingMask.style.display="none",this.chatLoadingTimer&&(clearTimeout(this.chatLoadingTimer),this.chatLoadingTimer=null)}chatReadyHandler(t){!t||!t.data||t.data.type!=="SMI_CHAT_READY"||this.$iframe&&t.source!==this.$iframe.contentWindow||this.finishChatLoading()}setInitialPosition(){this.originalPosX=window.innerWidth-window.innerWidth*.02-this.currentWidth(),this.originalPosY=window.innerHeight-window.innerHeight*.08-this.currentHeight(),this.posX=this.originalPosX,this.posY=this.originalPosY}handleResize(){clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout(()=>{if(this.isHidden){const r=this.$icon.getBoundingClientRect();this.posX=window.innerWidth-Math.max(40,r.width*.3),this.posY=(window.innerHeight-r.height)/2,this.applyIconStyle();return}const t=window.innerWidth,e=window.innerHeight;if(this.hasDragged){const r=this.posX/this.windowWidth,s=this.posY/this.windowHeight;this.posX=t*r,this.posY=e*s}else{const r=t/this.windowWidth,s=e/this.windowHeight;this.posX=this.originalPosX*r,this.posY=this.originalPosY*s}const i=this.$icon.offsetWidth||this.currentWidth();this.posX=Math.max(0,Math.min(t-i,this.posX)),this.posY=Math.min(e-this.currentHeight(),Math.max(0,this.posY)),this.windowWidth=t,this.windowHeight=e,this.originalPosX=this.posX,this.originalPosY=this.posY,this.applyIconStyle()},100)}getEventPoint(t){return t.touches&&t.touches.length?t.touches[0]:t.changedTouches&&t.changedTouches.length?t.changedTouches[0]:t}getEventPointerId(t){return t.pointerId!==void 0?t.pointerId:"touch"}startIconDrag(t){if(this.isHidden||this.isDragging)return;const e=this.getEventPoint(t);if(t.preventDefault(),t.pointerId!==void 0&&t.currentTarget&&t.currentTarget.setPointerCapture)try{t.currentTarget.setPointerCapture(t.pointerId)}catch(i){}this.isDragging=!0,this.dragPointerId=this.getEventPointerId(t),this.startX=e.clientX,this.startY=e.clientY,this.initialX=this.posX,this.initialY=this.posY,this.dragMaskVisible=!0,this.$mask.style.display="block",document.addEventListener("pointermove",this._onIconDrag,{passive:!1}),document.addEventListener("pointerup",this._stopIconDrag),document.addEventListener("pointercancel",this._stopIconDrag),document.addEventListener("touchmove",this._onIconDrag,{passive:!1}),document.addEventListener("touchend",this._stopIconDrag),document.addEventListener("touchcancel",this._stopIconDrag)}onIconDrag(t){if(!this.isDragging||this.getEventPointerId(t)!==this.dragPointerId)return;const e=this.getEventPoint(t);t.preventDefault();const i=e.clientX-this.startX,r=e.clientY-this.startY,s=window.innerWidth-this.currentWidth(),d=window.innerHeight-this.currentHeight();this.posX=Math.min(s,Math.max(0,this.initialX+i)),this.posY=Math.min(d,Math.max(0,this.initialY+r)),(i!==0||r!==0)&&(this.hasMoved=!0);const a=this.$trash.getBoundingClientRect();this.isOverTrash=e.clientX>=a.left&&e.clientX<=a.right&&e.clientY>=a.top&&e.clientY<=a.bottom,this.$trash.classList.toggle("active",this.isOverTrash),this.applyIconStyle()}stopIconDrag(t){if(!this.isDragging||this.getEventPointerId(t)!==this.dragPointerId)return;const e=this.getEventPoint(t);this.isDragging=!1,this.dragPointerId=null,this.hasDragged=!0,this.removeIconDragListeners();const i=this.$trash.getBoundingClientRect();if(e.clientX>=i.left&&e.clientX<=i.right&&e.clientY>=i.top&&e.clientY<=i.bottom){this.isHidden=!0;const r=this.$icon.getBoundingClientRect();this.posY=(window.innerHeight-r.height)/2,this.posX=window.innerWidth-Math.max(40,r.width*.3)}this.dragMaskVisible=!1,this.isOverTrash=!1,this.$mask.style.display="none",this.$trash.classList.remove("active"),setTimeout(()=>{this.hasMoved=!1},100),this.saveIconPosition(),this.applyIconStyle()}removeIconDragListeners(){document.removeEventListener("pointermove",this._onIconDrag),document.removeEventListener("pointerup",this._stopIconDrag),document.removeEventListener("pointercancel",this._stopIconDrag),document.removeEventListener("touchmove",this._onIconDrag),document.removeEventListener("touchend",this._stopIconDrag),document.removeEventListener("touchcancel",this._stopIconDrag)}saveIconPosition(){try{const t=JSON.parse(localStorage.getItem("robotPosition")||"{}");t.x=this.posX/window.innerWidth,t.y=this.posY/window.innerHeight,t.isHidden=this.isHidden,localStorage.setItem("robotPosition",JSON.stringify(t))}catch(t){console.warn("[mi-float-robot] 保存图标位置失败",t)}}restoreDrawerPosition(t){if(!t||!t.drawer)return;const e=t.drawer,i=Math.max(y,Math.min(window.innerWidth,Number(e.width)||this.defaultDrawerWidth())),r=Math.max(v,Math.min(window.innerHeight,Number(e.height)||this.defaultDrawerHeight())),s=Math.max(0,Math.min(window.innerWidth-i,(Number(e.x)||0)*window.innerWidth)),d=Math.max(0,Math.min(window.innerHeight-r,(Number(e.y)||0)*window.innerHeight));this.drawerWidth=i,this.drawerHeight=r,this.drawerLeft=s,this.drawerTop=d}startDrawerDrag(t,e){if(t.preventDefault(),t.stopPropagation(),t.pointerId!==void 0&&t.currentTarget&&t.currentTarget.setPointerCapture)try{t.currentTarget.setPointerCapture(t.pointerId)}catch(a){}const i=this.drawerWidth!=null?this.drawerWidth:this.defaultDrawerWidth(),r=this.drawerHeight!=null?this.drawerHeight:this.defaultDrawerHeight(),s=this.drawerLeft!=null?this.drawerLeft:window.innerWidth-i,d=this.drawerTop!=null?this.drawerTop:0;this.drawerDrag={mode:e,startX:t.clientX,startY:t.clientY,left:s,top:d,width:i,height:r},this.$drawer.classList.add("drawer-dragging"),document.addEventListener("pointermove",this._onDrawerDrag),document.addEventListener("pointerup",this._stopDrawerDrag),document.addEventListener("pointercancel",this._stopDrawerDrag)}onDrawerDrag(t){if(!this.drawerDrag)return;t.preventDefault();const e=this.drawerDrag,i=t.clientX-e.startX,r=t.clientY-e.startY,s=y,d=v;if(e.mode==="move"){const a=Math.max(0,Math.min(window.innerWidth-e.width,e.left+i)),l=Math.max(0,Math.min(window.innerHeight-e.height,e.top+r));this.drawerLeft=a,this.drawerTop=l}else if(e.mode==="resize-w"){const a=e.left+e.width;let l=Math.max(0,e.left+i),w=a-l;w<s&&(w=s,l=a-s),this.drawerLeft=l,this.drawerWidth=w}else if(e.mode==="resize-h")this.drawerHeight=Math.max(d,Math.min(window.innerHeight,e.height+r));else if(e.mode==="resize-e")this.drawerWidth=Math.max(s,Math.min(window.innerWidth-e.left,e.width+i));else if(e.mode==="resize-sw"){const a=e.left+e.width;let l=Math.max(0,e.left+i),w=a-l;w<s&&(w=s,l=a-s);const $=Math.max(d,Math.min(window.innerHeight,e.height+r));this.drawerLeft=l,this.drawerWidth=w,this.drawerHeight=$}else e.mode==="resize-se"&&(this.drawerWidth=Math.max(s,Math.min(window.innerWidth-e.left,e.width+i)),this.drawerHeight=Math.max(d,Math.min(window.innerHeight,e.height+r)));this.applyDrawerStyle()}stopDrawerDrag(){this.drawerDrag&&(this.drawerDrag=null,this.$drawer.classList.remove("drawer-dragging"),this.removeDrawerDragListeners(),this.saveDrawerPosition())}removeDrawerDragListeners(){document.removeEventListener("pointermove",this._onDrawerDrag),document.removeEventListener("pointerup",this._stopDrawerDrag),document.removeEventListener("pointercancel",this._stopDrawerDrag)}handleWindowBlur(){this.drawerDrag&&(this.drawerDrag=null,this.$drawer.classList.remove("drawer-dragging"),this.removeDrawerDragListeners()),this.isDragging&&(this.isDragging=!1,this.dragPointerId=null,this.removeIconDragListeners(),this.dragMaskVisible=!1,this.isOverTrash=!1,this.$mask.style.display="none",this.$trash.classList.remove("active"))}saveDrawerPosition(){const t=this.drawerWidth!=null?this.drawerWidth:this.defaultDrawerWidth(),e=this.drawerHeight!=null?this.drawerHeight:this.defaultDrawerHeight(),i=this.drawerLeft!=null?this.drawerLeft:window.innerWidth-t,r=this.drawerTop!=null?this.drawerTop:0;try{const s=JSON.parse(localStorage.getItem("robotPosition")||"{}");s.drawer={x:i/window.innerWidth,y:r/window.innerHeight,width:t,height:e},localStorage.setItem("robotPosition",JSON.stringify(s))}catch(s){console.warn("[mi-float-robot] 保存抽屉位置失败",s)}}render(){const t=document.createElement("style");t.textContent=n,this.shadowRoot.appendChild(t);const e=document.createElement("div");e.innerHTML=`
219
+ <div class="robot-icon-box" title="智能助手" style="display:none">
220
+ <img class="robot-icon-image" alt="智能助手" />
221
+ </div>
222
+ <div class="robot-drag-mask" style="display:none">
223
+ <div class="robot-trash-icon">🗑️</div>
224
+ </div>
225
+ <div class="robot-drawer-container" style="display:none">
226
+ <div class="drawer-header">
227
+ <span class="drawer-header-title">智能问答</span>
228
+ <div class="drawer-controls">
229
+ <button type="button" class="drawer-control-btn" title="最小化" aria-label="最小化">—</button>
230
+ <button type="button" class="drawer-control-btn drawer-control-btn--close" title="关闭" aria-label="关闭">×</button>
231
+ </div>
232
+ </div>
233
+ <div class="drawer-body">
234
+ <iframe class="robot-iframe" title="智能问答"></iframe>
235
+ <div class="robot-loading-mask" style="display:none"><span class="robot-loading-spinner"></span></div>
236
+ </div>
237
+ <div class="drawer-resize drawer-resize-w"></div>
238
+ <div class="drawer-resize drawer-resize-e"></div>
239
+ <div class="drawer-resize drawer-resize-h"></div>
240
+ <div class="drawer-resize drawer-resize-sw"></div>
241
+ <div class="drawer-resize drawer-resize-se"></div>
242
+ </div>
243
+ <button type="button" class="minimized-chat" title="恢复智能问答" style="display:none">
244
+ <span>智能问答</span>
245
+ </button>
246
+ `,this.shadowRoot.appendChild(e),this.$icon=e.querySelector(".robot-icon-box"),this.$iconImage=e.querySelector(".robot-icon-image"),this.$mask=e.querySelector(".robot-drag-mask"),this.$trash=e.querySelector(".robot-trash-icon"),this.$drawer=e.querySelector(".robot-drawer-container"),this.$drawerHeader=e.querySelector(".drawer-header"),this.$minimizeBtn=e.querySelector('.drawer-control-btn[title="最小化"]'),this.$closeBtn=e.querySelector(".drawer-control-btn--close"),this.$iframe=e.querySelector(".robot-iframe"),this.$loadingMask=e.querySelector(".robot-loading-mask"),this.$minimized=e.querySelector(".minimized-chat"),this.bindEvents()}bindEvents(){this.$icon.addEventListener("pointerdown",t=>this.startIconDrag(t)),this.$icon.addEventListener("touchstart",t=>this.startIconDrag(t)),this.$icon.addEventListener("click",()=>this.openDrawer()),this.$drawerHeader.addEventListener("pointerdown",t=>this.startDrawerDrag(t,"move")),this.$minimizeBtn.addEventListener("pointerdown",t=>t.stopPropagation()),this.$minimizeBtn.addEventListener("click",()=>this.minimizeDrawer()),this.$closeBtn.addEventListener("pointerdown",t=>t.stopPropagation()),this.$closeBtn.addEventListener("click",()=>this.closeDrawer()),this.$drawer.querySelector(".drawer-resize-w").addEventListener("pointerdown",t=>this.startDrawerDrag(t,"resize-w")),this.$drawer.querySelector(".drawer-resize-e").addEventListener("pointerdown",t=>this.startDrawerDrag(t,"resize-e")),this.$drawer.querySelector(".drawer-resize-h").addEventListener("pointerdown",t=>this.startDrawerDrag(t,"resize-h")),this.$drawer.querySelector(".drawer-resize-sw").addEventListener("pointerdown",t=>this.startDrawerDrag(t,"resize-sw")),this.$drawer.querySelector(".drawer-resize-se").addEventListener("pointerdown",t=>this.startDrawerDrag(t,"resize-se")),this.$minimized.addEventListener("click",()=>this.restoreDrawer())}}const p="__FLOAT_ROBOT_CONFIG__",E="x-float-robot";function S(c={}){if(typeof window=="undefined")return;const t=window[p]||{};window[p]=g(g({},t),c)}function H(){return typeof window!="undefined"&&window[p]||{}}function D(c=E){typeof window!="undefined"&&(window.customElements.get(c)||window.customElements.define(c,x))}D(),o.FetchFloatRobotAdapter=b,o.FloatRobotAdapter=m,o.FloatRobotElement=x,o.configure=S,o.defineFloatRobot=D,o.getConfig=H,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})});
247
+ //# sourceMappingURL=mi-float-robot.umd.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mi-float-robot.umd.cjs","sources":["../src/styles.js","../src/default-avatar.js","../src/adapter.js","../src/element.js","../src/index.js"],"sourcesContent":["/**\n * Shadow DOM 样式(由原 FloatPopupChat.vue 的 scoped SCSS 扁平化而来)。\n * 使用 Shadow DOM 隔离,避免与宿主页面样式冲突。\n */\nexport const styles = `\n:host {\n all: initial;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;\n}\n\n.robot-icon-box {\n user-select: none;\n touch-action: none;\n position: fixed;\n z-index: 4000;\n transition: transform 0.3s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 8px;\n box-sizing: border-box;\n}\n\n.robot-icon-image {\n display: block;\n max-width: 100%;\n height: auto;\n object-fit: contain;\n}\n\n.robot-drag-mask {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.3);\n z-index: 3999;\n}\n\n.robot-trash-icon {\n position: fixed;\n right: 20px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 40px;\n padding: 10px;\n background: rgba(0, 0, 0, 0.6);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n z-index: 4000;\n}\n\n.robot-trash-icon.active {\n transform: translateY(-50%) scale(1.2);\n background: #ff0000;\n}\n\n.robot-drawer-container {\n position: fixed;\n left: 0;\n top: 0;\n display: flex;\n flex-direction: column;\n background-color: #ffffff;\n z-index: 4000;\n box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n border-radius: 8px;\n transition: width 0.3s ease, height 0.3s ease;\n}\n\n.robot-drawer-container.drawer-dragging {\n transition: none !important;\n}\n\n.drawer-header {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 40px;\n padding: 0 10px 0 14px;\n background: #f5f7fa;\n border-bottom: 1px solid #e4e7ed;\n cursor: move;\n user-select: none;\n touch-action: none;\n z-index: 10001;\n}\n\n.drawer-header-title {\n font-size: 14px;\n font-weight: 600;\n color: #303133;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.drawer-controls {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.drawer-control-btn {\n width: 26px;\n height: 26px;\n border: none;\n background: rgba(255, 255, 255, 0.92);\n color: #606266;\n font-size: 16px;\n line-height: 1;\n cursor: pointer;\n border-radius: 4px;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);\n transition: background 0.2s ease, color 0.2s ease;\n}\n\n.drawer-control-btn:hover {\n background: #e4e7ed;\n}\n\n.drawer-control-btn--close:hover {\n background: #f56c6c;\n color: #fff;\n}\n\n.drawer-body {\n position: relative;\n flex: 1;\n min-height: 0;\n width: 100%;\n}\n\n.robot-iframe {\n width: 100%;\n height: 100%;\n border: none;\n display: block;\n}\n\n.robot-drawer-container.drawer-dragging .robot-iframe {\n pointer-events: none;\n}\n\n.robot-loading-mask {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #ffffff;\n z-index: 9000;\n}\n\n.robot-loading-spinner {\n width: 28px;\n height: 28px;\n border: 3px solid #dce6f0;\n border-top-color: #409eff;\n border-radius: 50%;\n animation: float-robot-spin 0.8s linear infinite;\n}\n\n@keyframes float-robot-spin {\n to { transform: rotate(360deg); }\n}\n\n.drawer-resize {\n position: absolute;\n z-index: 10000;\n touch-action: none;\n}\n\n.drawer-resize-w { left: 0; top: 0; bottom: 0; width: 6px; cursor: ew-resize; }\n.drawer-resize-e { right: 0; top: 0; bottom: 0; width: 6px; cursor: ew-resize; }\n.drawer-resize-h { left: 0; right: 0; bottom: 0; height: 6px; cursor: ns-resize; }\n.drawer-resize-sw { left: 0; bottom: 0; width: 16px; height: 16px; cursor: nesw-resize; }\n.drawer-resize-se { right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; }\n\n.minimized-chat {\n position: fixed;\n right: 24px;\n bottom: 24px;\n z-index: 4001;\n display: inline-flex;\n align-items: center;\n height: 40px;\n padding: 0 14px;\n border: 1px solid #d9e6ff;\n border-radius: 20px;\n background: #ffffff;\n color: #315b9d;\n box-shadow: 0 6px 18px rgba(28, 67, 128, 0.2);\n cursor: pointer;\n font-size: 14px;\n font-family: inherit;\n transition: box-shadow 0.2s ease, transform 0.2s ease;\n}\n\n.minimized-chat:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 22px rgba(28, 67, 128, 0.28);\n}\n\n.minimized-chat:focus {\n outline: none;\n box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.25), 0 6px 18px rgba(28, 67, 128, 0.2);\n}\n`\n","/**\n * 默认头像:内联 SVG(data URI),避免额外资源文件依赖。\n * 使用方可通过 configure({ avatar }) 或 <x-float-robot avatar=\"...\"> 覆盖。\n */\nconst svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\">\n <rect width=\"64\" height=\"64\" rx=\"14\" fill=\"#409eff\"/>\n <rect x=\"27\" y=\"10\" width=\"10\" height=\"6\" rx=\"3\" fill=\"#c7ddf5\"/>\n <circle cx=\"23\" cy=\"30\" r=\"5\" fill=\"#ffffff\"/>\n <circle cx=\"41\" cy=\"30\" r=\"5\" fill=\"#ffffff\"/>\n <rect x=\"24\" y=\"42\" width=\"16\" height=\"5\" rx=\"2.5\" fill=\"#ffffff\"/>\n</svg>`\n\nexport const defaultAvatar = `data:image/svg+xml,${encodeURIComponent(svg)}`\n","/**\n * 适配器基类:组件通过它获取「是否显示」与「头像/样式配置」。\n * 使用方可以继承本类实现自定义逻辑(例如对接公司内部 RPC 接口),\n * 再通过 configure({ adapter }) 或 <x-float-robot> 的属性注入。\n */\nexport class FloatRobotAdapter {\n /**\n * 是否显示机器人图标。\n * @returns {Promise<boolean>|boolean}\n */\n async getSwitch() {\n return true\n }\n\n /**\n * 获取机器人配置;返回 null 表示没有可用配置(不显示)。\n * @returns {Promise<Object|null>|Object|null}\n *\n * 约定返回结构:\n * {\n * showRobot: true, // 是否显示机器人图标\n * avatar: 'https://...', // 头像完整 URL(可选,缺省用默认头像)\n * style: { // 图标样式(全部可选)\n * scale: 1,\n * width: 80,\n * height: 100,\n * opacity: 1,\n * border: 'none',\n * shadowLevel: 'light', // none | light | medium | strong\n * borderRadius: 0,\n * borderRadiusUnit: 'px'\n * }\n * }\n */\n async getConfig() {\n return null\n }\n}\n\n/**\n * 默认 fetch 适配器:通过 GET 请求约定的配置接口。\n * 适合没有内部 RPC 基础设施、愿意提供一个简单 JSON 接口的项目。\n */\nexport class FetchFloatRobotAdapter extends FloatRobotAdapter {\n constructor(options = {}) {\n super()\n this.switchUrl = options.switchUrl || options.switch_url || ''\n this.configUrl = options.configUrl || options.config_url || ''\n this.fetchImpl = options.fetch || ((url) => window.fetch(url, { credentials: 'include' }))\n }\n\n async getSwitch() {\n if (!this.switchUrl) return true\n const res = await this.fetchImpl(this.switchUrl)\n const json = await this._toJson(res)\n return this._normalizeSwitch(json)\n }\n\n async getConfig() {\n if (!this.configUrl) return null\n const res = await this.fetchImpl(this.configUrl)\n const json = await this._toJson(res)\n return this._normalizeConfig(json)\n }\n\n async _toJson(res) {\n if (res && typeof res.json === 'function') return res.json()\n return res\n }\n\n _normalizeSwitch(json) {\n if (typeof json === 'boolean') return json\n if (json && typeof json === 'object') {\n if (typeof json.showRobot === 'boolean') return json.showRobot\n if (typeof json.enabled === 'boolean') return json.enabled\n // 兼容 { value: '{\"smi-idb\":1}' } 这类字符串配置\n if (json.value != null) {\n const parsed = this._parseValue(json.value)\n if (parsed && typeof parsed === 'object') {\n const vals = Object.values(parsed)\n return vals.length > 0 && vals.every(v => Number(v) === 1)\n }\n return Boolean(parsed)\n }\n }\n return true\n }\n\n _normalizeConfig(json) {\n if (!json) return null\n // 允许返回被 { data: ... } / { result: { data: ... } } 包裹一层\n let data = json\n if (Array.isArray(data)) data = data[0]\n while (data && typeof data === 'object' && !Object.prototype.hasOwnProperty.call(data, 'avatar') && !Object.prototype.hasOwnProperty.call(data, 'style') && !Object.prototype.hasOwnProperty.call(data, 'showRobot')) {\n if (Array.isArray(data.data)) { data = data.data[0]; continue }\n if (data.data && typeof data.data === 'object') { data = data.data; continue }\n if (data.result && typeof data.result === 'object') { data = data.result; continue }\n break\n }\n if (!data || typeof data !== 'object') return null\n return data\n }\n\n _parseValue(value) {\n if (value == null) return value\n const str = String(value)\n try {\n return JSON.parse(str.replace(/'/g, '\"'))\n } catch (e) {\n return value\n }\n }\n}\n","import { styles } from './styles.js'\nimport { defaultAvatar } from './default-avatar.js'\nimport { FetchFloatRobotAdapter } from './adapter.js'\n\nconst DRAWER_MIN_WIDTH = 560\nconst DRAWER_MIN_HEIGHT = 400\nconst GLOBAL_KEY = '__FLOAT_ROBOT_CONFIG__'\n\nfunction getGlobalConfig() {\n return (typeof window !== 'undefined' && window[GLOBAL_KEY]) || {}\n}\n\n/**\n * 浮窗智能问答机器人 Web Component。\n * 通过 <x-float-robot> 使用,配置可由 HTML 属性或 configure() 注入。\n */\nexport class FloatRobotElement extends HTMLElement {\n constructor() {\n super()\n this.attachShadow({ mode: 'open' })\n\n // 图标尺寸\n this.imgWidth = 80\n this.imgHeight = 100\n this.imageAspectRatio = 1.25\n\n // 抽屉状态\n this.drawerVisible = false\n this.drawerMinimized = false\n this.drawerLeft = null\n this.drawerTop = null\n this.drawerWidth = null\n this.drawerHeight = null\n this.drawerDrag = null\n\n // 图标拖拽状态\n this.posX = 0\n this.posY = 0\n this.isDragging = false\n this.dragPointerId = null\n this.startX = 0\n this.startY = 0\n this.initialX = 0\n this.initialY = 0\n this.hasDragged = false\n this.hasMoved = false\n this.dragMaskVisible = false\n this.isHidden = false\n this.isOverTrash = false\n this.windowWidth = 0\n this.windowHeight = 0\n this.originalPosX = 0\n this.originalPosY = 0\n\n // 配置与可见性\n this.showRobot = false\n this.robotAvatar = ''\n this.robotStyleConfig = null\n this.robotShowEnabled = true\n this._switchEnabled = true\n this._configAvailable = true\n this._adapter = null\n\n // loading 与定时器\n this.chatLoading = false\n this.chatLoadingTimer = null\n this.resizeTimer = null\n\n // 需要反复绑定/解绑的监听器,用箭头函数字段保证引用一致\n this._onIconDrag = (e) => this.onIconDrag(e)\n this._stopIconDrag = (e) => this.stopIconDrag(e)\n this._onDrawerDrag = (e) => this.onDrawerDrag(e)\n this._stopDrawerDrag = () => this.stopDrawerDrag()\n this._handleResize = () => this.handleResize()\n this._handleStorageChange = (e) => this.handleStorageChange(e)\n this._handleWindowBlur = () => this.handleWindowBlur()\n this._chatReadyHandler = (e) => this.chatReadyHandler(e)\n }\n\n // ==================== 生命周期 ====================\n\n connectedCallback() {\n this.render()\n window.addEventListener('message', this._chatReadyHandler)\n this.initRobot()\n }\n\n disconnectedCallback() {\n this.removeIconDragListeners()\n this.removeDrawerDragListeners()\n window.removeEventListener('resize', this._handleResize)\n window.removeEventListener('storage', this._handleStorageChange)\n window.removeEventListener('blur', this._handleWindowBlur)\n window.removeEventListener('message', this._chatReadyHandler)\n if (this.chatLoadingTimer) {\n clearTimeout(this.chatLoadingTimer)\n this.chatLoadingTimer = null\n }\n if (this.resizeTimer) {\n clearTimeout(this.resizeTimer)\n this.resizeTimer = null\n }\n }\n\n // ==================== 配置解析 ====================\n\n getAttr(name) {\n return this.getAttribute(name) || ''\n }\n\n resolveChatUrl() {\n const global = getGlobalConfig()\n return this.getAttr('chat-url') || global.chatUrl || ''\n }\n\n resolveAvatar() {\n const global = getGlobalConfig()\n return this.getAttr('avatar') || global.avatar || defaultAvatar\n }\n\n resolveAdapter() {\n const global = getGlobalConfig()\n if (global.adapter) return global.adapter\n const switchUrl = this.getAttr('switch-url') || global.switchUrl || ''\n const configUrl = this.getAttr('config-url') || global.configUrl || ''\n if (switchUrl || configUrl) {\n return new FetchFloatRobotAdapter({ switchUrl, configUrl, fetch: global.fetch })\n }\n return null\n }\n\n async initRobot() {\n const adapter = this.resolveAdapter()\n this._adapter = adapter\n\n if (adapter) {\n try {\n this._switchEnabled = !!(await adapter.getSwitch())\n } catch (e) {\n console.warn('[mi-float-robot] 获取机器人开关失败', e)\n this._switchEnabled = false\n }\n if (!this._switchEnabled) return\n\n try {\n const config = await adapter.getConfig()\n if (config) {\n this.applyConfig(config)\n } else {\n this._configAvailable = false\n }\n } catch (e) {\n console.warn('[mi-float-robot] 获取机器人配置失败', e)\n }\n }\n\n // 静态头像兜底(config 未提供 avatar 时使用 attribute / configure / 默认值)\n if (!this.robotAvatar) {\n this.robotAvatar = this.resolveAvatar()\n this.loadImageAspectRatio(this.robotAvatar)\n }\n\n let savedPos = null\n try {\n savedPos = JSON.parse(localStorage.getItem('robotPosition'))\n } catch (e) {\n savedPos = null\n }\n\n if (savedPos) {\n this.posX = savedPos.x * window.innerWidth\n this.posY = savedPos.y * window.innerHeight\n this.isHidden = savedPos.isHidden\n } else {\n this.setInitialPosition()\n }\n\n this.restoreDrawerPosition(savedPos)\n this.windowWidth = window.innerWidth\n this.windowHeight = window.innerHeight\n this.originalPosX = this.posX\n this.originalPosY = this.posY\n\n window.addEventListener('resize', this._handleResize)\n window.addEventListener('storage', this._handleStorageChange)\n window.addEventListener('blur', this._handleWindowBlur)\n\n this.updateRobotVisibility()\n this.applyIconStyle()\n }\n\n applyConfig(config) {\n if (!config) return\n if (config.avatar) {\n this.robotAvatar = config.avatar\n this.loadImageAspectRatio(config.avatar)\n }\n if (config.style) {\n this.robotStyleConfig = config.style\n }\n if (config.showRobot !== undefined) {\n this.robotShowEnabled = config.showRobot\n }\n // 兼容 style 直接平铺在顶层的情况\n if (config.width) this.imgWidth = config.width\n if (config.height) this.imgHeight = config.height\n if (config.scale) this.robotStyleConfig = { ...(this.robotStyleConfig || {}), scale: config.scale }\n }\n\n loadImageAspectRatio(url) {\n const img = new Image()\n img.onload = () => {\n if (img.width > 0 && img.height > 0) {\n this.imageAspectRatio = img.height / img.width\n }\n }\n img.onerror = () => {}\n img.src = url\n }\n\n handleStorageChange(e) {\n if (e.key !== 'robotConfigLive') return\n try {\n const config = JSON.parse(e.newValue)\n this.applyConfig(config)\n if (config.showRobot !== undefined) {\n this._configAvailable = true\n this.robotShowEnabled = config.showRobot\n this.updateRobotVisibility()\n this.applyIconStyle()\n }\n } catch (err) {\n console.warn('[mi-float-robot] 解析配置失败', err)\n }\n }\n\n updateRobotVisibility() {\n this.showRobot = this._switchEnabled && this._configAvailable && this.robotShowEnabled\n }\n\n // ==================== 样式计算 ====================\n\n currentScale() {\n return (this.robotStyleConfig && this.robotStyleConfig.scale) || 1\n }\n\n baseWidth() {\n return (this.robotStyleConfig && this.robotStyleConfig.width) || this.imgWidth\n }\n\n currentWidth() {\n return this.baseWidth() * this.currentScale()\n }\n\n currentHeight() {\n return this.baseWidth() * this.imageAspectRatio * this.currentScale()\n }\n\n applyIconStyle() {\n const config = this.robotStyleConfig || {}\n const shadowMap = {\n none: 'none',\n light: '0 2px 8px rgba(0, 0, 0, 0.08)',\n medium: '0 4px 16px rgba(0, 0, 0, 0.12)',\n strong: '0 6px 24px rgba(0, 0, 0, 0.18)'\n }\n const width = config.width || this.imgWidth\n const scale = config.scale || 1\n\n this.$icon.style.display = this.showRobot ? 'flex' : 'none'\n this.$icon.style.left = this.posX + 'px'\n this.$icon.style.top = this.posY + 'px'\n this.$icon.style.width = width + 'px'\n this.$icon.style.height = 'auto'\n this.$icon.style.border = config.border || 'none'\n this.$icon.style.boxShadow = shadowMap[config.shadowLevel] || 'none'\n this.$icon.style.opacity = config.opacity != null ? config.opacity : 1\n this.$icon.style.transform = (this.isHidden ? 'rotate(-90deg) ' : '') + 'scale(' + scale + ')'\n this.$icon.style.cursor = 'move'\n\n let borderRadius = '0'\n if (config.borderRadius !== undefined) {\n borderRadius = typeof config.borderRadius === 'string'\n ? config.borderRadius\n : (config.borderRadius || 0) + (config.borderRadiusUnit || 'px')\n }\n this.$iconImage.style.width = width + 'px'\n this.$iconImage.style.height = 'auto'\n this.$iconImage.style.objectFit = 'contain'\n this.$iconImage.style.borderRadius = borderRadius\n this.$iconImage.src = this.robotAvatar || defaultAvatar\n }\n\n defaultDrawerWidth() {\n return Math.round(window.innerWidth * 0.8)\n }\n\n defaultDrawerHeight() {\n return window.innerHeight\n }\n\n applyDrawerStyle() {\n const width = this.drawerWidth != null ? this.drawerWidth : this.defaultDrawerWidth()\n const height = this.drawerHeight != null ? this.drawerHeight : this.defaultDrawerHeight()\n const left = this.drawerLeft != null ? this.drawerLeft : window.innerWidth - width\n const top = this.drawerTop != null ? this.drawerTop : 0\n this.$drawer.style.left = left + 'px'\n this.$drawer.style.top = top + 'px'\n this.$drawer.style.width = width + 'px'\n this.$drawer.style.height = height + 'px'\n }\n\n applyDrawerVisibility() {\n this.$drawer.style.display = this.drawerVisible && !this.drawerMinimized ? 'flex' : 'none'\n this.$minimized.style.display = this.drawerVisible && this.drawerMinimized ? 'inline-flex' : 'none'\n }\n\n // ==================== 抽屉交互 ====================\n\n openDrawer() {\n if (this.hasMoved) return\n if (this.isHidden) {\n this.setInitialPosition()\n this.isHidden = false\n this.applyIconStyle()\n return\n }\n if (!this.drawerVisible) {\n this.chatLoading = true\n this.$loadingMask.style.display = 'flex'\n this.chatLoadingTimer = setTimeout(() => this.finishChatLoading(), 30000)\n }\n this.drawerVisible = true\n this.drawerMinimized = false\n if (!this.$iframe.src) {\n this.$iframe.src = this.resolveChatUrl()\n }\n this.applyDrawerStyle()\n this.applyDrawerVisibility()\n }\n\n closeDrawer() {\n this.drawerVisible = false\n this.drawerMinimized = false\n this.applyDrawerVisibility()\n this.finishChatLoading()\n }\n\n minimizeDrawer() {\n this.drawerMinimized = true\n this.applyDrawerVisibility()\n }\n\n restoreDrawer() {\n this.drawerMinimized = false\n this.drawerVisible = true\n this.applyDrawerVisibility()\n }\n\n finishChatLoading() {\n this.chatLoading = false\n this.$loadingMask.style.display = 'none'\n if (this.chatLoadingTimer) {\n clearTimeout(this.chatLoadingTimer)\n this.chatLoadingTimer = null\n }\n }\n\n chatReadyHandler(event) {\n if (!event || !event.data || event.data.type !== 'SMI_CHAT_READY') return\n if (this.$iframe && event.source !== this.$iframe.contentWindow) return\n this.finishChatLoading()\n }\n\n // ==================== 图标拖拽 ====================\n\n setInitialPosition() {\n this.originalPosX = window.innerWidth - (window.innerWidth * 0.02) - this.currentWidth()\n this.originalPosY = window.innerHeight - (window.innerHeight * 0.08) - this.currentHeight()\n this.posX = this.originalPosX\n this.posY = this.originalPosY\n }\n\n handleResize() {\n clearTimeout(this.resizeTimer)\n this.resizeTimer = setTimeout(() => {\n if (this.isHidden) {\n const rect = this.$icon.getBoundingClientRect()\n this.posX = window.innerWidth - Math.max(40, rect.width * 0.3)\n this.posY = (window.innerHeight - rect.height) / 2\n this.applyIconStyle()\n return\n }\n\n const newWidth = window.innerWidth\n const newHeight = window.innerHeight\n if (!this.hasDragged) {\n const widthRatio = newWidth / this.windowWidth\n const heightRatio = newHeight / this.windowHeight\n this.posX = this.originalPosX * widthRatio\n this.posY = this.originalPosY * heightRatio\n } else {\n const relativeX = this.posX / this.windowWidth\n const relativeY = this.posY / this.windowHeight\n this.posX = newWidth * relativeX\n this.posY = newHeight * relativeY\n }\n\n const iconWidth = this.$icon.offsetWidth || this.currentWidth()\n this.posX = Math.max(0, Math.min(newWidth - iconWidth, this.posX))\n this.posY = Math.min(newHeight - this.currentHeight(), Math.max(0, this.posY))\n\n this.windowWidth = newWidth\n this.windowHeight = newHeight\n this.originalPosX = this.posX\n this.originalPosY = this.posY\n this.applyIconStyle()\n }, 100)\n }\n\n getEventPoint(event) {\n return event.touches && event.touches.length\n ? event.touches[0]\n : event.changedTouches && event.changedTouches.length\n ? event.changedTouches[0]\n : event\n }\n\n getEventPointerId(event) {\n return event.pointerId !== undefined ? event.pointerId : 'touch'\n }\n\n startIconDrag(event) {\n if (this.isHidden || this.isDragging) return\n const point = this.getEventPoint(event)\n event.preventDefault()\n if (event.pointerId !== undefined && event.currentTarget && event.currentTarget.setPointerCapture) {\n try { event.currentTarget.setPointerCapture(event.pointerId) } catch (e) {}\n }\n this.isDragging = true\n this.dragPointerId = this.getEventPointerId(event)\n this.startX = point.clientX\n this.startY = point.clientY\n this.initialX = this.posX\n this.initialY = this.posY\n this.dragMaskVisible = true\n this.$mask.style.display = 'block'\n document.addEventListener('pointermove', this._onIconDrag, { passive: false })\n document.addEventListener('pointerup', this._stopIconDrag)\n document.addEventListener('pointercancel', this._stopIconDrag)\n document.addEventListener('touchmove', this._onIconDrag, { passive: false })\n document.addEventListener('touchend', this._stopIconDrag)\n document.addEventListener('touchcancel', this._stopIconDrag)\n }\n\n onIconDrag(event) {\n if (!this.isDragging || this.getEventPointerId(event) !== this.dragPointerId) return\n const point = this.getEventPoint(event)\n event.preventDefault()\n\n const deltaX = point.clientX - this.startX\n const deltaY = point.clientY - this.startY\n const maxX = window.innerWidth - this.currentWidth()\n const maxY = window.innerHeight - this.currentHeight()\n\n this.posX = Math.min(maxX, Math.max(0, this.initialX + deltaX))\n this.posY = Math.min(maxY, Math.max(0, this.initialY + deltaY))\n\n if (deltaX !== 0 || deltaY !== 0) this.hasMoved = true\n\n const trashRect = this.$trash.getBoundingClientRect()\n this.isOverTrash = (\n point.clientX >= trashRect.left &&\n point.clientX <= trashRect.right &&\n point.clientY >= trashRect.top &&\n point.clientY <= trashRect.bottom\n )\n this.$trash.classList.toggle('active', this.isOverTrash)\n\n this.applyIconStyle()\n }\n\n stopIconDrag(event) {\n if (!this.isDragging || this.getEventPointerId(event) !== this.dragPointerId) return\n const point = this.getEventPoint(event)\n this.isDragging = false\n this.dragPointerId = null\n this.hasDragged = true\n this.removeIconDragListeners()\n\n const trashRect = this.$trash.getBoundingClientRect()\n if (\n point.clientX >= trashRect.left &&\n point.clientX <= trashRect.right &&\n point.clientY >= trashRect.top &&\n point.clientY <= trashRect.bottom\n ) {\n this.isHidden = true\n const rect = this.$icon.getBoundingClientRect()\n this.posY = (window.innerHeight - rect.height) / 2\n this.posX = window.innerWidth - Math.max(40, rect.width * 0.3)\n }\n\n this.dragMaskVisible = false\n this.isOverTrash = false\n this.$mask.style.display = 'none'\n this.$trash.classList.remove('active')\n setTimeout(() => { this.hasMoved = false }, 100)\n this.saveIconPosition()\n this.applyIconStyle()\n }\n\n removeIconDragListeners() {\n document.removeEventListener('pointermove', this._onIconDrag)\n document.removeEventListener('pointerup', this._stopIconDrag)\n document.removeEventListener('pointercancel', this._stopIconDrag)\n document.removeEventListener('touchmove', this._onIconDrag)\n document.removeEventListener('touchend', this._stopIconDrag)\n document.removeEventListener('touchcancel', this._stopIconDrag)\n }\n\n saveIconPosition() {\n try {\n const saved = JSON.parse(localStorage.getItem('robotPosition') || '{}')\n saved.x = this.posX / window.innerWidth\n saved.y = this.posY / window.innerHeight\n saved.isHidden = this.isHidden\n localStorage.setItem('robotPosition', JSON.stringify(saved))\n } catch (e) {\n console.warn('[mi-float-robot] 保存图标位置失败', e)\n }\n }\n\n // ==================== 抽屉拖拽 / 缩放 ====================\n\n restoreDrawerPosition(savedPos) {\n if (!savedPos || !savedPos.drawer) return\n const d = savedPos.drawer\n const width = Math.max(DRAWER_MIN_WIDTH, Math.min(window.innerWidth, Number(d.width) || this.defaultDrawerWidth()))\n const height = Math.max(DRAWER_MIN_HEIGHT, Math.min(window.innerHeight, Number(d.height) || this.defaultDrawerHeight()))\n const left = Math.max(0, Math.min(window.innerWidth - width, (Number(d.x) || 0) * window.innerWidth))\n const top = Math.max(0, Math.min(window.innerHeight - height, (Number(d.y) || 0) * window.innerHeight))\n this.drawerWidth = width\n this.drawerHeight = height\n this.drawerLeft = left\n this.drawerTop = top\n }\n\n startDrawerDrag(event, mode) {\n event.preventDefault()\n event.stopPropagation()\n if (event.pointerId !== undefined && event.currentTarget && event.currentTarget.setPointerCapture) {\n try { event.currentTarget.setPointerCapture(event.pointerId) } catch (e) {}\n }\n const width = this.drawerWidth != null ? this.drawerWidth : this.defaultDrawerWidth()\n const height = this.drawerHeight != null ? this.drawerHeight : this.defaultDrawerHeight()\n const left = this.drawerLeft != null ? this.drawerLeft : window.innerWidth - width\n const top = this.drawerTop != null ? this.drawerTop : 0\n this.drawerDrag = { mode, startX: event.clientX, startY: event.clientY, left, top, width, height }\n this.$drawer.classList.add('drawer-dragging')\n document.addEventListener('pointermove', this._onDrawerDrag)\n document.addEventListener('pointerup', this._stopDrawerDrag)\n document.addEventListener('pointercancel', this._stopDrawerDrag)\n }\n\n onDrawerDrag(event) {\n if (!this.drawerDrag) return\n event.preventDefault()\n const d = this.drawerDrag\n const deltaX = event.clientX - d.startX\n const deltaY = event.clientY - d.startY\n const minW = DRAWER_MIN_WIDTH\n const minH = DRAWER_MIN_HEIGHT\n\n if (d.mode === 'move') {\n const left = Math.max(0, Math.min(window.innerWidth - d.width, d.left + deltaX))\n const top = Math.max(0, Math.min(window.innerHeight - d.height, d.top + deltaY))\n this.drawerLeft = left\n this.drawerTop = top\n } else if (d.mode === 'resize-w') {\n const right = d.left + d.width\n let left = Math.max(0, d.left + deltaX)\n let width = right - left\n if (width < minW) { width = minW; left = right - minW }\n this.drawerLeft = left\n this.drawerWidth = width\n } else if (d.mode === 'resize-h') {\n this.drawerHeight = Math.max(minH, Math.min(window.innerHeight, d.height + deltaY))\n } else if (d.mode === 'resize-e') {\n this.drawerWidth = Math.max(minW, Math.min(window.innerWidth - d.left, d.width + deltaX))\n } else if (d.mode === 'resize-sw') {\n const right = d.left + d.width\n let left = Math.max(0, d.left + deltaX)\n let width = right - left\n if (width < minW) { width = minW; left = right - minW }\n const height = Math.max(minH, Math.min(window.innerHeight, d.height + deltaY))\n this.drawerLeft = left\n this.drawerWidth = width\n this.drawerHeight = height\n } else if (d.mode === 'resize-se') {\n this.drawerWidth = Math.max(minW, Math.min(window.innerWidth - d.left, d.width + deltaX))\n this.drawerHeight = Math.max(minH, Math.min(window.innerHeight, d.height + deltaY))\n }\n\n this.applyDrawerStyle()\n }\n\n stopDrawerDrag() {\n if (!this.drawerDrag) return\n this.drawerDrag = null\n this.$drawer.classList.remove('drawer-dragging')\n this.removeDrawerDragListeners()\n this.saveDrawerPosition()\n }\n\n removeDrawerDragListeners() {\n document.removeEventListener('pointermove', this._onDrawerDrag)\n document.removeEventListener('pointerup', this._stopDrawerDrag)\n document.removeEventListener('pointercancel', this._stopDrawerDrag)\n }\n\n handleWindowBlur() {\n if (this.drawerDrag) {\n this.drawerDrag = null\n this.$drawer.classList.remove('drawer-dragging')\n this.removeDrawerDragListeners()\n }\n if (this.isDragging) {\n this.isDragging = false\n this.dragPointerId = null\n this.removeIconDragListeners()\n this.dragMaskVisible = false\n this.isOverTrash = false\n this.$mask.style.display = 'none'\n this.$trash.classList.remove('active')\n }\n }\n\n saveDrawerPosition() {\n const width = this.drawerWidth != null ? this.drawerWidth : this.defaultDrawerWidth()\n const height = this.drawerHeight != null ? this.drawerHeight : this.defaultDrawerHeight()\n const left = this.drawerLeft != null ? this.drawerLeft : window.innerWidth - width\n const top = this.drawerTop != null ? this.drawerTop : 0\n try {\n const saved = JSON.parse(localStorage.getItem('robotPosition') || '{}')\n saved.drawer = { x: left / window.innerWidth, y: top / window.innerHeight, width, height }\n localStorage.setItem('robotPosition', JSON.stringify(saved))\n } catch (e) {\n console.warn('[mi-float-robot] 保存抽屉位置失败', e)\n }\n }\n\n // ==================== 渲染 ====================\n\n render() {\n const style = document.createElement('style')\n style.textContent = styles\n this.shadowRoot.appendChild(style)\n\n const root = document.createElement('div')\n root.innerHTML = `\n <div class=\"robot-icon-box\" title=\"智能助手\" style=\"display:none\">\n <img class=\"robot-icon-image\" alt=\"智能助手\" />\n </div>\n <div class=\"robot-drag-mask\" style=\"display:none\">\n <div class=\"robot-trash-icon\">🗑️</div>\n </div>\n <div class=\"robot-drawer-container\" style=\"display:none\">\n <div class=\"drawer-header\">\n <span class=\"drawer-header-title\">智能问答</span>\n <div class=\"drawer-controls\">\n <button type=\"button\" class=\"drawer-control-btn\" title=\"最小化\" aria-label=\"最小化\">—</button>\n <button type=\"button\" class=\"drawer-control-btn drawer-control-btn--close\" title=\"关闭\" aria-label=\"关闭\">×</button>\n </div>\n </div>\n <div class=\"drawer-body\">\n <iframe class=\"robot-iframe\" title=\"智能问答\"></iframe>\n <div class=\"robot-loading-mask\" style=\"display:none\"><span class=\"robot-loading-spinner\"></span></div>\n </div>\n <div class=\"drawer-resize drawer-resize-w\"></div>\n <div class=\"drawer-resize drawer-resize-e\"></div>\n <div class=\"drawer-resize drawer-resize-h\"></div>\n <div class=\"drawer-resize drawer-resize-sw\"></div>\n <div class=\"drawer-resize drawer-resize-se\"></div>\n </div>\n <button type=\"button\" class=\"minimized-chat\" title=\"恢复智能问答\" style=\"display:none\">\n <span>智能问答</span>\n </button>\n `\n this.shadowRoot.appendChild(root)\n\n this.$icon = root.querySelector('.robot-icon-box')\n this.$iconImage = root.querySelector('.robot-icon-image')\n this.$mask = root.querySelector('.robot-drag-mask')\n this.$trash = root.querySelector('.robot-trash-icon')\n this.$drawer = root.querySelector('.robot-drawer-container')\n this.$drawerHeader = root.querySelector('.drawer-header')\n this.$minimizeBtn = root.querySelector('.drawer-control-btn[title=\"最小化\"]')\n this.$closeBtn = root.querySelector('.drawer-control-btn--close')\n this.$iframe = root.querySelector('.robot-iframe')\n this.$loadingMask = root.querySelector('.robot-loading-mask')\n this.$minimized = root.querySelector('.minimized-chat')\n\n this.bindEvents()\n }\n\n bindEvents() {\n this.$icon.addEventListener('pointerdown', (e) => this.startIconDrag(e))\n this.$icon.addEventListener('touchstart', (e) => this.startIconDrag(e))\n this.$icon.addEventListener('click', () => this.openDrawer())\n\n this.$drawerHeader.addEventListener('pointerdown', (e) => this.startDrawerDrag(e, 'move'))\n this.$minimizeBtn.addEventListener('pointerdown', (e) => e.stopPropagation())\n this.$minimizeBtn.addEventListener('click', () => this.minimizeDrawer())\n this.$closeBtn.addEventListener('pointerdown', (e) => e.stopPropagation())\n this.$closeBtn.addEventListener('click', () => this.closeDrawer())\n\n this.$drawer.querySelector('.drawer-resize-w').addEventListener('pointerdown', (e) => this.startDrawerDrag(e, 'resize-w'))\n this.$drawer.querySelector('.drawer-resize-e').addEventListener('pointerdown', (e) => this.startDrawerDrag(e, 'resize-e'))\n this.$drawer.querySelector('.drawer-resize-h').addEventListener('pointerdown', (e) => this.startDrawerDrag(e, 'resize-h'))\n this.$drawer.querySelector('.drawer-resize-sw').addEventListener('pointerdown', (e) => this.startDrawerDrag(e, 'resize-sw'))\n this.$drawer.querySelector('.drawer-resize-se').addEventListener('pointerdown', (e) => this.startDrawerDrag(e, 'resize-se'))\n\n this.$minimized.addEventListener('click', () => this.restoreDrawer())\n }\n}\n","import { FloatRobotElement } from './element.js'\nimport { FloatRobotAdapter, FetchFloatRobotAdapter } from './adapter.js'\n\nconst GLOBAL_KEY = '__FLOAT_ROBOT_CONFIG__'\nconst DEFAULT_TAG_NAME = 'x-float-robot'\n\n/**\n * 全局配置。组件初始化时会读取这里的配置与 <x-float-robot> 上的属性。\n * @param {Object} options\n * @param {string} [options.chatUrl] 聊天页地址(iframe src)\n * @param {string} [options.avatar] 头像完整 URL\n * @param {Object} [options.adapter] 配置适配器实例\n * @param {string} [options.switchUrl] 开关接口地址(未传 adapter 时生效)\n * @param {string} [options.configUrl] 配置接口地址(未传 adapter 时生效)\n * @param {Function} [options.fetch] 自定义 fetch 函数\n */\nexport function configure(options = {}) {\n if (typeof window === 'undefined') return\n const prev = window[GLOBAL_KEY] || {}\n window[GLOBAL_KEY] = { ...prev, ...options }\n}\n\n/**\n * 读取当前全局配置。\n * @returns {Object}\n */\nexport function getConfig() {\n return (typeof window !== 'undefined' && window[GLOBAL_KEY]) || {}\n}\n\n/**\n * 注册自定义元素(默认标签名 x-float-robot,可自定义避免冲突)。\n * @param {string} tagName 自定义标签名,必须包含连字符\n */\nexport function defineFloatRobot(tagName = DEFAULT_TAG_NAME) {\n if (typeof window === 'undefined') return\n if (!window.customElements.get(tagName)) {\n window.customElements.define(tagName, FloatRobotElement)\n }\n}\n\n// 默认自动注册 <x-float-robot>\ndefineFloatRobot()\n\nexport { FloatRobotElement, FloatRobotAdapter, FetchFloatRobotAdapter }\n"],"names":["styles","defaultAvatar","FloatRobotAdapter","FetchFloatRobotAdapter","options","url","res","json","parsed","vals","v","data","value","str","e","DRAWER_MIN_WIDTH","DRAWER_MIN_HEIGHT","GLOBAL_KEY","getGlobalConfig","FloatRobotElement","name","global","switchUrl","configUrl","adapter","config","savedPos","__spreadProps","__spreadValues","img","err","shadowMap","width","scale","borderRadius","height","left","top","event","rect","newWidth","newHeight","relativeX","relativeY","widthRatio","heightRatio","iconWidth","point","deltaX","deltaY","maxX","maxY","trashRect","saved","d","mode","minW","minH","right","style","root","DEFAULT_TAG_NAME","configure","prev","getConfig","defineFloatRobot","tagName"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "mi-float-robot",
3
+ "version": "1.0.0",
4
+ "description": "跨框架浮窗智能问答机器人 Web Component,支持拖拽、缩放、最小化与 iframe 嵌入,零运行时依赖。",
5
+ "type": "module",
6
+ "main": "./dist/mi-float-robot.umd.cjs",
7
+ "module": "./dist/mi-float-robot.js",
8
+ "unpkg": "./dist/mi-float-robot.umd.cjs",
9
+ "jsdelivr": "./dist/mi-float-robot.umd.cjs",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/mi-float-robot.js",
13
+ "require": "./dist/mi-float-robot.umd.cjs",
14
+ "default": "./dist/mi-float-robot.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "sideEffects": [
21
+ "dist/mi-float-robot.js",
22
+ "dist/mi-float-robot.umd.cjs"
23
+ ],
24
+ "scripts": {
25
+ "dev": "vite",
26
+ "build": "vite build",
27
+ "prepublishOnly": "npm run build"
28
+ },
29
+ "keywords": [
30
+ "web-component",
31
+ "custom-element",
32
+ "float-robot",
33
+ "chat",
34
+ "iframe",
35
+ "assistant"
36
+ ],
37
+ "license": "MIT",
38
+ "devDependencies": {
39
+ "vite": "^5.4.21"
40
+ }
41
+ }