/** * WxInputBridge — 微信小程序 bindinput/bindconfirm 适配为 IInputSource。 * * 使用方式(在 terminal-core-view/index.js 中): * const bridge = createWxInputBridge(); * // 绑定到 InputBridge * const core_bridge = new InputBridge(); * bridge.on('key', p => { const seq = core_bridge.mapKey(...); transport.send(seq); }); * bridge.on('input', p => { if (!p.isComposing && p.data) transport.send(p.data); }); * bridge.on('paste', p => { transport.send(core_bridge.mapPaste(p.text)); }); * * 组件调用(WXML 事件 → 桥接): * Page/Component: { * onInput(e) { bridge.triggerInput(e.detail.value, e.detail.isComposing); }, * onConfirm() { bridge.triggerConfirm(); }, * onPaste(text){ bridge.triggerPaste(text); }, * onFocus() { bridge.triggerFocus(); }, * onBlur() { bridge.triggerBlur(); }, * } */ function createWxInputBridge() { const _listeners = Object.create(null); function on(event, cb) { if (!_listeners[event]) _listeners[event] = []; _listeners[event].push(cb); return function off() { const arr = _listeners[event]; if (!arr) return; const idx = arr.indexOf(cb); if (idx >= 0) arr.splice(idx, 1); }; } function _emit(event, payload) { const arr = _listeners[event]; if (!arr) return; for (let i = 0; i < arr.length; i++) { try { arr[i](payload); } catch(e) { /* isolation */ } } } // ── WXML 事件驱动 API ───────────────────────────────────────────────────── /** * 由 WXML bindinput 调用。 * 注意:小程序 bindinput 的 value 是整体输入框值,不是增量; * 调用方应提取增量(新增字符)后传入 data 参数。 */ function triggerInput(data, isComposing) { _emit('input', { data: data != null ? String(data) : '', isComposing: !!isComposing, }); } /** * 由 WXML bindconfirm 调用(用户点击软键盘"完成/回车")。 */ function triggerConfirm() { _emit('key', { key: 'Enter', code: 'Enter', ctrlKey: false, altKey: false, shiftKey: false, metaKey: false, }); } /** * 由触控工具栏按键调用(箭头键、Tab、Ctrl+C 等)。 * @param {string} key KeyboardEvent.key 等价值(如 "ArrowUp"、"c") * @param {string} code KeyboardEvent.code 等价值(可省略,默认与 key 相同) * @param {{ ctrlKey, altKey, shiftKey, metaKey }} mods 修饰键状态 */ function triggerKey(key, code, mods) { const m = mods || {}; _emit('key', { key: key, code: code || key, ctrlKey: !!m.ctrlKey, altKey: !!m.altKey, shiftKey: !!m.shiftKey, metaKey: !!m.metaKey, }); } /** * 由粘贴操作触发(通过 wx.getClipboardData 读取后调用)。 */ function triggerPaste(text) { _emit('paste', { text: String(text || '') }); } /** * IME 组合开始(候选词输入开始)。 */ function triggerCompositionStart(data) { _emit('compositionstart', { data: String(data || '') }); } /** * IME 组合结束(候选词确认)。 */ function triggerCompositionEnd(data) { _emit('compositionend', { data: String(data || '') }); } return { on: on, // WXML 事件驱动方法 triggerInput: triggerInput, triggerConfirm: triggerConfirm, triggerKey: triggerKey, triggerPaste: triggerPaste, triggerCompositionStart: triggerCompositionStart, triggerCompositionEnd: triggerCompositionEnd, }; } module.exports = { createWxInputBridge: createWxInputBridge };