@textbus/platform-browser 5.1.5 → 5.2.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":"index.esm.js","sources":["../src/_utils/uikit.ts","../src/_utils/env.ts","../src/injection-tokens.ts","../src/parser.ts","../src/selection-bridge.ts","../src/types.ts","../src/magic-input.ts","../src/collaborate-cursor.ts","../src/native-input.ts","../src/dom-adapter.ts","../src/browser-module.ts"],"sourcesContent":["/**\n * 选区焦点可视位置\n */\nexport interface Rect {\n left: number\n top: number\n width: number\n height: number\n}\n\nexport interface UIElementParams {\n classes?: string[]\n attrs?: {[key: string]: any}\n props?: {[key: string]: any}\n styles?: {[key: string]: any}\n children?: (Node | null)[]\n on?: Record<string, (ev: Event) => void>\n}\n\nexport function createElement(tagName: string, options: UIElementParams = {}): HTMLElement {\n const el = document.createElement(tagName)\n if (options.classes) {\n el.classList.add(...options.classes)\n }\n if (options.attrs) {\n Object.keys(options.attrs).forEach(key => {\n el.setAttribute(key, options.attrs![key])\n })\n }\n if (options.props) {\n Object.keys(options.props).forEach(key => {\n (el as any)[key] = options.props![key]\n })\n }\n if (options.styles) {\n Object.assign(el.style, options.styles)\n }\n if (options.children) {\n options.children.filter(i => i).forEach(item => {\n el.appendChild(item as Node)\n })\n }\n if (options.on) {\n Object.keys(options.on).forEach(key => {\n el.addEventListener(key, options.on![key])\n })\n }\n return el\n}\n\nexport function getLayoutRectByRange(range: Range): Rect {\n let { startContainer, startOffset } = range\n if (startContainer.nodeType === Node.TEXT_NODE) {\n if (startOffset > 0) {\n return range.getBoundingClientRect()\n }\n const parentNode = startContainer.parentNode!\n startOffset = Array.from(parentNode.childNodes).indexOf(startContainer as any)\n startContainer = parentNode\n }\n\n const beforeNode = startContainer.childNodes[startOffset - 1]\n if (beforeNode) {\n if (beforeNode.nodeType === Node.ELEMENT_NODE && beforeNode.nodeName.toLowerCase() !== 'br') {\n const rect = (beforeNode as HTMLElement).getBoundingClientRect()\n return {\n left: rect.right,\n top: rect.top,\n width: range.collapsed ? 1 : rect.width,\n height: rect.height\n }\n } else if (beforeNode.nodeType === Node.TEXT_NODE) {\n const range2 = document.createRange()\n range2.setStart(beforeNode, beforeNode.textContent!.length)\n range2.setEnd(beforeNode, beforeNode.textContent!.length)\n const rect = range2.getBoundingClientRect()\n return {\n left: rect.right,\n top: rect.top,\n width: range.collapsed ? 1 : rect.width,\n height: rect.height\n }\n }\n }\n const offsetNode = startContainer.childNodes[startOffset]\n let isInsertBefore = false\n if (!offsetNode) {\n const lastChild = startContainer.lastChild\n if (lastChild && lastChild.nodeType === Node.ELEMENT_NODE) {\n const rect = (lastChild as HTMLElement).getBoundingClientRect()\n return {\n left: rect.right,\n top: rect.top,\n width: range.collapsed ? 1 : rect.width,\n height: rect.height\n }\n }\n }\n if (offsetNode) {\n if (offsetNode.nodeType === Node.ELEMENT_NODE && offsetNode.nodeName.toLowerCase() !== 'br') {\n const rect = (offsetNode as HTMLElement).getBoundingClientRect()\n return {\n left: rect.left,\n top: rect.top,\n width: range.collapsed ? 1 : rect.width,\n height: rect.height\n }\n }\n isInsertBefore = true\n }\n const span = startContainer.ownerDocument!.createElement('span')\n span.innerText = '\\u200b'\n span.style.display = 'inline-block'\n if (isInsertBefore) {\n startContainer.insertBefore(span, offsetNode)\n } else {\n startContainer.appendChild(span)\n }\n const rect = span.getBoundingClientRect()\n startContainer.removeChild(span)\n return {\n left: rect.left,\n top: rect.top,\n width: range.collapsed ? 1 : rect.width,\n height: rect.height\n }\n}\n","export const isWindows = () => /win(dows|32|64)/i.test(navigator.userAgent)\nexport const isMac = () => /mac os/i.test(navigator.userAgent)\nexport const isSafari = () => /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent)\nexport const isFirefox = () => /Firefox/.test(navigator.userAgent)\n\nexport const isMobileBrowser = () => /Android|iPhone|iPad/.test(navigator.userAgent)\n","import { InjectionToken } from '@viewfly/core'\n\nimport { ViewOptions } from './browser-module'\n\n/**\n * 编辑器可选项依赖注入 token\n */\nexport const EDITOR_OPTIONS = new InjectionToken<ViewOptions>('EDITOR_OPTIONS')\n\n/**\n * 编辑器容器依赖注入 token\n */\nexport const VIEW_CONTAINER = new InjectionToken<HTMLElement>('VIEW_CONTAINER')\n\n/**\n * 编辑器容器依赖注入 token\n */\nexport const VIEW_DOCUMENT = new InjectionToken<HTMLElement>('VIEW_DOCUMENT')\n\n/**\n * 编辑器容器遮罩层 token\n */\nexport const VIEW_MASK = new InjectionToken<HTMLElement>('VIEW_MASK')\n","import { Inject, Injectable } from '@viewfly/core'\nimport { Attribute, Component, ContentType, FormatItem, Formatter, FormatValue, Slot, Textbus } from '@textbus/core'\n\nimport { EDITOR_OPTIONS } from './injection-tokens'\nimport { ViewOptions } from './browser-module'\n\n/**\n * 插槽解析器\n */\nexport interface SlotParser {\n /**\n * 将指定 DOM 节点解析为插槽数据\n * @param childSlot 储存数据的插槽\n * @param slotRootElement 插槽的根节点\n * @param slotContentHostElement 插槽的内容节点\n *\n * 注意:当不传入内容节点时,Textbus 会把根节点当成内容节点\n */<T extends Slot>(childSlot: T, slotRootElement: Element, slotContentHostElement?: Element): T\n}\n\n/**\n * 组件加载器\n */\nexport interface ComponentLoader {\n /** 识别组件的匹配方法 */\n match(element: Element,\n returnableContentTypes: ContentType[]): boolean\n\n /** 读取组件内容的方法 */\n read(element: Element, textbus: Textbus, slotParser: SlotParser): Component | Slot | void\n}\n\nexport interface FormatLoaderReadResult<T = FormatValue> {\n formatter: Formatter<T>\n value: T\n}\n\n/**\n * 格式加载器\n */\nexport interface FormatLoader<T = FormatValue> {\n /**\n * 匹配一个 DOM 节点是否是某个格式节点\n * @param element\n */\n match(element: Element): boolean\n\n /**\n * 读取匹配到的节点,并返回读取后的信息\n * @param element\n */\n read(element: Element): FormatLoaderReadResult<T>\n}\n\nexport interface AttributeLoaderReadResult<T = FormatValue> {\n attribute: Attribute<T>\n value: T\n}\n\n/**\n * 属性加载器\n */\nexport interface AttributeLoader<T = FormatValue> {\n /**\n * 匹配一个 DOM 节点是否是某个属性节点\n * @param element\n */\n match(element: Element): boolean\n\n /**\n * 读取匹配到的节点,并返回读取后的信息\n * @param element\n */\n read(element: Element): AttributeLoaderReadResult<T>\n}\n\n/**\n * 用于解析 HTML,并把 HTML 内容转换为 Textbus 可以支持的组件或插槽数据\n */\n@Injectable()\nexport class Parser {\n static parseHTML(html: string) {\n return new DOMParser().parseFromString(html, 'text/html').body\n }\n\n componentLoaders: ComponentLoader[]\n formatLoaders: FormatLoader<any>[]\n attributeLoaders: AttributeLoader<any>[]\n\n constructor(@Inject(EDITOR_OPTIONS) options: ViewOptions,\n private textbus: Textbus) {\n const componentLoaders = [\n ...(options.componentLoaders || [])\n ]\n const formatLoaders = [\n ...(options.formatLoaders || [])\n ]\n const attributeLoaders = [\n ...(options.attributeLoaders || [])\n ]\n // options.imports?.forEach(i => {\n // componentLoaders.push(...(i.componentLoaders || []))\n // formatLoaders.push(...(i.formatLoaders || []))\n // })\n this.componentLoaders = componentLoaders\n this.formatLoaders = formatLoaders\n this.attributeLoaders = attributeLoaders\n }\n\n /**\n * 使用指定的组件加载器解析一段 HTML 字符串或 DOM 元素\n * @param html\n * @param rootComponentLoader\n */\n parseDoc(html: string | HTMLElement, rootComponentLoader: ComponentLoader) {\n const element = typeof html === 'string' ? Parser.parseHTML(html) : html\n return rootComponentLoader.read(\n element,\n this.textbus,\n (childSlot, slotRootElement, slotContentHostElement = slotRootElement) => {\n return this.readSlot(childSlot, slotRootElement, slotContentHostElement)\n }\n )\n }\n\n /**\n * 将一段 HTML 或 DOM 元素解析到指定插槽\n * @param html\n * @param rootSlot\n */\n parse(html: string | HTMLElement, rootSlot: Slot) {\n const element = typeof html === 'string' ? Parser.parseHTML(html) : html\n return this.readFormats(element, rootSlot)\n }\n\n private readComponent(el: Node, slot: Slot) {\n if (el.nodeType === Node.ELEMENT_NODE) {\n if ((el as HTMLElement).tagName === 'BR') {\n slot.insert('\\n')\n return\n }\n const schema = [...slot.schema]\n for (const t of this.componentLoaders) {\n if (t.match(el as HTMLElement, schema)) {\n const result = t.read(\n el as HTMLElement,\n this.textbus,\n (childSlot, slotRootElement, slotContentHostElement = slotRootElement) => {\n return this.readSlot(childSlot, slotRootElement, slotContentHostElement)\n }\n )\n if (!result) {\n return\n }\n if (result instanceof Slot) {\n result.toDelta().forEach(i => slot.insert(i.insert, i.formats))\n return\n }\n slot.insert(result)\n return\n }\n }\n this.readFormats(el as HTMLElement, slot)\n } else if (el.nodeType === Node.TEXT_NODE) {\n this.readText(slot, el)\n }\n }\n\n private readText(slot: Slot, el: Node) {\n const textContent = el.textContent\n if (/^\\s*[\\r\\n\\u200b]+\\s*$/.test(textContent as string)) {\n return\n }\n slot.insert(textContent as string)\n }\n\n private readFormats(el: Element, slot: Slot) {\n const formats = this.formatLoaders.filter(f => {\n return f.match(el)\n }).map(f => {\n return f.read(el)\n })\n const startIndex = slot.index\n let startNode = el.firstChild\n while (startNode) {\n this.readComponent(startNode, slot)\n startNode = startNode.nextSibling\n }\n const endIndex = slot.index\n this.applyFormats(slot, formats.map<FormatItem<any>>(i => {\n return {\n formatter: i.formatter,\n value: i.value,\n startIndex,\n endIndex\n }\n }))\n slot.retain(endIndex)\n return slot\n }\n\n private readSlot<T extends Slot>(childSlot: T, slotRootElement: Element, slotContentElement: Element): T {\n if (slotRootElement.nodeType === Node.ELEMENT_NODE) {\n this.attributeLoaders.filter(a => {\n return a.match(slotRootElement)\n }).forEach(a => {\n const r = a.read(slotRootElement)\n childSlot.setAttribute(r.attribute, r.value)\n })\n }\n if (slotContentElement.nodeType === Node.ELEMENT_NODE) {\n this.readFormats(slotContentElement, childSlot)\n } else {\n this.readText(childSlot, slotContentElement)\n }\n return childSlot\n }\n\n private applyFormats(slot: Slot, formatItems: FormatItem<any>[]) {\n slot.background(() => {\n formatItems.forEach(i => {\n slot.retain(i.startIndex)\n slot.retain(i.endIndex - i.startIndex, i.formatter, i.value)\n })\n })\n }\n}\n","import { delay, filter, fromEvent, Observable, Subject, Subscription } from '@tanbo/stream'\nimport { Inject, Injectable } from '@viewfly/core'\nimport {\n NativeSelectionBridge,\n NativeSelectionConnector,\n SelectionPosition,\n Slot,\n AbstractSelection,\n RootComponentRef,\n Controller,\n Selection,\n Textbus,\n Scheduler\n} from '@textbus/core'\n\nimport { EDITOR_OPTIONS, VIEW_DOCUMENT } from './injection-tokens'\nimport { getLayoutRectByRange, Rect } from './_utils/uikit'\nimport { Input } from './types'\nimport { ViewOptions } from './browser-module'\nimport { DomAdapter } from './dom-adapter'\n\n/**\n * Textbus PC 端选区桥接实现\n */\n@Injectable()\nexport class SelectionBridge implements NativeSelectionBridge {\n onSelectionChange: Observable<Range | null>\n nativeSelection = document.getSelection()!\n\n syncSelectionFromNativeSelectionChange = true\n\n private selectionChangeEvent = new Subject<Range | null>()\n\n private subs: Subscription[] = []\n private sub: Subscription\n private connector: NativeSelectionConnector | null = null\n\n private ignoreSelectionChange = false\n\n private changeFromUser = false\n private docContainer: HTMLElement\n\n private cacheCaretPositionTimer!: any\n private oldCaretPosition!: Rect | null\n\n constructor(@Inject(EDITOR_OPTIONS) private config: ViewOptions,\n textbus: Textbus,\n controller: Controller,\n private selection: Selection,\n private rootComponentRef: RootComponentRef,\n private input: Input,\n private scheduler: Scheduler,\n private domAdapter: DomAdapter) {\n this.docContainer = textbus.get(VIEW_DOCUMENT)\n this.onSelectionChange = this.selectionChangeEvent.asObservable().pipe(filter(() => {\n return !controller.readonly\n }))\n this.sub = this.onSelectionChange.subscribe((r) => {\n if (r) {\n input.focus(r, this.changeFromUser)\n } else {\n input.blur()\n }\n })\n this.sub.add(\n fromEvent(document, 'focusin').subscribe(ev => {\n let target = ev.target as HTMLElement\n if (/^(input|textarea|select)$/i.test(target.nodeName)) {\n if (target.tagName.toLowerCase() === 'input' && /^(range|date)$/.test((target as HTMLInputElement).type)) {\n return\n }\n this.ignoreSelectionChange = true\n return\n }\n if (!config.useContentEditable) {\n while (target) {\n if (target.contentEditable === 'true') {\n this.ignoreSelectionChange = true\n return\n }\n target = target.parentNode as HTMLElement\n }\n }\n })\n )\n this.sub.add(\n fromEvent(document, 'focusout').subscribe(() => {\n this.ignoreSelectionChange = false\n })\n )\n }\n\n connect(connector: NativeSelectionConnector) {\n this.disConnect()\n this.connector = connector\n this.syncSelection(connector)\n this.listen(connector)\n }\n\n disConnect() {\n this.connector = null\n this.unListen()\n }\n\n getRect(location: SelectionPosition) {\n const { focus, anchor } = this.getPositionByRange({\n focusOffset: location.offset,\n anchorOffset: location.offset,\n focusSlot: location.slot,\n anchorSlot: location.slot\n })\n if (!focus || !anchor) {\n return null\n }\n const nativeRange = document.createRange()\n nativeRange.setStart(focus.node, focus.offset)\n nativeRange.collapse()\n return getLayoutRectByRange(nativeRange)\n }\n\n restore(abstractSelection: AbstractSelection | null, fromLocal: boolean) {\n this.changeFromUser = fromLocal\n if (this.ignoreSelectionChange || !this.connector) {\n return\n }\n this.unListen()\n if (!abstractSelection) {\n this.nativeSelection.removeAllRanges()\n this.selectionChangeEvent.next(null)\n this.listen(this.connector)\n return\n }\n\n const { focus, anchor } = this.getPositionByRange(abstractSelection)\n if (!focus || !anchor) {\n this.nativeSelection.removeAllRanges()\n this.selectionChangeEvent.next(null)\n this.listen(this.connector)\n return\n }\n\n function tryOffset(position: {node: Node, offset: number}) {\n if (!position.node) {\n return\n }\n if (position.node.nodeType === Node.TEXT_NODE) {\n const len = position.node.textContent!.length\n if (position.offset > len) {\n position.offset = len\n }\n } else if (position.node.nodeType === Node.ELEMENT_NODE) {\n const len = position.node.childNodes.length\n if (position.offset > len) {\n position.offset = len\n }\n }\n }\n\n try {\n tryOffset(focus)\n tryOffset(anchor)\n this.nativeSelection.setBaseAndExtent(anchor.node, anchor.offset, focus.node, focus.offset)\n } catch (e) {\n setTimeout(() => {\n throw e\n })\n }\n if (this.nativeSelection.rangeCount) {\n const nativeRange = this.nativeSelection.getRangeAt(0)\n this.selectionChangeEvent.next(nativeRange)\n } else {\n this.selectionChangeEvent.next(null)\n }\n\n // hack start 浏览器会触发上面选区更改事件\n const bind = () => {\n if (this.connector) {\n this.listen(this.connector)\n }\n }\n if (fromLocal) {\n Promise.resolve().then(bind)\n return\n }\n if (typeof requestIdleCallback === 'function') {\n requestIdleCallback(bind)\n } else {\n setTimeout(bind, 30)\n }\n // hack end\n }\n\n destroy() {\n this.subs.forEach(i => i.unsubscribe())\n this.sub.unsubscribe()\n }\n\n getPositionByRange(abstractSelection: AbstractSelection) {\n let focus!: {node: Node, offset: number} | null\n let anchor!: {node: Node, offset: number} | null\n try {\n focus = this.findSelectedNodeAndOffset(abstractSelection.focusSlot!, abstractSelection.focusOffset!)\n anchor = focus\n if (abstractSelection.anchorSlot !== abstractSelection.focusSlot ||\n abstractSelection.anchorOffset !== abstractSelection.focusOffset) {\n anchor = this.findSelectedNodeAndOffset(abstractSelection.anchorSlot!, abstractSelection.anchorOffset!)\n }\n return {\n focus,\n anchor\n }\n } catch (e) {\n return {\n focus: null,\n anchor: null\n }\n }\n }\n\n getPreviousLinePositionByCurrent(position: SelectionPosition): SelectionPosition | null {\n return this.getLinePosition(position, false)\n }\n\n getNextLinePositionByCurrent(position: SelectionPosition): SelectionPosition | null {\n return this.getLinePosition(position, true)\n }\n\n private getLinePosition(currentPosition: SelectionPosition, toNext: boolean): SelectionPosition | null {\n clearTimeout(this.cacheCaretPositionTimer)\n let p: SelectionPosition\n if (this.oldCaretPosition) {\n p = toNext ?\n this.getNextLinePositionByOffset(currentPosition, this.oldCaretPosition.left) :\n this.getPreviousLinePositionByOffset(currentPosition, this.oldCaretPosition.left)\n } else {\n this.oldCaretPosition = this.getRect(currentPosition)!\n p = toNext ?\n this.getNextLinePositionByOffset(currentPosition, this.oldCaretPosition.left) :\n this.getPreviousLinePositionByOffset(currentPosition, this.oldCaretPosition.left)\n }\n this.cacheCaretPositionTimer = setTimeout(() => {\n this.oldCaretPosition = null\n }, 3000)\n return p\n }\n\n /**\n * 获取选区向上移动一行的位置。\n * @param currentPosition\n * @param startLeft 参考位置。\n */\n private getPreviousLinePositionByOffset(currentPosition: SelectionPosition, startLeft: number): SelectionPosition {\n let isToPrevLine = false\n let loopCount = 0\n let minLeft = startLeft\n let focusSlot = currentPosition.slot\n let focusOffset = currentPosition.offset\n let minTop = this.getRect({\n slot: focusSlot,\n offset: focusOffset\n })!.top\n\n let position: SelectionPosition\n let oldPosition!: SelectionPosition\n let oldLeft = 0\n while (true) {\n loopCount++\n position = this.selection.getPreviousPositionByPosition(focusSlot, focusOffset)\n focusSlot = position.slot\n focusOffset = position.offset\n const rect2 = this.getRect(position)!\n if (!isToPrevLine) {\n if (rect2.left > minLeft || rect2.top + rect2.height <= minTop) {\n isToPrevLine = true\n } else if (rect2.left === minLeft && rect2.top === minTop) {\n return position\n }\n minLeft = rect2.left\n minTop = rect2.top\n // oldPosition = position\n }\n if (isToPrevLine) {\n if (rect2.left <= startLeft) {\n return position\n }\n if (oldPosition) {\n if (rect2.left >= oldLeft) {\n return oldPosition\n }\n }\n oldLeft = rect2.left\n oldPosition = position\n }\n if (loopCount > 10000) {\n break\n }\n }\n return position || {\n offset: 0,\n slot: focusSlot\n }\n }\n\n /**\n * 获取选区向下移动一行的位置。\n * @param currentPosition\n * @param startLeft 参考位置。\n */\n private getNextLinePositionByOffset(currentPosition: SelectionPosition, startLeft: number): SelectionPosition {\n let isToNextLine = false\n let loopCount = 0\n let maxRight = startLeft\n let focusSlot = currentPosition.slot\n let focusOffset = currentPosition.offset\n const rect = this.getRect({\n slot: focusSlot,\n offset: focusOffset\n })!\n let minTop = rect.top\n let oldPosition!: SelectionPosition\n let oldLeft = 0\n while (true) {\n loopCount++\n const position = this.selection.getNextPositionByPosition(focusSlot, focusOffset)\n focusSlot = position.slot\n focusOffset = position.offset\n const rect2 = this.getRect(position)!\n if (!isToNextLine) {\n if (rect2.left < maxRight || rect2.top >= minTop + rect.height) {\n isToNextLine = true\n } else if (rect2.left === maxRight && rect2.top === minTop) {\n return position\n }\n maxRight = rect2.left\n minTop = rect2.top\n oldPosition = position\n }\n if (isToNextLine) {\n if (rect2.left > startLeft) {\n return oldPosition\n }\n if (oldPosition) {\n if (rect2.left <= oldLeft) {\n return oldPosition\n }\n }\n oldPosition = position\n oldLeft = rect2.left\n }\n if (loopCount > 10000) {\n break\n }\n }\n return oldPosition || {\n offset: focusSlot.length,\n slot: focusSlot\n }\n }\n\n private unListen() {\n this.subs.forEach(i => i.unsubscribe())\n this.subs = []\n }\n\n private listen(connector: NativeSelectionConnector) {\n if (!this.config.useContentEditable) {\n const selection = this.nativeSelection\n this.subs.push(\n fromEvent<MouseEvent>(this.docContainer, 'mousedown').subscribe(ev => {\n if (this.ignoreSelectionChange || ev.button === 2) {\n return\n }\n if (!ev.shiftKey) {\n selection.removeAllRanges()\n }\n })\n )\n }\n let isUpdating = false\n this.subs.push(\n this.scheduler.onDocChange.subscribe(() => {\n isUpdating = true\n }),\n this.scheduler.onDocChanged.pipe(delay()).subscribe(() => {\n isUpdating = false\n }),\n fromEvent(document, 'selectionchange').subscribe(() => {\n if (isUpdating) {\n return\n }\n if (this.syncSelectionFromNativeSelectionChange) {\n this.syncSelection(connector)\n }\n })\n )\n }\n\n private syncSelection(connector: NativeSelectionConnector) {\n const selection = this.nativeSelection\n this.changeFromUser = true\n if (this.ignoreSelectionChange ||\n this.input.composition ||\n selection.rangeCount === 0 ||\n !this.docContainer.contains(selection.anchorNode) ||\n this.rootComponentRef.component.slots.length === 0) {\n return\n }\n const rawRange = selection.getRangeAt(0)\n const nativeRange = rawRange.cloneRange()\n const isFocusEnd = selection.focusNode === nativeRange.endContainer && selection.focusOffset === nativeRange.endOffset\n const isFocusStart = selection.focusNode === nativeRange.startContainer && selection.focusOffset === nativeRange.startOffset\n if (!this.docContainer.contains(selection.focusNode)) {\n if (isFocusEnd) {\n const nativeNode = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.slots.at(0)!)\n if (!nativeNode) {\n return\n }\n nativeRange.setEndAfter(nativeNode.lastChild!)\n } else {\n const nativeNode = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.slots.at(-1)!)\n if (!nativeNode) {\n return\n }\n nativeRange.setStartBefore(nativeNode.firstChild!)\n }\n }\n\n const startPosition = this.getCorrectedPosition(nativeRange.startContainer, nativeRange.startOffset, isFocusStart)\n const endPosition = nativeRange.collapsed ?\n startPosition :\n this.getCorrectedPosition(nativeRange.endContainer, nativeRange.endOffset, isFocusEnd)\n\n if ([Node.ELEMENT_NODE, Node.TEXT_NODE].includes(nativeRange.commonAncestorContainer?.nodeType as any) &&\n startPosition && endPosition) {\n const abstractSelection = connector.beforeChange(isFocusEnd ? {\n anchorSlot: startPosition.slot,\n anchorOffset: startPosition.offset,\n focusSlot: endPosition.slot,\n focusOffset: endPosition.offset\n } : {\n focusSlot: startPosition.slot,\n focusOffset: startPosition.offset,\n anchorSlot: endPosition.slot,\n anchorOffset: endPosition.offset\n })\n if (!abstractSelection) {\n this.selectionChangeEvent.next(null)\n connector.setSelection(null)\n return\n }\n const { focus, anchor } = this.getPositionByRange(abstractSelection)\n if (focus && anchor) {\n let start = anchor\n let end = focus\n if (isFocusStart) {\n start = focus\n end = anchor\n }\n if (nativeRange.startContainer !== start.node || nativeRange.startOffset !== start.offset) {\n nativeRange.setStart(start.node, start.offset)\n }\n if (nativeRange.endContainer !== end.node || nativeRange.endOffset !== end.offset) {\n nativeRange.setEnd(end.node, end.offset)\n }\n connector.setSelection(abstractSelection)\n if (selection.isCollapsed && (\n rawRange.startContainer !== start.node ||\n rawRange.startOffset !== start.offset ||\n rawRange.endContainer !== end.node ||\n rawRange.endOffset !== end.offset\n )) {\n rawRange.setStart(start.node, start.offset)\n rawRange.setEnd(end.node, end.offset)\n }\n this.selectionChangeEvent.next(nativeRange)\n } else {\n connector.setSelection(null)\n }\n return\n }\n connector.setSelection(null)\n }\n\n private findSelectedNodeAndOffset(slot: Slot, offset: number): {node: Node, offset: number} | null {\n const prev = slot.getContentAtIndex(offset - 1)\n const nodes = this.domAdapter.getNodesBySlot(slot)\n\n if (prev) {\n if (typeof prev !== 'string') {\n const nativeNode = this.domAdapter.getNativeNodeByComponent(prev)!\n return {\n node: nativeNode.parentNode!,\n offset: Array.from(nativeNode.parentNode!.childNodes).indexOf(nativeNode) + 1\n }\n } else if (prev === '\\n') {\n for (const node of nodes) {\n if (node instanceof Text) {\n continue\n }\n if (node.nodeName === 'BR') {\n const position = this.domAdapter.getLocationByNativeNode(node)\n if (position) {\n if (position.endIndex === offset) {\n const parentNode = node.parentNode!\n return {\n node: parentNode,\n offset: Array.from(parentNode.childNodes).indexOf(node as ChildNode) + 1\n }\n }\n }\n }\n }\n }\n }\n const current = slot.getContentAtIndex(offset)\n if (current && typeof current !== 'string') {\n const nativeNode = this.domAdapter.getNativeNodeByComponent(current)!\n return {\n node: nativeNode.parentNode!,\n offset: Array.from(nativeNode.parentNode!.childNodes).indexOf(nativeNode)\n }\n }\n for (const node of nodes) {\n if (node instanceof Element) {\n if (node.tagName === 'BR') {\n const position = this.domAdapter.getLocationByNativeNode(node)\n if (position) {\n if (position.startIndex === offset) {\n const parentNode = node.parentNode!\n return {\n node: parentNode,\n offset: Array.from(parentNode.childNodes).indexOf(node)\n }\n }\n }\n }\n continue\n }\n const position = this.domAdapter.getLocationByNativeNode(node)\n if (position) {\n if (offset >= position.startIndex && offset <= position.endIndex) {\n return {\n node: node,\n offset: offset - position.startIndex\n }\n }\n }\n }\n return null\n }\n\n private getCorrectedPosition(node: Node, offset: number, toAfter: boolean, excludeNodes: Node[] = []): SelectionPosition | null {\n excludeNodes.push(node)\n if (node.nodeType === Node.ELEMENT_NODE) {\n const containerPosition = this.domAdapter.getLocationByNativeNode(node)\n const childNode = node.childNodes[offset]\n if (childNode) {\n const childPosition = this.domAdapter.getLocationByNativeNode(childNode)\n if (childPosition) {\n if (containerPosition) {\n return {\n slot: childPosition.slot,\n offset: childPosition.startIndex\n }\n }\n return this.findFocusNode(childNode, toAfter, excludeNodes)\n }\n return this.findFocusNode(childNode, toAfter, excludeNodes)\n }\n const prevNode = node.childNodes[offset - 1]\n if (prevNode) {\n const prevPosition = this.domAdapter.getLocationByNativeNode(prevNode)\n if (prevPosition && containerPosition) {\n return {\n slot: prevPosition.slot,\n offset: prevPosition.endIndex\n }\n }\n }\n if (containerPosition) {\n return {\n slot: containerPosition.slot,\n offset: containerPosition.endIndex\n }\n }\n const nextNode = toAfter ? node.nextSibling : node.previousSibling\n if (nextNode) {\n return this.findFocusNode(nextNode, toAfter, excludeNodes)\n }\n return this.findFocusNodeByParent(node, toAfter, excludeNodes)\n } else if (node.nodeType === Node.TEXT_NODE) {\n const containerPosition = this.domAdapter.getLocationByNativeNode(node)\n if (containerPosition) {\n return {\n slot: containerPosition.slot,\n offset: containerPosition.startIndex + offset\n }\n }\n const nextNode = toAfter ? node.nextSibling : node.previousSibling\n if (nextNode) {\n return this.findFocusNode(nextNode, toAfter, excludeNodes)\n }\n return this.findFocusNodeByParent(node, toAfter, excludeNodes)\n }\n return null\n }\n\n private findFocusNode(node: Node, toAfter = false, excludeNodes: Node[] = []): SelectionPosition | null {\n if (excludeNodes.includes(node)) {\n const next = toAfter ? node.nextSibling : node.previousSibling\n if (next) {\n return this.findFocusNode(next, toAfter, excludeNodes)\n }\n return this.findFocusNodeByParent(node, toAfter, excludeNodes)\n }\n excludeNodes.push(node)\n const position = this.domAdapter.getLocationByNativeNode(node as any)\n if (position) {\n return {\n slot: position.slot,\n offset: toAfter ? position.startIndex : position.endIndex\n }\n }\n const firstChild = toAfter ? node.firstChild : node.lastChild\n if (firstChild) {\n return this.findFocusNode(firstChild, toAfter, excludeNodes)\n }\n const nextSibling = toAfter ? node.nextSibling : node.previousSibling\n if (nextSibling) {\n return this.findFocusNode(nextSibling, toAfter, excludeNodes)\n }\n return this.findFocusNodeByParent(node, toAfter, excludeNodes)\n }\n\n private findFocusNodeByParent(node: Node, toAfter: boolean, excludeNodes: Node[]) {\n const parentNode = node.parentNode\n if (parentNode) {\n const parentPosition = this.domAdapter.getLocationByNativeNode(parentNode)\n if (parentPosition) {\n return {\n slot: parentPosition.slot,\n offset: toAfter ? parentPosition.endIndex : parentPosition.startIndex\n }\n }\n excludeNodes.push(node)\n return this.findFocusNode(parentNode, toAfter, excludeNodes)\n }\n return null\n }\n}\n","import { Observable } from '@tanbo/stream'\n\nimport { Rect } from './_utils/uikit'\n\nexport interface CaretLimit {\n top: number\n bottom: number\n}\n\nexport interface CaretPosition {\n left: number\n top: number\n height: number\n}\n\nexport interface Caret {\n onPositionChange: Observable<CaretPosition | null>\n readonly rect: Rect\n\n refresh(): void\n}\n\nexport abstract class Input {\n /**\n * @experimental\n */\n abstract composition: boolean\n /**\n * @experimental\n */\n abstract onReady: Promise<void>\n abstract caret: Caret\n abstract disabled: boolean\n\n abstract focus(nativeRange: Range, reFlash: boolean): void\n\n abstract blur(): void\n\n abstract destroy(): void\n}\n","import { distinctUntilChanged, filter, fromEvent, map, merge, Observable, Subject, Subscription } from '@tanbo/stream'\nimport { Injectable } from '@viewfly/core'\nimport {\n Commander,\n CompositionStartEventData,\n ContentType,\n Controller,\n Event,\n invokeListener,\n Keyboard,\n Scheduler,\n Selection,\n Slot,\n Textbus\n} from '@textbus/core'\n\nimport { createElement, getLayoutRectByRange } from './_utils/uikit'\nimport { Parser } from './parser'\nimport { isFirefox, isMac, isSafari, isWindows } from './_utils/env'\nimport { VIEW_MASK } from './injection-tokens'\nimport { Caret, CaretLimit, CaretPosition, Input } from './types'\nimport { DomAdapter } from './dom-adapter'\n\nconst iframeHTML = `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n <title>Textbus</title>\n <style>\n html {position: fixed; left:0; overflow: hidden}\n html, body{height: 100%;width:100%}\n body{margin:0; overflow: hidden}\n textarea{width: 2000px;height: 100%;opacity: 0; padding: 0; outline: none; border: none; position: absolute; left:0; top:0;}\n </style>\n</head>\n<body>\n</body>\n</html>\n`\n\ninterface CaretStyle {\n height: string\n lineHeight: string\n fontSize: string\n}\n\nclass ExperimentalCaret implements Caret {\n onPositionChange: Observable<CaretPosition | null>\n onStyleChange: Observable<CaretStyle>\n elementRef: HTMLElement\n changeFromSelf = false\n\n getLimit = function (): CaretLimit {\n return {\n top: 0,\n bottom: document.documentElement.clientHeight\n }\n }\n\n get rect() {\n return this.caret.getBoundingClientRect()\n }\n\n private timer: any = null\n private caret: HTMLElement\n\n private set display(v: boolean) {\n this._display = v\n this.caret.style.visibility = v ? 'visible' : 'hidden'\n }\n\n private get display() {\n return this._display\n }\n\n private _display = true\n private flashing = true\n\n private subscription = new Subscription()\n\n private positionChangeEvent = new Subject<CaretPosition | null>()\n private styleChangeEvent = new Subject<CaretStyle>()\n private oldRange: Range | null = null\n\n constructor(\n private domRenderer: DomAdapter,\n private scheduler: Scheduler,\n private editorMask: HTMLElement) {\n this.onPositionChange = this.positionChangeEvent.pipe(distinctUntilChanged())\n this.onStyleChange = this.styleChangeEvent.asObservable()\n this.elementRef = createElement('div', {\n styles: {\n position: 'absolute',\n width: '2px',\n pointerEvents: 'none'\n },\n children: [\n this.caret = createElement('span', {\n styles: {\n width: '100%',\n height: '100%',\n position: 'absolute',\n left: 0,\n top: 0\n }\n })\n ]\n })\n\n this.subscription.add(\n fromEvent(document, 'mousedown').subscribe(() => {\n this.flashing = false\n }),\n fromEvent(document, 'mouseup').subscribe(() => {\n this.flashing = true\n }),\n )\n this.editorMask.appendChild(this.elementRef)\n }\n\n refresh() {\n if (this.oldRange) {\n this.show(this.oldRange, false)\n }\n }\n\n show(range: Range, restart: boolean) {\n this.oldRange = range\n if (restart || this.scheduler.lastChangesHasLocalUpdate) {\n clearTimeout(this.timer)\n }\n this.updateCursorPosition(range)\n if (range.collapsed) {\n if (restart || this.scheduler.lastChangesHasLocalUpdate) {\n this.display = true\n const toggleShowHide = () => {\n this.display = !this.display || !this.flashing\n this.timer = setTimeout(toggleShowHide, 400)\n }\n clearTimeout(this.timer)\n this.timer = setTimeout(toggleShowHide, 400)\n }\n } else {\n this.display = false\n clearTimeout(this.timer)\n }\n }\n\n hide() {\n this.display = false\n clearTimeout(this.timer)\n this.positionChangeEvent.next(null)\n }\n\n destroy() {\n clearTimeout(this.timer)\n // this.caret.\n this.subscription.unsubscribe()\n }\n\n private updateCursorPosition(nativeRange: Range) {\n const startContainer = nativeRange.startContainer\n\n const node = (startContainer.nodeType === Node.ELEMENT_NODE ? startContainer : startContainer.parentNode) as HTMLElement\n if (node?.nodeType !== Node.ELEMENT_NODE) {\n this.positionChangeEvent.next(null)\n return\n }\n const compositionNode = this.domRenderer.compositionNode\n if (compositionNode) {\n nativeRange = nativeRange.cloneRange()\n nativeRange.selectNodeContents(compositionNode)\n nativeRange.collapse()\n }\n const rect = getLayoutRectByRange(nativeRange)\n const { fontSize, lineHeight, color, writingMode } = getComputedStyle(node)\n\n let height: number\n if (isNaN(+lineHeight)) {\n const f = parseFloat(lineHeight)\n if (isNaN(f)) {\n height = parseFloat(fontSize)\n } else {\n height = f\n }\n } else {\n height = parseFloat(fontSize) * parseFloat(lineHeight)\n }\n\n const boxHeight = Math.max(Math.floor(Math.max(height, rect.height)), 12)\n // const boxHeight = Math.floor(height)\n\n let rectTop = rect.top\n if (rect.height < height) {\n rectTop -= (height - rect.height) / 2\n }\n\n rectTop = Math.floor(rectTop)\n\n const containerRect = this.editorMask.getBoundingClientRect()\n\n const top = Math.floor(rectTop - containerRect.top)\n const left = Math.floor(rect.left + rect.width / 2 - containerRect.left)\n let rotate = 0\n if (nativeRange.collapsed) {\n rotate = Math.round(Math.atan2(rect.width, rect.height) * 180 / Math.PI)\n\n if (rotate !== 0) {\n const hackEle = document.createElement('span')\n // eslint-disable-next-line max-len\n hackEle.style.cssText = 'display: inline-block; width: 10px; height: 10px; position: relative; contain: layout style size; writing-mode: inherit'\n const pointEle = document.createElement('span')\n pointEle.style.cssText = 'position: absolute; left: 0; top: 0; width:0;height:0'\n hackEle.append(pointEle)\n node.append(hackEle)\n\n const p1 = pointEle.getBoundingClientRect()\n pointEle.style.right = '0'\n pointEle.style.left = ''\n const p2 = pointEle.getBoundingClientRect()\n\n const x = p1.x - p2.x\n const y = p1.y - p2.y\n\n rotate = Math.atan2(y, x) * 180 / Math.PI\n hackEle.remove()\n }\n }\n if (writingMode === 'vertical-lr' || writingMode === 'vertical-rl') {\n rotate += 90\n }\n Object.assign(this.elementRef.style, {\n left: left + 'px',\n top: top + 'px',\n height: boxHeight + 'px',\n lineHeight: boxHeight + 'px',\n fontSize,\n transform: `rotate(${rotate}deg)`,\n })\n\n this.caret.style.backgroundColor = color === 'rgba(0, 0, 0, 0)' ? '#000' : color\n this.styleChangeEvent.next({\n height: boxHeight + 'px',\n lineHeight: boxHeight + 'px',\n fontSize\n })\n this.positionChangeEvent.next({\n left,\n top: rectTop,\n height: boxHeight\n })\n\n if (this.changeFromSelf) {\n this.changeFromSelf = false\n const selfRect = this.elementRef.getBoundingClientRect()\n const scrollContainer = this.getScrollContainer(startContainer)\n const scrollRect = scrollContainer === document.documentElement ?\n { top: 0, bottom: document.documentElement.clientHeight } :\n scrollContainer.getBoundingClientRect()\n const limit = this.getLimit()\n\n const top = Math.max(limit.top, scrollRect.top)\n const bottom = Math.min(limit.bottom, scrollRect.bottom)\n\n if (selfRect.top < top) {\n scrollContainer.scrollTop -= top - selfRect.top\n } else if (selfRect.bottom > bottom) {\n scrollContainer.scrollTop += selfRect.bottom - bottom\n }\n }\n }\n\n private getScrollContainer(container: Node): Element {\n while (container) {\n if (container instanceof Element) {\n const styles = getComputedStyle(container)\n if (styles.overflow !== 'visible' || styles.overflowX !== 'visible' || styles.overflowY !== 'visible') {\n return container\n }\n }\n container = container.parentNode as Node\n }\n return document.documentElement\n }\n}\n\n\n/**\n * Textbus PC 端输入实现\n */\n@Injectable()\nexport class MagicInput extends Input {\n composition = false\n onReady: Promise<void>\n caret: ExperimentalCaret\n\n set disabled(b: boolean) {\n this._disabled = b\n if (b && this.textarea) {\n this.textarea.disabled = b\n }\n }\n\n get disabled() {\n return this._disabled\n }\n\n private isSafari = isSafari()\n private isFirefox = isFirefox()\n private isMac = isMac()\n private isWindows = isWindows()\n private _disabled = false\n private container = this.createEditableFrame()\n\n private subscription = new Subscription()\n private doc!: Document\n\n private textarea: HTMLTextAreaElement | null = null\n\n private isFocus = false\n private nativeFocus = false\n\n private ignoreComposition = false // 有 bug 版本搜狗拼音\n\n constructor(private domAdapter: DomAdapter,\n private parser: Parser,\n private keyboard: Keyboard,\n private commander: Commander,\n private selection: Selection,\n private controller: Controller,\n private scheduler: Scheduler,\n private textbus: Textbus) {\n super()\n this.caret = new ExperimentalCaret(this.domAdapter, this.scheduler, this.textbus.get(VIEW_MASK))\n this.onReady = new Promise<void>(resolve => {\n this.subscription.add(\n fromEvent(this.container, 'load').subscribe(() => {\n const doc = this.container.contentDocument!\n doc.open()\n doc.write(iframeHTML)\n doc.close()\n this.doc = doc\n this.init()\n resolve()\n }),\n controller.onReadonlyStateChange.subscribe(() => {\n if (controller.readonly) {\n this.blur()\n }\n })\n )\n })\n\n this.caret.elementRef.append(this.container)\n }\n\n focus(range: Range, restart: boolean) {\n if (!this.disabled) {\n this.caret.show(range, restart)\n }\n if (this.controller.readonly) {\n return\n }\n if (!this.isFocus) {\n this.textarea?.focus()\n setTimeout(() => {\n if (!this.nativeFocus && this.isFocus) {\n this.reInit()\n }\n })\n }\n this.isFocus = true\n }\n\n blur() {\n this.caret.hide()\n this.textarea?.blur()\n this.isFocus = false\n }\n\n destroy() {\n this.caret.destroy()\n this.subscription.unsubscribe()\n }\n\n private reInit(delay = false) {\n this.subscription.unsubscribe()\n this.textarea?.parentNode?.removeChild(this.textarea)\n this.subscription = new Subscription()\n this.init()\n if (delay) {\n setTimeout(() => {\n this.textarea?.focus()\n })\n } else {\n this.textarea?.focus()\n }\n }\n\n private init() {\n const doc = this.doc\n const contentBody = doc.body\n const textarea = doc.createElement('textarea')\n textarea.disabled = this.disabled\n contentBody.appendChild(textarea)\n this.textarea = textarea\n this.subscription.add(\n fromEvent(textarea, 'blur').subscribe(() => {\n // if (this.isFocus) {\n // this.isFocus = false\n // this.reInit(true)\n // }\n this.isFocus = false\n this.nativeFocus = false\n this.caret.hide()\n if (this.domAdapter.composition) {\n const slot = this.domAdapter.composition.slot\n this.domAdapter.composition = null\n this.domAdapter.compositionNode = null\n slot.__changeMarker__.forceMarkDirtied()\n }\n }),\n fromEvent(textarea, 'focus').subscribe(() => {\n this.nativeFocus = true\n }),\n this.caret.onStyleChange.subscribe(style => {\n Object.assign(textarea.style, style)\n })\n )\n this.handleInput(textarea)\n this.handleShortcut(textarea)\n this.handleDefaultActions(textarea)\n }\n\n private handleDefaultActions(textarea: HTMLTextAreaElement) {\n this.subscription.add(\n fromEvent<ClipboardEvent>(isFirefox() ? textarea : document, 'copy').subscribe(ev => {\n this.copyHandler(ev)\n }),\n fromEvent<ClipboardEvent>(textarea, 'paste').subscribe(ev => {\n this.pasteHandler(ev)\n })\n )\n }\n\n copyHandler(ev: ClipboardEvent) {\n const selection = this.selection\n if (!selection.isSelected) {\n return\n }\n if (selection.startSlot === selection.endSlot && selection.endOffset! - selection.startOffset! === 1) {\n const content = selection.startSlot!.getContentAtIndex(selection.startOffset!)\n if (typeof content === 'object') {\n const clipboardData = ev.clipboardData!\n const nativeSelection = document.getSelection()!\n const range = nativeSelection.getRangeAt(0)\n const div = document.createElement('div')\n const fragment = range.cloneContents()\n div.append(fragment)\n clipboardData.setData('text/html', div.innerHTML)\n clipboardData.setData('text', div.innerText)\n ev.preventDefault()\n }\n }\n }\n\n pasteHandler(ev: ClipboardEvent) {\n const text = ev.clipboardData!.getData('Text')\n\n const types = Array.from(ev.clipboardData!.types || [])\n const files = Array.from(ev.clipboardData!.files)\n if (types.every(type => type === 'Files') && files.length) {\n Promise.all(files.filter(i => {\n return /image/i.test(i.type)\n }).map(item => {\n const reader = new FileReader()\n return new Promise(resolve => {\n reader.onload = (event) => {\n resolve(event.target!.result)\n }\n reader.readAsDataURL(item)\n })\n })).then(urls => {\n const html = urls.map(i => {\n return `<img src=${i}>`\n }).join('')\n this.paste(html, text)\n })\n ev.preventDefault()\n return\n }\n\n const div = this.doc.createElement('div')\n div.style.cssText = 'width:1px; height:10px; overflow: hidden; position: fixed; left: 50%; top: 50%; opacity:0'\n div.contentEditable = 'true'\n this.doc.body.appendChild(div)\n div.focus()\n setTimeout(() => {\n this.doc.body.removeChild(div)\n div.style.cssText = ''\n this.paste(div, text)\n })\n }\n\n private paste(dom: HTMLElement | string, text: string) {\n const slot = this.parser.parse(dom, new Slot([\n ContentType.BlockComponent,\n ContentType.InlineComponent,\n ContentType.Text\n ]))\n\n this.commander.paste(slot, text)\n }\n\n private handleShortcut(textarea: HTMLTextAreaElement) {\n let isWriting = false\n let isIgnore = false\n this.subscription.add(\n fromEvent(textarea, 'compositionstart').subscribe(() => {\n isWriting = true\n }),\n fromEvent(textarea, 'compositionend').subscribe(() => {\n isWriting = false\n }),\n fromEvent<InputEvent>(textarea, 'beforeinput').subscribe(ev => {\n this.ignoreComposition = false\n if (this.isSafari) {\n if (ev.inputType === 'insertFromComposition') {\n isIgnore = true\n }\n }\n }),\n fromEvent<KeyboardEvent>(textarea, 'keydown').pipe(filter(() => {\n if (this.isSafari && isIgnore) {\n isIgnore = false\n return false\n }\n return !isWriting // || !this.textarea.value\n })).subscribe(ev => {\n this.ignoreComposition = false\n let key = ev.key\n const keys = ')!@#$%^Z&*('\n const b = key === 'Process' && /Digit\\d/.test(ev.code) && ev.shiftKey\n if (b) {\n // 大小写锁定为大写 + 全角 + shift + 数字键,还存在问题\n key = keys.charAt(+ev.code.substring(5))\n ev.preventDefault()\n }\n this.caret.changeFromSelf = true\n const is = this.keyboard.execShortcut({\n key: key,\n altKey: ev.altKey,\n shiftKey: ev.shiftKey,\n modKey: this.isMac ? ev.metaKey : ev.ctrlKey,\n agent: {\n key: ev.key,\n code: ev.code,\n keyCode: ev.keyCode,\n }\n })\n if (is) {\n this.ignoreComposition = true\n ev.preventDefault()\n } else {\n this.caret.changeFromSelf = false\n }\n })\n )\n }\n\n private handleInput(textarea: HTMLTextAreaElement) {\n let startIndex = 0\n this.subscription.add(\n fromEvent<CompositionEvent>(textarea, 'compositionstart').pipe(filter(() => {\n return !this.ignoreComposition\n })).subscribe(() => {\n if (!this.selection.isCollapsed) {\n this.caret.changeFromSelf = true\n this.commander.delete()\n }\n this.composition = true\n startIndex = this.selection.startOffset!\n const startSlot = this.selection.startSlot!\n const event = new Event<Slot, CompositionStartEventData>(startSlot, {\n index: startIndex\n })\n invokeListener(startSlot.parent!, 'onCompositionStart', event)\n }),\n fromEvent<CompositionEvent>(textarea, 'compositionupdate').pipe(filter(() => {\n return !this.ignoreComposition\n })).pipe(distinctUntilChanged((prev, next) => {\n return prev.data !== next.data\n })).subscribe(ev => {\n if (ev.data === ' ') {\n // 处理搜狗五笔不符合 composition 事件预期,会意外跳光标的问题\n return\n }\n const startSlot = this.selection.startSlot!\n this.domAdapter.composition = {\n slot: startSlot,\n text: ev.data,\n offset: ev.data.length,\n index: startIndex\n }\n\n this.caret.changeFromSelf = true\n this.caret.refresh()\n const event = new Event(startSlot, {\n index: startIndex,\n data: ev.data\n })\n\n invokeListener(startSlot.parent!, 'onCompositionUpdate', event)\n startSlot.__changeMarker__.forceMarkDirtied()\n })\n )\n let isCompositionEnd = false\n this.subscription.add(\n merge(\n fromEvent<InputEvent>(textarea, 'beforeinput').pipe(\n filter(ev => {\n ev.preventDefault()\n if (this.isFirefox && ev.inputType === 'insertFromPaste') {\n return false\n }\n if (this.isSafari) {\n isCompositionEnd = ev.inputType === 'insertFromComposition'\n return ev.inputType === 'insertText' || ev.inputType === 'insertFromComposition'\n }\n return !ev.isComposing && !!ev.data\n }),\n map(ev => {\n return ev.data as string\n })\n ),\n this.isSafari ? new Observable<string>() : fromEvent<CompositionEvent>(textarea, 'compositionend')\n .pipe(filter(() => {\n return !this.ignoreComposition\n })).pipe(\n map(ev => {\n isCompositionEnd = true\n ev.preventDefault()\n textarea.value = ''\n return ev.data\n })\n )\n ).subscribe(text => {\n this.composition = false\n this.domAdapter.composition = null\n if (text) {\n this.caret.changeFromSelf = true\n this.commander.write(text)\n } else {\n this.selection.startSlot?.__changeMarker__.forceMarkDirtied()\n }\n if (isCompositionEnd) {\n const startSlot = this.selection.startSlot\n if (startSlot) {\n const event = new Event<Slot>(startSlot, null)\n invokeListener(startSlot.parent!, 'onCompositionEnd', event)\n }\n }\n isCompositionEnd = false\n })\n )\n }\n\n private createEditableFrame() {\n return createElement('iframe', {\n attrs: {\n scrolling: 'no'\n },\n styles: {\n border: 'none',\n width: '100%',\n display: 'block',\n height: '100%',\n position: 'relative',\n top: this.isWindows ? '3px' : '0'\n }\n }) as HTMLIFrameElement\n }\n}\n","import { Injectable, Optional } from '@viewfly/core'\nimport { Selection, AbstractSelection, Scheduler, Textbus, SelectionPaths } from '@textbus/core'\nimport { fromEvent, Subject, Subscription } from '@tanbo/stream'\n\nimport { VIEW_CONTAINER } from './injection-tokens'\nimport { SelectionBridge } from './selection-bridge'\nimport { createElement, getLayoutRectByRange, Rect } from './_utils/uikit'\n\nexport interface SelectionRect extends Rect {\n color: string\n username: string\n}\n\nexport interface RemoteSelectionCursor {\n cursor: HTMLElement\n anchor: HTMLElement\n userTip: HTMLElement\n}\n\n/**\n * 远程光标绘制范围计算代理类,可用于定制特定场景下的远程选区绘制,如表格有选区,不会遵守常见的文档流形式\n */\nexport abstract class CollaborateSelectionAwarenessDelegate {\n abstract getRects(abstractSelection: AbstractSelection,\n nativeRange: Range,\n selectionCursor: UserSelectionCursor): false | Rect[]\n}\n\n/**\n * 协作用户虚拟光标信息\n */\nexport interface UserSelectionCursor {\n username: string\n color: string\n selection: SelectionPaths\n data?: any\n}\n\n/**\n * 协作光标绘制类\n */\n@Injectable()\nexport class CollaborateCursor {\n private host = createElement('div', {\n styles: {\n position: 'absolute',\n left: 0,\n top: 0,\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n zIndex: 1\n }\n })\n private canvasContainer = createElement('div', {\n styles: {\n position: 'absolute',\n left: 0,\n top: 0,\n width: '100%',\n height: '100%',\n overflow: 'hidden'\n }\n })\n private canvas = createElement('canvas', {\n styles: {\n position: 'absolute',\n opacity: 0.5,\n left: 0,\n top: 0,\n width: '100%',\n height: document.documentElement.clientHeight + 'px',\n pointerEvents: 'none',\n }\n }) as HTMLCanvasElement\n private context = this.canvas.getContext('2d')!\n private tooltips = createElement('div', {\n styles: {\n position: 'absolute',\n left: 0,\n top: 0,\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n fontSize: '12px',\n zIndex: 10\n }\n })\n\n private onRectsChange = new Subject<SelectionRect[]>()\n\n private subscription = new Subscription()\n private selectionCursors: UserSelectionCursor[] = []\n private container: HTMLElement\n private ratio = window.devicePixelRatio || 1\n\n constructor(textbus: Textbus,\n private nativeSelection: SelectionBridge,\n private scheduler: Scheduler,\n private selection: Selection,\n @Optional() private awarenessDelegate?: CollaborateSelectionAwarenessDelegate) {\n this.container = textbus.get(VIEW_CONTAINER)\n this.canvasContainer.append(this.canvas)\n this.host.append(this.canvasContainer, this.tooltips)\n this.container.prepend(this.host)\n this.subscription.add(this.onRectsChange.subscribe(rects => {\n for (const rect of rects) {\n this.context.fillStyle = rect.color\n this.context.beginPath()\n this.context.rect(rect.left, rect.top, rect.width, rect.height)\n this.context.fill()\n this.context.closePath()\n }\n }), fromEvent(window, 'resize').subscribe(() => {\n this.canvas.style.height = document.documentElement.clientHeight + 'px'\n this.refresh()\n }), this.scheduler.onDocChanged.subscribe(() => {\n this.refresh()\n }))\n }\n\n /**\n * 刷新协作光标,由于 Textbus 只会绘制可视区域的光标,当可视区域发生变化时,需要重新绘制\n */\n refresh() {\n this.draw(this.selectionCursors)\n }\n\n destroy() {\n this.subscription.unsubscribe()\n }\n\n /**\n * 根据远程用户光标位置,绘制协作光标\n * @param paths\n */\n draw(paths: UserSelectionCursor[]) {\n this.selectionCursors = paths\n const containerRect = this.container.getBoundingClientRect()\n this.canvas.style.top = containerRect.top * -1 + 'px'\n this.canvas.width = this.canvas.offsetWidth * this.ratio\n this.canvas.height = this.canvas.offsetHeight * this.ratio\n this.context.scale(this.ratio, this.ratio)\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)\n\n const users: SelectionRect[] = []\n\n paths.filter(i => {\n return i.selection.anchor.length && i.selection.focus.length\n }).forEach(item => {\n const anchorPaths = [...item.selection.anchor]\n const focusPaths = [...item.selection.focus]\n const anchorOffset = anchorPaths.pop()!\n const anchorSlot = this.selection.findSlotByPaths(anchorPaths)\n const focusOffset = focusPaths.pop()!\n const focusSlot = this.selection.findSlotByPaths(focusPaths)\n if (!anchorSlot || !focusSlot) {\n return\n }\n\n const { focus, anchor } = this.nativeSelection.getPositionByRange({\n focusOffset,\n anchorOffset,\n focusSlot,\n anchorSlot\n })\n if (!focus || !anchor) {\n return\n }\n const nativeRange = document.createRange()\n try {\n nativeRange.setStart(anchor.node, anchor.offset)\n nativeRange.setEnd(focus.node, focus.offset)\n } catch (e) {\n return\n }\n if ((anchor.node !== focus.node || anchor.offset !== focus.offset) && nativeRange.collapsed) {\n nativeRange.setStart(focus.node, focus.offset)\n nativeRange.setEnd(anchor.node, anchor.offset)\n }\n\n let rects: Rect[] | DOMRectList | false = false\n if (this.awarenessDelegate) {\n rects = this.awarenessDelegate.getRects({\n focusOffset,\n anchorOffset,\n focusSlot,\n anchorSlot\n }, nativeRange, item)\n }\n if (!rects) {\n rects = nativeRange.getClientRects()\n }\n const selectionRects: SelectionRect[] = []\n for (let i = rects.length - 1; i >= 0; i--) {\n const rect = rects[i]\n selectionRects.push({\n color: item.color,\n username: item.username,\n left: rect.left - containerRect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n })\n }\n this.onRectsChange.next(selectionRects)\n\n const cursorRange = nativeRange.cloneRange()\n cursorRange.setStart(focus.node, focus.offset)\n cursorRange.collapse(true)\n\n const cursorRect = getLayoutRectByRange(cursorRange)\n\n const rect: SelectionRect = {\n username: item.username,\n color: item.color,\n left: cursorRect.left - containerRect.left,\n top: cursorRect.top - containerRect.top,\n width: 1,\n height: cursorRect.height\n }\n if (rect.left < 0 || rect.top < 0 || rect.left > containerRect.width) {\n return\n }\n users.push(rect)\n })\n this.drawUserCursor(users)\n }\n\n protected drawUserCursor(rects: SelectionRect[]) {\n for (let i = 0; i < rects.length; i++) {\n const rect = rects[i]\n const { cursor, userTip, anchor } = this.getUserCursor(i)\n Object.assign(cursor.style, {\n left: rect.left + 'px',\n top: rect.top + 'px',\n width: rect.width + 'px',\n height: rect.height + 'px',\n background: rect.color,\n display: 'block'\n })\n anchor.style.background = rect.color\n userTip.innerText = rect.username\n userTip.style.background = rect.color\n }\n\n for (let i = rects.length; i < this.tooltips.children.length; i++) {\n this.tooltips.removeChild(this.tooltips.children[i])\n }\n }\n\n private getUserCursor(index: number): RemoteSelectionCursor {\n let child: HTMLElement = this.tooltips.children[index] as HTMLElement\n if (child) {\n const anchor = child.children[0] as HTMLElement\n return {\n cursor: child,\n anchor,\n userTip: anchor.children[0] as HTMLElement\n }\n }\n const userTip = createElement('span', {\n styles: {\n position: 'absolute',\n left: '50%',\n transform: 'translateX(-50%)',\n marginBottom: '2px',\n bottom: '100%',\n whiteSpace: 'nowrap',\n color: '#fff',\n boxShadow: '0 1px 2px rgba(0,0,0,.1)',\n opacity: 0.8,\n borderRadius: '3px',\n padding: '3px 5px',\n pointerEvents: 'none',\n }\n })\n\n const anchor = createElement('span', {\n styles: {\n position: 'absolute',\n top: '-2px',\n left: '-2px',\n width: '5px',\n height: '5px',\n borderRadius: '50%',\n pointerEvents: 'auto',\n pointer: 'cursor',\n },\n children: [userTip]\n })\n child = createElement('span', {\n styles: {\n position: 'absolute',\n },\n children: [\n anchor\n ]\n })\n this.tooltips.append(child)\n return {\n cursor: child,\n anchor,\n userTip\n }\n }\n}\n","import { Injectable } from '@viewfly/core'\nimport {\n distinctUntilChanged,\n filter,\n fromEvent,\n map,\n merge,\n Observable,\n Subject,\n Subscription,\n} from '@tanbo/stream'\nimport {\n Commander,\n CompositionStartEventData,\n CompositionUpdateEventData,\n ContentType,\n Controller,\n Event,\n invokeListener,\n Keyboard,\n Selection,\n Slot,\n Textbus\n} from '@textbus/core'\n\nimport { Caret, CaretPosition, Input } from './types'\nimport { VIEW_DOCUMENT } from './injection-tokens'\nimport { isSafari, isMac, isMobileBrowser, isFirefox } from './_utils/env'\nimport { Parser } from './parser'\nimport { getLayoutRectByRange } from './_utils/uikit'\nimport { DomAdapter } from './dom-adapter'\n\nclass NativeCaret implements Caret {\n onPositionChange: Observable<CaretPosition | null>\n\n set nativeRange(range: Range | null) {\n this._nativeRange = range\n if (range) {\n const r = range.cloneRange()\n r.collapse(true)\n const rect = getLayoutRectByRange(r)\n this.positionChangeEvent.next({\n left: rect.left,\n top: rect.top,\n height: rect.height\n })\n } else {\n this.positionChangeEvent.next(null)\n }\n }\n\n get nativeRange() {\n return this._nativeRange\n }\n\n get rect() {\n if (this.nativeRange) {\n const range = this.nativeRange.cloneRange()\n range.collapse(true)\n return getLayoutRectByRange(range)\n }\n return {\n left: 0,\n top: 0,\n width: 0,\n height: 0\n }\n }\n\n private _nativeRange: Range | null = null\n private subs: Subscription[] = []\n\n private positionChangeEvent = new Subject<CaretPosition | null>()\n\n constructor() {\n this.onPositionChange = this.positionChangeEvent.pipe(distinctUntilChanged())\n }\n\n refresh() {\n //\n }\n\n destroy() {\n this.subs.forEach(i => i.unsubscribe())\n this.subs = []\n }\n}\n\n@Injectable()\nexport class NativeInput extends Input {\n caret = new NativeCaret()\n\n composition = false\n // compositionState: CompositionState | null = null\n\n onReady = Promise.resolve()\n\n set disabled(b: boolean) {\n this._disabled = b\n if (this.controller.readonly) {\n this.documentView.contentEditable = 'false'\n return\n }\n this.documentView.contentEditable = b ? 'false' : 'true'\n }\n\n get disabled() {\n return this._disabled\n }\n\n private _disabled = false\n private documentView: HTMLElement\n private nativeSelection = document.getSelection()!\n\n private subscription = new Subscription()\n private nativeRange: Range | null = null\n\n private isSafari = isSafari()\n private isMac = isMac()\n private isMobileBrowser = isMobileBrowser()\n\n private ignoreComposition = false // 有 bug 版本搜狗拼音\n\n constructor(textbus: Textbus,\n private parser: Parser,\n private selection: Selection,\n private keyboard: Keyboard,\n private domAdapter: DomAdapter,\n private commander: Commander,\n private controller: Controller) {\n super()\n this.documentView = textbus.get(VIEW_DOCUMENT)\n if (!controller.readonly) {\n this.documentView.contentEditable = 'true'\n }\n this.subscription.add(\n controller.onReadonlyStateChange.subscribe(() => {\n this.documentView.contentEditable = controller.readonly ? 'false' : 'true'\n })\n )\n this.handleShortcut(this.documentView)\n this.handleInput(this.documentView)\n this.handleDefaultActions(this.documentView)\n }\n\n focus(nativeRange: Range) {\n if (this.controller.readonly) {\n return\n }\n this.caret.nativeRange = nativeRange\n this.nativeRange = nativeRange\n }\n\n blur() {\n if (this.nativeRange && this.nativeSelection.rangeCount > 0) {\n const current = this.nativeSelection.getRangeAt(0)\n if (current === this.nativeRange) {\n this.nativeSelection.removeAllRanges()\n this.nativeRange = null\n return\n }\n }\n }\n\n destroy() {\n this.caret.destroy()\n this.subscription.unsubscribe()\n }\n\n private handleDefaultActions(textarea: HTMLElement) {\n this.subscription.add(\n fromEvent<ClipboardEvent>(isFirefox() ? textarea : document, 'copy').subscribe(ev => {\n this.copyHandler(ev)\n }),\n fromEvent<ClipboardEvent>(textarea, 'paste').subscribe(ev => {\n this.pasteHandler(ev)\n })\n )\n }\n\n copyHandler(ev: ClipboardEvent) {\n const selection = this.selection\n if (!selection.isSelected) {\n return\n }\n if (selection.startSlot === selection.endSlot && selection.endOffset! - selection.startOffset! === 1) {\n const content = selection.startSlot!.getContentAtIndex(selection.startOffset!)\n if (typeof content === 'object') {\n const clipboardData = ev.clipboardData!\n const nativeSelection = document.getSelection()!\n const range = nativeSelection.getRangeAt(0)\n const div = document.createElement('div')\n const fragment = range.cloneContents()\n div.append(fragment)\n clipboardData.setData('text/html', div.innerHTML)\n clipboardData.setData('text', div.innerText)\n ev.preventDefault()\n }\n }\n }\n\n pasteHandler(ev: ClipboardEvent) {\n const text = ev.clipboardData!.getData('Text')\n\n const types = Array.from(ev.clipboardData!.types || [])\n const files = Array.from(ev.clipboardData!.files)\n if (types.every(type => type === 'Files') && files.length) {\n Promise.all(files.filter(i => {\n return /image/i.test(i.type)\n }).map(item => {\n const reader = new FileReader()\n return new Promise(resolve => {\n reader.onload = (event) => {\n resolve(event.target!.result)\n }\n reader.readAsDataURL(item)\n })\n })).then(urls => {\n const html = urls.map(i => {\n return `<img src=${i}>`\n }).join('')\n this.paste(html, text)\n })\n ev.preventDefault()\n return\n }\n\n const div = document.createElement('div')\n div.style.cssText = 'width:1px; height:10px; overflow: hidden; position: fixed; left: 50%; top: 50%; opacity:0'\n div.contentEditable = 'true'\n document.body.appendChild(div)\n div.focus()\n setTimeout(() => {\n document.body.removeChild(div)\n div.style.cssText = ''\n this.paste(div, text)\n })\n }\n\n private paste(dom: HTMLElement | string, text: string) {\n const slot = this.parser.parse(dom, new Slot([\n ContentType.BlockComponent,\n ContentType.InlineComponent,\n ContentType.Text\n ]))\n\n this.commander.paste(slot, text)\n }\n\n private handleShortcut(input: HTMLElement) {\n let isWriting = false\n let isIgnore = false\n this.subscription.add(\n fromEvent(input, 'compositionstart').subscribe(() => {\n isWriting = true\n }),\n fromEvent(input, 'compositionend').subscribe(() => {\n isWriting = false\n }),\n fromEvent<InputEvent>(input, 'beforeinput').subscribe(ev => {\n if (this.isSafari) {\n if (ev.inputType === 'insertFromComposition') {\n isIgnore = true\n }\n }\n }),\n fromEvent<KeyboardEvent>(input, 'keydown').pipe(filter(() => {\n if (this.isSafari && isIgnore) {\n isIgnore = false\n return false\n }\n return !isWriting // || !this.textarea.value\n })).subscribe(ev => {\n this.ignoreComposition = false\n let key = ev.key\n const keys = ')!@#$%^Z&*('\n const b = key === 'Process' && /Digit\\d/.test(ev.code) && ev.shiftKey\n if (b) {\n key = keys.charAt(+ev.code.substring(5))\n ev.preventDefault()\n }\n const is = this.keyboard.execShortcut({\n key: key,\n altKey: ev.altKey,\n shiftKey: ev.shiftKey,\n modKey: this.isMac ? ev.metaKey : ev.ctrlKey,\n agent: {\n key: ev.key,\n keyCode: ev.keyCode,\n code: ev.code\n }\n })\n if (is) {\n this.ignoreComposition = true\n ev.preventDefault()\n }\n })\n )\n }\n\n private handleInput(input: HTMLElement) {\n if (this.isMobileBrowser) {\n this.handleMobileInput(input)\n } else {\n this.handlePCInput(input)\n }\n }\n\n private handleMobileInput(input: HTMLElement) {\n let isCompositionStart = true\n let startIndex: number\n const compositionStart = () => {\n this.composition = true\n startIndex = this.selection.startOffset!\n const startSlot = this.selection.startSlot!\n const event = new Event<Slot, CompositionStartEventData>(startSlot, {\n index: startIndex\n })\n invokeListener(startSlot.parent!, 'onCompositionStart', event)\n }\n const compositionUpdate = (data: string) => {\n const startSlot = this.selection.startSlot!\n const event = new Event<Slot, CompositionUpdateEventData>(startSlot, {\n index: startIndex,\n data\n })\n\n invokeListener(startSlot.parent!, 'onCompositionUpdate', event)\n }\n const compositionEnd = (data: string) => {\n this.composition = false\n\n if (data) {\n this.commander.write(data)\n }\n const startSlot = this.selection.startSlot\n if (startSlot) {\n const event = new Event<Slot>(startSlot, null)\n invokeListener(startSlot.parent!, 'onCompositionEnd', event)\n }\n }\n this.subscription.add(\n fromEvent(input, 'compositionstart').subscribe(() => {\n compositionStart()\n }),\n fromEvent<CompositionEvent>(input, 'compositionupdate').subscribe(ev => {\n compositionUpdate(ev.data)\n }),\n fromEvent<CompositionEvent>(input, 'compositionend').subscribe(ev => {\n compositionEnd(ev.data)\n const startContainer = this.nativeSelection.focusNode\n if (startContainer instanceof Text && startContainer.textContent === ev.data) {\n startContainer.remove()\n }\n }),\n fromEvent<InputEvent>(input, 'beforeinput').subscribe(ev => {\n switch (ev.inputType) {\n case 'insertText':\n if (ev.data) {\n this.commander.write(ev.data)\n ev.preventDefault()\n }\n break\n case 'insertCompositionText':\n if (isCompositionStart) {\n isCompositionStart = false\n compositionStart()\n } else {\n compositionUpdate(ev.data || '')\n }\n break\n case 'deleteCompositionText':\n this.composition = false\n break\n case 'deleteContentBackward': {\n this.composition = false\n const range = ev.getTargetRanges()[0]\n if (!range) {\n break\n }\n const location = this.domAdapter.getLocationByNativeNode(range.startContainer)!\n const startSlot = this.selection.startSlot\n if (startSlot) {\n this.selection.setBaseAndExtent(\n startSlot,\n location.startIndex + range.startOffset,\n startSlot,\n location.startIndex + range.endOffset)\n\n this.commander.delete()\n }\n break\n }\n case 'insertReplacementText': {\n this.composition = false\n const range = ev.getTargetRanges()[0]\n const location = this.domAdapter.getLocationByNativeNode(range.startContainer)!\n const startSlot = this.selection.startSlot!\n this.selection.setBaseAndExtent(\n startSlot,\n location.startIndex + range.startOffset,\n startSlot,\n location.startIndex + range.endOffset)\n\n this.commander.delete()\n const text = ev.dataTransfer?.getData('text') || ev.data || null\n if (text) {\n this.commander.write(text)\n }\n break\n }\n //\n // case 'insertFromComposition': {\n // compositionEnd(ev.data || '')\n // break\n // }\n }\n })\n )\n }\n\n private handlePCInput(input: HTMLElement) {\n let startIndex = 0\n let isCompositionEnd = false\n this.subscription.add(\n fromEvent(input, 'compositionstart').pipe(filter(() => {\n return !this.ignoreComposition\n })).subscribe(() => {\n this.composition = true\n startIndex = this.selection.startOffset!\n const startSlot = this.selection.startSlot!\n const event = new Event<Slot, CompositionStartEventData>(startSlot, {\n index: startIndex\n })\n invokeListener(startSlot.parent!, 'onCompositionStart', event)\n }),\n fromEvent<CompositionEvent>(input, 'compositionupdate').pipe(filter(() => {\n return !this.ignoreComposition\n })).subscribe(ev => {\n const startSlot = this.selection.startSlot!\n const event = new Event(startSlot, {\n index: startIndex,\n data: ev.data\n })\n\n invokeListener(startSlot.parent!, 'onCompositionUpdate', event)\n }),\n merge(\n fromEvent<InputEvent>(input, 'beforeinput').pipe(\n map(ev => {\n ev.preventDefault()\n if (ev.inputType === 'insertCompositionText') {\n return null\n }\n if (ev.inputType === 'insertReplacementText') {\n const range = ev.getTargetRanges()[0]\n const location = this.domAdapter.getLocationByNativeNode(range.startContainer)!\n const startSlot = this.selection.startSlot!\n this.selection.setBaseAndExtent(\n startSlot,\n location.startIndex + range.startOffset,\n startSlot,\n location.startIndex + range.endOffset)\n\n this.commander.delete()\n return ev.dataTransfer?.getData('text') || ev.data || null\n }\n isCompositionEnd = ev.inputType === 'insertFromComposition'\n if (isCompositionEnd && this.composition) {\n return null\n }\n if (this.isSafari) {\n if (ev.inputType === 'insertText' || isCompositionEnd) {\n return ev.data\n }\n }\n if (!ev.isComposing && !!ev.data) {\n return ev.data\n }\n return null\n }),\n filter(text => {\n return text\n })\n ),\n this.isSafari ? new Observable<string>() :\n fromEvent<CompositionEvent>(input, 'compositionend').pipe(filter(() => {\n return !this.ignoreComposition\n })).pipe(\n filter(() => {\n return this.composition\n }),\n map(ev => {\n isCompositionEnd = true\n ev.preventDefault()\n return ev.data\n }),\n filter(() => {\n const b = this.ignoreComposition\n this.ignoreComposition = false\n return !b\n })\n )\n ).subscribe(text => {\n this.composition = false\n if (text) {\n const startContainer = this.nativeSelection.focusNode\n if (startContainer instanceof Text && startContainer.textContent === text) {\n startContainer.remove()\n }\n this.commander.write(text)\n }\n if (isCompositionEnd) {\n const startSlot = this.selection.startSlot\n if (startSlot) {\n const event = new Event<Slot>(startSlot, null)\n invokeListener(startSlot.parent!, 'onCompositionEnd', event)\n }\n }\n isCompositionEnd = false\n })\n )\n }\n}\n","import { Adapter } from '@textbus/core'\nimport { Subject } from '@tanbo/stream'\n\nimport { createElement } from './_utils/uikit'\nimport { VIEW_DOCUMENT } from './injection-tokens'\n\nexport abstract class DomAdapter<\n ViewComponent extends object = object,\n ViewElement extends object = object> extends Adapter<Element, Node, ViewComponent, ViewElement> {\n onViewUpdated = new Subject<void>()\n host = createElement('div', {\n styles: {\n cursor: 'text',\n wordBreak: 'break-all',\n boxSizing: 'border-box',\n flex: 1,\n outline: 'none'\n },\n attrs: {\n 'data-textbus-view': VIEW_DOCUMENT,\n },\n props: {\n id: 'textbus-' + Number((Math.random() + '').substring(2)).toString(16)\n }\n })\n}\n","import {\n ComponentConstructor,\n Component,\n ComponentLiteral,\n FocusManager,\n makeError,\n Module,\n NativeSelectionBridge,\n Registry,\n Textbus,\n Adapter,\n} from '@textbus/core'\nimport { Provider } from '@viewfly/core'\nimport { distinctUntilChanged, map, Subject } from '@tanbo/stream'\n\nimport { AttributeLoader, ComponentLoader, FormatLoader, Parser } from './parser'\nimport { EDITOR_OPTIONS, VIEW_CONTAINER, VIEW_DOCUMENT, VIEW_MASK } from './injection-tokens'\nimport { SelectionBridge } from './selection-bridge'\nimport { Input } from './types'\nimport { MagicInput } from './magic-input'\nimport { CollaborateCursor } from './collaborate-cursor'\nimport { createElement } from './_utils/uikit'\nimport { NativeInput } from './native-input'\nimport { DomAdapter } from './dom-adapter'\n\nconst browserErrorFn = makeError('BrowserModule')\n\n/**\n * Textbus PC 端配置接口\n */\nexport interface ViewOptions {\n /** 跨平台适配器 */\n adapter: DomAdapter<any, any>\n\n /** 编辑器根节点 */\n renderTo(): HTMLElement\n\n /** 自动获取焦点 */\n autoFocus?: boolean\n /** 编辑区最小高度 */\n minHeight?: string\n /** 组件加载器 */\n componentLoaders?: ComponentLoader[]\n /** 格式加载器 */\n formatLoaders?: FormatLoader<any>[]\n /** 属性加载器 */\n attributeLoaders?: AttributeLoader<any>[]\n /** 使用 contentEditable 作为编辑器控制可编辑范围 */\n useContentEditable?: boolean\n}\n\nexport class BrowserModule implements Module {\n providers: Provider[]\n\n private workbench!: HTMLElement\n\n constructor(public config: ViewOptions) {\n const { mask, wrapper } = BrowserModule.createLayout()\n wrapper.prepend(config.adapter.host)\n if (config.minHeight) {\n config.adapter.host.style.minHeight = config.minHeight\n }\n this.providers = [{\n provide: EDITOR_OPTIONS,\n useValue: config\n }, {\n provide: VIEW_CONTAINER,\n useValue: wrapper\n }, {\n provide: VIEW_DOCUMENT,\n useValue: config.adapter.host\n }, {\n provide: VIEW_MASK,\n useValue: mask\n }, {\n provide: NativeSelectionBridge,\n useExisting: SelectionBridge\n }, {\n provide: Input,\n useClass: config.useContentEditable ? NativeInput : MagicInput\n }, {\n provide: Adapter,\n useValue: config.adapter\n }, {\n provide: DomAdapter,\n useValue: config.adapter\n }, {\n provide: FocusManager,\n useFactory: (input: Input): FocusManager => {\n const focusEvent = new Subject<void>()\n const blurEvent = new Subject<void>()\n input.caret.onPositionChange.pipe(\n map(p => !!p),\n distinctUntilChanged()\n ).subscribe(b => {\n if (b) {\n focusEvent.next()\n } else {\n blurEvent.next()\n }\n })\n return {\n onFocus: focusEvent,\n onBlur: blurEvent\n }\n },\n deps: [Input]\n },\n Parser,\n SelectionBridge,\n CollaborateCursor\n ]\n\n this.workbench = wrapper\n }\n\n /**\n * 解析 HTML 并返回一个组件实例\n * @param html 要解析的 HTML\n * @param rootComponentLoader 文档根组件加载器\n * @param textbus\n */\n readDocumentByHTML(html: string, rootComponentLoader: ComponentLoader, textbus: Textbus): Component {\n const parser = textbus.get(Parser)\n const doc = parser.parseDoc(html, rootComponentLoader)\n if (doc instanceof Component) {\n return doc\n }\n throw browserErrorFn('rootComponentLoader must return a component instance.')\n }\n\n /**\n * 将组件数据解析到组件实例中\n * @param data 要解析的 JSON 数据\n * @param rootComponent 根组件\n * @param textbus\n */\n readDocumentByComponentLiteral(data: ComponentLiteral, rootComponent: ComponentConstructor, textbus: Textbus): Component {\n const registry = textbus.get(Registry)\n return registry.createComponentByFactory(data, rootComponent)\n }\n\n async setup(textbus: Textbus) {\n const host = this.config.renderTo()\n if (!(host instanceof HTMLElement)) {\n throw browserErrorFn('view container is not a HTMLElement')\n }\n\n host.append(this.workbench)\n await textbus.get(Input).onReady\n return () => {\n this.workbench.remove()\n }\n }\n\n onAfterStartup(textbus: Textbus) {\n if (this.config.autoFocus) {\n textbus.focus()\n }\n }\n\n onDestroy(textbus: Textbus) {\n textbus.get(Input).destroy()\n textbus.get(SelectionBridge).destroy()\n textbus.get(CollaborateCursor).destroy()\n }\n\n private static createLayout() {\n const mask = createElement('div', {\n attrs: {\n 'data-textbus-view': VIEW_MASK,\n },\n styles: {\n position: 'absolute',\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n pointerEvents: 'none',\n // overflow: 'hidden'\n }\n })\n const maskWrapper = createElement('div', {\n styles: {\n position: 'absolute',\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n margin: '0 -2px',\n zIndex: 1,\n pointerEvents: 'none',\n overflow: 'hidden'\n },\n children: [mask]\n })\n const wrapper = createElement('div', {\n attrs: {\n 'data-textbus-view': VIEW_CONTAINER,\n },\n styles: {\n display: 'flex',\n minHeight: '100%',\n position: 'relative',\n flexDirection: 'column'\n },\n children: [maskWrapper]\n })\n return {\n wrapper,\n mask\n }\n }\n}\n"],"names":["createElement","tagName","options","el","key","i","item","getLayoutRectByRange","range","startContainer","startOffset","parentNode","beforeNode","rect","range2","offsetNode","isInsertBefore","lastChild","span","isWindows","isMac","isSafari","isFirefox","isMobileBrowser","EDITOR_OPTIONS","InjectionToken","VIEW_CONTAINER","VIEW_DOCUMENT","VIEW_MASK","Parser","textbus","componentLoaders","formatLoaders","attributeLoaders","html","rootComponentLoader","element","childSlot","slotRootElement","slotContentHostElement","rootSlot","slot","schema","t","result","Slot","textContent","formats","f","startIndex","startNode","endIndex","slotContentElement","a","r","formatItems","__decorateClass","Injectable","__decorateParam","SelectionBridge","config","controller","selection","rootComponentRef","input","scheduler","domAdapter","filter","fromEvent","ev","target","Subject","connector","location","focus","anchor","nativeRange","abstractSelection","fromLocal","tryOffset","position","len","e","bind","currentPosition","toNext","p","startLeft","isToPrevLine","loopCount","minLeft","focusSlot","focusOffset","minTop","oldPosition","oldLeft","rect2","isToNextLine","maxRight","isUpdating","delay","rawRange","isFocusEnd","isFocusStart","nativeNode","startPosition","endPosition","start","end","offset","prev","nodes","node","current","toAfter","excludeNodes","containerPosition","childNode","childPosition","prevNode","prevPosition","nextNode","next","firstChild","nextSibling","parentPosition","Input","iframeHTML","ExperimentalCaret","domRenderer","editorMask","distinctUntilChanged","v","Subscription","restart","toggleShowHide","compositionNode","fontSize","lineHeight","color","writingMode","height","boxHeight","rectTop","containerRect","top","left","rotate","hackEle","pointEle","p1","p2","x","y","selfRect","scrollContainer","scrollRect","limit","bottom","container","styles","MagicInput","parser","keyboard","commander","resolve","doc","b","contentBody","textarea","style","clipboardData","div","fragment","text","types","files","type","reader","event","urls","dom","ContentType","isWriting","isIgnore","startSlot","Event","invokeListener","isCompositionEnd","merge","map","Observable","CollaborateSelectionAwarenessDelegate","CollaborateCursor","nativeSelection","awarenessDelegate","rects","paths","users","anchorPaths","focusPaths","anchorOffset","anchorSlot","selectionRects","cursorRange","cursorRect","cursor","userTip","index","child","Optional","NativeCaret","NativeInput","isCompositionStart","compositionStart","compositionUpdate","data","compositionEnd","DomAdapter","Adapter","browserErrorFn","makeError","BrowserModule","mask","wrapper","NativeSelectionBridge","FocusManager","focusEvent","blurEvent","Component","rootComponent","Registry","host","maskWrapper"],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("@textbus/core"),c=require("@tanbo/stream"),C=require("@viewfly/core");function y(f,t={}){const s=document.createElement(f);return t.classes&&s.classList.add(...t.classes),t.attrs&&Object.keys(t.attrs).forEach(i=>{s.setAttribute(i,t.attrs[i])}),t.props&&Object.keys(t.props).forEach(i=>{s[i]=t.props[i]}),t.styles&&Object.assign(s.style,t.styles),t.children&&t.children.filter(i=>i).forEach(i=>{s.appendChild(i)}),t.on&&Object.keys(t.on).forEach(i=>{s.addEventListener(i,t.on[i])}),s}function N(f){let{startContainer:t,startOffset:s}=f;if(t.nodeType===Node.TEXT_NODE){if(s>0)return f.getBoundingClientRect();const a=t.parentNode;s=Array.from(a.childNodes).indexOf(t),t=a}const i=t.childNodes[s-1];if(i){if(i.nodeType===Node.ELEMENT_NODE&&i.nodeName.toLowerCase()!=="br"){const a=i.getBoundingClientRect();return{left:a.right,top:a.top,width:f.collapsed?1:a.width,height:a.height}}else if(i.nodeType===Node.TEXT_NODE){const a=document.createRange();a.setStart(i,i.textContent.length),a.setEnd(i,i.textContent.length);const l=a.getBoundingClientRect();return{left:l.right,top:l.top,width:f.collapsed?1:l.width,height:l.height}}}const e=t.childNodes[s];let o=!1;if(!e){const a=t.lastChild;if(a&&a.nodeType===Node.ELEMENT_NODE){const l=a.getBoundingClientRect();return{left:l.right,top:l.top,width:f.collapsed?1:l.width,height:l.height}}}if(e){if(e.nodeType===Node.ELEMENT_NODE&&e.nodeName.toLowerCase()!=="br"){const a=e.getBoundingClientRect();return{left:a.left,top:a.top,width:f.collapsed?1:a.width,height:a.height}}o=!0}const n=t.ownerDocument.createElement("span");n.innerText="​",n.style.display="inline-block",o?t.insertBefore(n,e):t.appendChild(n);const r=n.getBoundingClientRect();return t.removeChild(n),{left:r.left,top:r.top,width:f.collapsed?1:r.width,height:r.height}}const M=()=>/win(dows|32|64)/i.test(navigator.userAgent),_=()=>/mac os/i.test(navigator.userAgent),A=()=>/Safari/.test(navigator.userAgent)&&!/Chrome/.test(navigator.userAgent),D=()=>/Firefox/.test(navigator.userAgent),j=()=>/Android|iPhone|iPad/.test(navigator.userAgent),B=new C.InjectionToken("EDITOR_OPTIONS"),I=new C.InjectionToken("VIEW_CONTAINER"),O=new C.InjectionToken("VIEW_DOCUMENT"),L=new C.InjectionToken("VIEW_MASK");var U=Object.getOwnPropertyDescriptor,V=(f,t,s,i)=>{for(var e=i>1?void 0:i?U(t,s):t,o=f.length-1,n;o>=0;o--)(n=f[o])&&(e=n(e)||e);return e},K=(f,t)=>(s,i)=>t(s,i,f);exports.Parser=class{constructor(t,s){this.textbus=s;const i=[...t.componentLoaders||[]],e=[...t.formatLoaders||[]],o=[...t.attributeLoaders||[]];this.componentLoaders=i,this.formatLoaders=e,this.attributeLoaders=o}textbus;static parseHTML(t){return new DOMParser().parseFromString(t,"text/html").body}componentLoaders;formatLoaders;attributeLoaders;parseDoc(t,s){const i=typeof t=="string"?exports.Parser.parseHTML(t):t;return s.read(i,this.textbus,(e,o,n=o)=>this.readSlot(e,o,n))}parse(t,s){const i=typeof t=="string"?exports.Parser.parseHTML(t):t;return this.readFormats(i,s)}readComponent(t,s){if(t.nodeType===Node.ELEMENT_NODE){if(t.tagName==="BR"){s.insert(`
2
+ `);return}const i=[...s.schema];for(const e of this.componentLoaders)if(e.match(t,i)){const o=e.read(t,this.textbus,(n,r,a=r)=>this.readSlot(n,r,a));if(!o)return;if(o instanceof u.Slot){o.toDelta().forEach(n=>s.insert(n.insert,n.formats));return}s.insert(o);return}this.readFormats(t,s)}else t.nodeType===Node.TEXT_NODE&&this.readText(s,t)}readText(t,s){const i=s.textContent;/^\s*[\r\n\u200b]+\s*$/.test(i)||t.insert(i)}readFormats(t,s){const i=this.formatLoaders.filter(r=>r.match(t)).map(r=>r.read(t)),e=s.index;let o=t.firstChild;for(;o;)this.readComponent(o,s),o=o.nextSibling;const n=s.index;return this.applyFormats(s,i.map(r=>({formatter:r.formatter,value:r.value,startIndex:e,endIndex:n}))),s.retain(n),s}readSlot(t,s,i){return s.nodeType===Node.ELEMENT_NODE&&this.attributeLoaders.filter(e=>e.match(s)).forEach(e=>{const o=e.read(s);t.setAttribute(o.attribute,o.value)}),i.nodeType===Node.ELEMENT_NODE?this.readFormats(i,t):this.readText(t,i),t}applyFormats(t,s){t.background(()=>{s.forEach(i=>{t.retain(i.startIndex),t.retain(i.endIndex-i.startIndex,i.formatter,i.value)})})}};exports.Parser=V([C.Injectable(),K(0,C.Inject(B))],exports.Parser);var $=Object.getOwnPropertyDescriptor,W=(f,t,s,i)=>{for(var e=i>1?void 0:i?$(t,s):t,o=f.length-1,n;o>=0;o--)(n=f[o])&&(e=n(e)||e);return e},X=(f,t)=>(s,i)=>t(s,i,f);exports.SelectionBridge=class{constructor(t,s,i,e,o,n,r,a){this.config=t,this.selection=e,this.rootComponentRef=o,this.input=n,this.scheduler=r,this.domAdapter=a,this.docContainer=s.get(O),this.onSelectionChange=this.selectionChangeEvent.asObservable().pipe(c.filter(()=>!i.readonly)),this.sub=this.onSelectionChange.subscribe(l=>{l?n.focus(l,this.changeFromUser):n.blur()}),this.sub.add(c.fromEvent(document,"focusin").subscribe(l=>{let d=l.target;if(/^(input|textarea|select)$/i.test(d.nodeName)){if(d.tagName.toLowerCase()==="input"&&/^(range|date)$/.test(d.type))return;this.ignoreSelectionChange=!0;return}if(!t.useContentEditable)for(;d;){if(d.contentEditable==="true"){this.ignoreSelectionChange=!0;return}d=d.parentNode}})),this.sub.add(c.fromEvent(document,"focusout").subscribe(()=>{this.ignoreSelectionChange=!1}))}config;selection;rootComponentRef;input;scheduler;domAdapter;onSelectionChange;nativeSelection=document.getSelection();syncSelectionFromNativeSelectionChange=!0;selectionChangeEvent=new c.Subject;subs=[];sub;connector=null;ignoreSelectionChange=!1;changeFromUser=!1;docContainer;cacheCaretPositionTimer;oldCaretPosition;connect(t){this.disConnect(),this.connector=t,this.syncSelection(t),this.listen(t)}disConnect(){this.connector=null,this.unListen()}getRect(t){const{focus:s,anchor:i}=this.getPositionByRange({focusOffset:t.offset,anchorOffset:t.offset,focusSlot:t.slot,anchorSlot:t.slot});if(!s||!i)return null;const e=document.createRange();return e.setStart(s.node,s.offset),e.collapse(),N(e)}restore(t,s){if(this.changeFromUser=s,this.ignoreSelectionChange||!this.connector)return;if(this.unListen(),!t){this.nativeSelection.removeAllRanges(),this.selectionChangeEvent.next(null),this.listen(this.connector);return}const{focus:i,anchor:e}=this.getPositionByRange(t);if(!i||!e){this.nativeSelection.removeAllRanges(),this.selectionChangeEvent.next(null),this.listen(this.connector);return}function o(r){if(r.node){if(r.node.nodeType===Node.TEXT_NODE){const a=r.node.textContent.length;r.offset>a&&(r.offset=a)}else if(r.node.nodeType===Node.ELEMENT_NODE){const a=r.node.childNodes.length;r.offset>a&&(r.offset=a)}}}try{o(i),o(e),this.nativeSelection.setBaseAndExtent(e.node,e.offset,i.node,i.offset)}catch(r){setTimeout(()=>{throw r})}if(this.nativeSelection.rangeCount){const r=this.nativeSelection.getRangeAt(0);this.selectionChangeEvent.next(r)}else this.selectionChangeEvent.next(null);const n=()=>{this.connector&&this.listen(this.connector)};if(s){Promise.resolve().then(n);return}typeof requestIdleCallback=="function"?requestIdleCallback(n):setTimeout(n,30)}destroy(){this.subs.forEach(t=>t.unsubscribe()),this.sub.unsubscribe()}getPositionByRange(t){let s,i;try{return s=this.findSelectedNodeAndOffset(t.focusSlot,t.focusOffset),i=s,(t.anchorSlot!==t.focusSlot||t.anchorOffset!==t.focusOffset)&&(i=this.findSelectedNodeAndOffset(t.anchorSlot,t.anchorOffset)),{focus:s,anchor:i}}catch{return{focus:null,anchor:null}}}getPreviousLinePositionByCurrent(t){return this.getLinePosition(t,!1)}getNextLinePositionByCurrent(t){return this.getLinePosition(t,!0)}getLinePosition(t,s){clearTimeout(this.cacheCaretPositionTimer);let i;return this.oldCaretPosition?i=s?this.getNextLinePositionByOffset(t,this.oldCaretPosition.left):this.getPreviousLinePositionByOffset(t,this.oldCaretPosition.left):(this.oldCaretPosition=this.getRect(t),i=s?this.getNextLinePositionByOffset(t,this.oldCaretPosition.left):this.getPreviousLinePositionByOffset(t,this.oldCaretPosition.left)),this.cacheCaretPositionTimer=setTimeout(()=>{this.oldCaretPosition=null},3e3),i}getPreviousLinePositionByOffset(t,s){let i=!1,e=0,o=s,n=t.slot,r=t.offset,a=this.getRect({slot:n,offset:r}).top,l,d,m=0;for(;;){e++,l=this.selection.getPreviousPositionByPosition(n,r),n=l.slot,r=l.offset;const h=this.getRect(l);if(!i){if(h.left>o||h.top+h.height<=a)i=!0;else if(h.left===o&&h.top===a)return l;o=h.left,a=h.top}if(i){if(h.left<=s)return l;if(d&&h.left>=m)return d;m=h.left,d=l}if(e>1e4)break}return l||{offset:0,slot:n}}getNextLinePositionByOffset(t,s){let i=!1,e=0,o=s,n=t.slot,r=t.offset;const a=this.getRect({slot:n,offset:r});let l=a.top,d,m=0;for(;;){e++;const h=this.selection.getNextPositionByPosition(n,r);n=h.slot,r=h.offset;const p=this.getRect(h);if(!i){if(p.left<o||p.top>=l+a.height)i=!0;else if(p.left===o&&p.top===l)return h;o=p.left,l=p.top,d=h}if(i){if(p.left>s||d&&p.left<=m)return d;d=h,m=p.left}if(e>1e4)break}return d||{offset:n.length,slot:n}}unListen(){this.subs.forEach(t=>t.unsubscribe()),this.subs=[]}listen(t){if(!this.config.useContentEditable){const i=this.nativeSelection;this.subs.push(c.fromEvent(this.docContainer,"mousedown").subscribe(e=>{this.ignoreSelectionChange||e.button===2||e.shiftKey||i.removeAllRanges()}))}let s=!1;this.subs.push(this.scheduler.onDocChange.subscribe(()=>{s=!0}),this.scheduler.onDocChanged.pipe(c.delay()).subscribe(()=>{s=!1}),c.fromEvent(document,"selectionchange").subscribe(()=>{s||this.syncSelectionFromNativeSelectionChange&&this.syncSelection(t)}))}syncSelection(t){const s=this.nativeSelection;if(this.changeFromUser=!0,this.ignoreSelectionChange||this.input.composition||s.rangeCount===0||!this.docContainer.contains(s.anchorNode)||this.rootComponentRef.component.slots.length===0)return;const i=s.getRangeAt(0),e=i.cloneRange(),o=s.focusNode===e.endContainer&&s.focusOffset===e.endOffset,n=s.focusNode===e.startContainer&&s.focusOffset===e.startOffset;if(!this.docContainer.contains(s.focusNode))if(o){const l=this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.slots.at(0));if(!l)return;e.setEndAfter(l.lastChild)}else{const l=this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.slots.at(-1));if(!l)return;e.setStartBefore(l.firstChild)}const r=this.getCorrectedPosition(e.startContainer,e.startOffset,n),a=e.collapsed?r:this.getCorrectedPosition(e.endContainer,e.endOffset,o);if([Node.ELEMENT_NODE,Node.TEXT_NODE].includes(e.commonAncestorContainer?.nodeType)&&r&&a){const l=t.beforeChange(o?{anchorSlot:r.slot,anchorOffset:r.offset,focusSlot:a.slot,focusOffset:a.offset}:{focusSlot:r.slot,focusOffset:r.offset,anchorSlot:a.slot,anchorOffset:a.offset});if(!l){this.selectionChangeEvent.next(null),t.setSelection(null);return}const{focus:d,anchor:m}=this.getPositionByRange(l);if(d&&m){let h=m,p=d;n&&(h=d,p=m),(e.startContainer!==h.node||e.startOffset!==h.offset)&&e.setStart(h.node,h.offset),(e.endContainer!==p.node||e.endOffset!==p.offset)&&e.setEnd(p.node,p.offset),t.setSelection(l),s.isCollapsed&&(i.startContainer!==h.node||i.startOffset!==h.offset||i.endContainer!==p.node||i.endOffset!==p.offset)&&(i.setStart(h.node,h.offset),i.setEnd(p.node,p.offset)),this.selectionChangeEvent.next(e)}else t.setSelection(null);return}t.setSelection(null)}findSelectedNodeAndOffset(t,s){const i=t.getContentAtIndex(s-1),e=this.domAdapter.getNodesBySlot(t);if(i){if(typeof i!="string"){const n=this.domAdapter.getNativeNodeByComponent(i);return{node:n.parentNode,offset:Array.from(n.parentNode.childNodes).indexOf(n)+1}}else if(i===`
3
+ `){for(const n of e)if(!(n instanceof Text)&&n.nodeName==="BR"){const r=this.domAdapter.getLocationByNativeNode(n);if(r&&r.endIndex===s){const a=n.parentNode;return{node:a,offset:Array.from(a.childNodes).indexOf(n)+1}}}}}const o=t.getContentAtIndex(s);if(o&&typeof o!="string"){const n=this.domAdapter.getNativeNodeByComponent(o);return{node:n.parentNode,offset:Array.from(n.parentNode.childNodes).indexOf(n)}}for(const n of e){if(n instanceof Element){if(n.tagName==="BR"){const a=this.domAdapter.getLocationByNativeNode(n);if(a&&a.startIndex===s){const l=n.parentNode;return{node:l,offset:Array.from(l.childNodes).indexOf(n)}}}continue}const r=this.domAdapter.getLocationByNativeNode(n);if(r&&s>=r.startIndex&&s<=r.endIndex)return{node:n,offset:s-r.startIndex}}return null}getCorrectedPosition(t,s,i,e=[]){if(e.push(t),t.nodeType===Node.ELEMENT_NODE){const o=this.domAdapter.getLocationByNativeNode(t),n=t.childNodes[s];if(n){const l=this.domAdapter.getLocationByNativeNode(n);return l?o?{slot:l.slot,offset:l.startIndex}:this.findFocusNode(n,i,e):this.findFocusNode(n,i,e)}const r=t.childNodes[s-1];if(r){const l=this.domAdapter.getLocationByNativeNode(r);if(l&&o)return{slot:l.slot,offset:l.endIndex}}if(o)return{slot:o.slot,offset:o.endIndex};const a=i?t.nextSibling:t.previousSibling;return a?this.findFocusNode(a,i,e):this.findFocusNodeByParent(t,i,e)}else if(t.nodeType===Node.TEXT_NODE){const o=this.domAdapter.getLocationByNativeNode(t);if(o)return{slot:o.slot,offset:o.startIndex+s};const n=i?t.nextSibling:t.previousSibling;return n?this.findFocusNode(n,i,e):this.findFocusNodeByParent(t,i,e)}return null}findFocusNode(t,s=!1,i=[]){if(i.includes(t)){const r=s?t.nextSibling:t.previousSibling;return r?this.findFocusNode(r,s,i):this.findFocusNodeByParent(t,s,i)}i.push(t);const e=this.domAdapter.getLocationByNativeNode(t);if(e)return{slot:e.slot,offset:s?e.startIndex:e.endIndex};const o=s?t.firstChild:t.lastChild;if(o)return this.findFocusNode(o,s,i);const n=s?t.nextSibling:t.previousSibling;return n?this.findFocusNode(n,s,i):this.findFocusNodeByParent(t,s,i)}findFocusNodeByParent(t,s,i){const e=t.parentNode;if(e){const o=this.domAdapter.getLocationByNativeNode(e);return o?{slot:o.slot,offset:s?o.endIndex:o.startIndex}:(i.push(t),this.findFocusNode(e,s,i))}return null}};exports.SelectionBridge=W([C.Injectable(),X(0,C.Inject(B))],exports.SelectionBridge);class w{}var z=Object.getOwnPropertyDescriptor,q=(f,t,s,i)=>{for(var e=i>1?void 0:i?z(t,s):t,o=f.length-1,n;o>=0;o--)(n=f[o])&&(e=n(e)||e);return e};const Y=`
4
+ <!DOCTYPE html>
5
+ <html>
6
+ <head>
7
+ <meta charset="UTF-8">
8
+ <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
9
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
10
+ <title>Textbus</title>
11
+ <style>
12
+ html {position: fixed; left:0; overflow: hidden}
13
+ html, body{height: 100%;width:100%}
14
+ body{margin:0; overflow: hidden}
15
+ textarea{width: 2000px;height: 100%;opacity: 0; padding: 0; outline: none; border: none; position: absolute; left:0; top:0;}
16
+ </style>
17
+ </head>
18
+ <body>
19
+ </body>
20
+ </html>
21
+ `;class Z{constructor(t,s,i){this.domRenderer=t,this.scheduler=s,this.editorMask=i,this.onPositionChange=this.positionChangeEvent.pipe(c.distinctUntilChanged()),this.onStyleChange=this.styleChangeEvent.asObservable(),this.elementRef=y("div",{styles:{position:"absolute",width:"2px",pointerEvents:"none"},children:[this.caret=y("span",{styles:{width:"100%",height:"100%",position:"absolute",left:0,top:0}})]}),this.subscription.add(c.fromEvent(document,"mousedown").subscribe(()=>{this.flashing=!1}),c.fromEvent(document,"mouseup").subscribe(()=>{this.flashing=!0})),this.editorMask.appendChild(this.elementRef)}domRenderer;scheduler;editorMask;onPositionChange;onStyleChange;elementRef;changeFromSelf=!1;getLimit=function(){return{top:0,bottom:document.documentElement.clientHeight}};get rect(){return this.caret.getBoundingClientRect()}timer=null;caret;set display(t){this._display=t,this.caret.style.visibility=t?"visible":"hidden"}get display(){return this._display}_display=!0;flashing=!0;subscription=new c.Subscription;positionChangeEvent=new c.Subject;styleChangeEvent=new c.Subject;oldRange=null;refresh(){this.oldRange&&this.show(this.oldRange,!1)}show(t,s){if(this.oldRange=t,(s||this.scheduler.lastChangesHasLocalUpdate)&&clearTimeout(this.timer),this.updateCursorPosition(t),t.collapsed){if(s||this.scheduler.lastChangesHasLocalUpdate){this.display=!0;const i=()=>{this.display=!this.display||!this.flashing,this.timer=setTimeout(i,400)};clearTimeout(this.timer),this.timer=setTimeout(i,400)}}else this.display=!1,clearTimeout(this.timer)}hide(){this.display=!1,clearTimeout(this.timer),this.positionChangeEvent.next(null)}destroy(){clearTimeout(this.timer),this.subscription.unsubscribe()}updateCursorPosition(t){const s=t.startContainer,i=s.nodeType===Node.ELEMENT_NODE?s:s.parentNode;if(i?.nodeType!==Node.ELEMENT_NODE){this.positionChangeEvent.next(null);return}const e=this.domRenderer.compositionNode;e&&(t=t.cloneRange(),t.selectNodeContents(e),t.collapse());const o=N(t),{fontSize:n,lineHeight:r,color:a,writingMode:l}=getComputedStyle(i);let d;if(isNaN(+r)){const g=parseFloat(r);isNaN(g)?d=parseFloat(n):d=g}else d=parseFloat(n)*parseFloat(r);const m=Math.max(Math.floor(Math.max(d,o.height)),12);let h=o.top;o.height<d&&(h-=(d-o.height)/2),h=Math.floor(h);const p=this.editorMask.getBoundingClientRect(),S=Math.floor(h-p.top),T=Math.floor(o.left+o.width/2-p.left);let x=0;if(t.collapsed&&(x=Math.round(Math.atan2(o.width,o.height)*180/Math.PI),x!==0)){const g=document.createElement("span");g.style.cssText="display: inline-block; width: 10px; height: 10px; position: relative; contain: layout style size; writing-mode: inherit";const b=document.createElement("span");b.style.cssText="position: absolute; left: 0; top: 0; width:0;height:0",g.append(b),i.append(g);const v=b.getBoundingClientRect();b.style.right="0",b.style.left="";const E=b.getBoundingClientRect(),R=v.x-E.x,P=v.y-E.y;x=Math.atan2(P,R)*180/Math.PI,g.remove()}if((l==="vertical-lr"||l==="vertical-rl")&&(x+=90),Object.assign(this.elementRef.style,{left:T+"px",top:S+"px",height:m+"px",lineHeight:m+"px",fontSize:n,transform:`rotate(${x}deg)`}),this.caret.style.backgroundColor=a==="rgba(0, 0, 0, 0)"?"#000":a,this.styleChangeEvent.next({height:m+"px",lineHeight:m+"px",fontSize:n}),this.positionChangeEvent.next({left:T,top:h,height:m}),this.changeFromSelf){this.changeFromSelf=!1;const g=this.elementRef.getBoundingClientRect(),b=this.getScrollContainer(s),v=b===document.documentElement?{top:0,bottom:document.documentElement.clientHeight}:b.getBoundingClientRect(),E=this.getLimit(),R=Math.max(E.top,v.top),P=Math.min(E.bottom,v.bottom);g.top<R?b.scrollTop-=R-g.top:g.bottom>P&&(b.scrollTop+=g.bottom-P)}}getScrollContainer(t){for(;t;){if(t instanceof Element){const s=getComputedStyle(t);if(s.overflow!=="visible"||s.overflowX!=="visible"||s.overflowY!=="visible")return t}t=t.parentNode}return document.documentElement}}exports.MagicInput=class extends w{constructor(t,s,i,e,o,n,r,a){super(),this.domAdapter=t,this.parser=s,this.keyboard=i,this.commander=e,this.selection=o,this.controller=n,this.scheduler=r,this.textbus=a,this.caret=new Z(this.domAdapter,this.scheduler,this.textbus.get(L)),this.onReady=new Promise(l=>{this.subscription.add(c.fromEvent(this.container,"load").subscribe(()=>{const d=this.container.contentDocument;d.open(),d.write(Y),d.close(),this.doc=d,this.init(),l()}),n.onReadonlyStateChange.subscribe(()=>{n.readonly&&this.blur()}))}),this.caret.elementRef.append(this.container)}domAdapter;parser;keyboard;commander;selection;controller;scheduler;textbus;composition=!1;onReady;caret;set disabled(t){this._disabled=t,t&&this.textarea&&(this.textarea.disabled=t)}get disabled(){return this._disabled}isSafari=A();isFirefox=D();isMac=_();isWindows=M();_disabled=!1;container=this.createEditableFrame();subscription=new c.Subscription;doc;textarea=null;isFocus=!1;nativeFocus=!1;ignoreComposition=!1;focus(t,s){this.disabled||this.caret.show(t,s),!this.controller.readonly&&(this.isFocus||(this.textarea?.focus(),setTimeout(()=>{!this.nativeFocus&&this.isFocus&&this.reInit()})),this.isFocus=!0)}blur(){this.caret.hide(),this.textarea?.blur(),this.isFocus=!1}destroy(){this.caret.destroy(),this.subscription.unsubscribe()}reInit(t=!1){this.subscription.unsubscribe(),this.textarea?.parentNode?.removeChild(this.textarea),this.subscription=new c.Subscription,this.init(),t?setTimeout(()=>{this.textarea?.focus()}):this.textarea?.focus()}init(){const t=this.doc,s=t.body,i=t.createElement("textarea");i.disabled=this.disabled,s.appendChild(i),this.textarea=i,this.subscription.add(c.fromEvent(i,"blur").subscribe(()=>{if(this.isFocus=!1,this.nativeFocus=!1,this.caret.hide(),this.domAdapter.composition){const e=this.domAdapter.composition.slot;this.domAdapter.composition=null,this.domAdapter.compositionNode=null,e.__changeMarker__.forceMarkDirtied()}}),c.fromEvent(i,"focus").subscribe(()=>{this.nativeFocus=!0}),this.caret.onStyleChange.subscribe(e=>{Object.assign(i.style,e)})),this.handleInput(i),this.handleShortcut(i),this.handleDefaultActions(i)}handleDefaultActions(t){this.subscription.add(c.fromEvent(D()?t:document,"copy").subscribe(s=>{this.copyHandler(s)}),c.fromEvent(t,"paste").subscribe(s=>{this.pasteHandler(s)}))}copyHandler(t){const s=this.selection;if(s.isSelected&&s.startSlot===s.endSlot&&s.endOffset-s.startOffset===1&&typeof s.startSlot.getContentAtIndex(s.startOffset)=="object"){const e=t.clipboardData,n=document.getSelection().getRangeAt(0),r=document.createElement("div"),a=n.cloneContents();r.append(a),e.setData("text/html",r.innerHTML),e.setData("text",r.innerText),t.preventDefault()}}pasteHandler(t){const s=t.clipboardData.getData("Text"),i=Array.from(t.clipboardData.types||[]),e=Array.from(t.clipboardData.files);if(i.every(n=>n==="Files")&&e.length){Promise.all(e.filter(n=>/image/i.test(n.type)).map(n=>{const r=new FileReader;return new Promise(a=>{r.onload=l=>{a(l.target.result)},r.readAsDataURL(n)})})).then(n=>{const r=n.map(a=>`<img src=${a}>`).join("");this.paste(r,s)}),t.preventDefault();return}const o=this.doc.createElement("div");o.style.cssText="width:1px; height:10px; overflow: hidden; position: fixed; left: 50%; top: 50%; opacity:0",o.contentEditable="true",this.doc.body.appendChild(o),o.focus(),setTimeout(()=>{this.doc.body.removeChild(o),o.style.cssText="",this.paste(o,s)})}paste(t,s){const i=this.parser.parse(t,new u.Slot([u.ContentType.BlockComponent,u.ContentType.InlineComponent,u.ContentType.Text]));this.commander.paste(i,s)}handleShortcut(t){let s=!1,i=!1;this.subscription.add(c.fromEvent(t,"compositionstart").subscribe(()=>{s=!0}),c.fromEvent(t,"compositionend").subscribe(()=>{s=!1}),c.fromEvent(t,"beforeinput").subscribe(e=>{this.ignoreComposition=!1,this.isSafari&&e.inputType==="insertFromComposition"&&(i=!0)}),c.fromEvent(t,"keydown").pipe(c.filter(()=>this.isSafari&&i?(i=!1,!1):!s)).subscribe(e=>{this.ignoreComposition=!1;let o=e.key;o==="Process"&&/Digit\d/.test(e.code)&&e.shiftKey&&(o=")!@#$%^Z&*(".charAt(+e.code.substring(5)),e.preventDefault()),this.caret.changeFromSelf=!0,this.keyboard.execShortcut({key:o,altKey:e.altKey,shiftKey:e.shiftKey,modKey:this.isMac?e.metaKey:e.ctrlKey,agent:{key:e.key,code:e.code,keyCode:e.keyCode}})?(this.ignoreComposition=!0,e.preventDefault()):this.caret.changeFromSelf=!1}))}handleInput(t){let s=0;this.subscription.add(c.fromEvent(t,"compositionstart").pipe(c.filter(()=>!this.ignoreComposition)).subscribe(()=>{this.selection.isCollapsed||(this.caret.changeFromSelf=!0,this.commander.delete()),this.composition=!0,s=this.selection.startOffset;const e=this.selection.startSlot,o=new u.Event(e,{index:s});u.invokeListener(e.parent,"onCompositionStart",o)}),c.fromEvent(t,"compositionupdate").pipe(c.filter(()=>!this.ignoreComposition)).pipe(c.distinctUntilChanged((e,o)=>e.data!==o.data)).subscribe(e=>{if(e.data===" ")return;const o=this.selection.startSlot;this.domAdapter.composition={slot:o,text:e.data,offset:e.data.length,index:s},this.caret.changeFromSelf=!0,this.caret.refresh();const n=new u.Event(o,{index:s,data:e.data});u.invokeListener(o.parent,"onCompositionUpdate",n),o.__changeMarker__.forceMarkDirtied()}));let i=!1;this.subscription.add(c.merge(c.fromEvent(t,"beforeinput").pipe(c.filter(e=>(e.preventDefault(),this.isFirefox&&e.inputType==="insertFromPaste"?!1:this.isSafari?(i=e.inputType==="insertFromComposition",e.inputType==="insertText"||e.inputType==="insertFromComposition"):!e.isComposing&&!!e.data)),c.map(e=>e.data)),this.isSafari?new c.Observable:c.fromEvent(t,"compositionend").pipe(c.filter(()=>!this.ignoreComposition)).pipe(c.map(e=>(i=!0,e.preventDefault(),t.value="",e.data)))).subscribe(e=>{if(this.composition=!1,this.domAdapter.composition=null,e?(this.caret.changeFromSelf=!0,this.commander.write(e)):this.selection.startSlot?.__changeMarker__.forceMarkDirtied(),i){const o=this.selection.startSlot;if(o){const n=new u.Event(o,null);u.invokeListener(o.parent,"onCompositionEnd",n)}}i=!1}))}createEditableFrame(){return y("iframe",{attrs:{scrolling:"no"},styles:{border:"none",width:"100%",display:"block",height:"100%",position:"relative",top:this.isWindows?"3px":"0"}})}};exports.MagicInput=q([C.Injectable()],exports.MagicInput);var G=Object.getOwnPropertyDescriptor,J=(f,t,s,i)=>{for(var e=i>1?void 0:i?G(t,s):t,o=f.length-1,n;o>=0;o--)(n=f[o])&&(e=n(e)||e);return e},Q=(f,t)=>(s,i)=>t(s,i,f);class tt{}exports.CollaborateCursor=class{constructor(t,s,i,e,o){this.nativeSelection=s,this.scheduler=i,this.selection=e,this.awarenessDelegate=o,this.container=t.get(I),this.canvasContainer.append(this.canvas),this.host.append(this.canvasContainer,this.tooltips),this.container.prepend(this.host),this.subscription.add(this.onRectsChange.subscribe(n=>{for(const r of n)this.context.fillStyle=r.color,this.context.beginPath(),this.context.rect(r.left,r.top,r.width,r.height),this.context.fill(),this.context.closePath()}),c.fromEvent(window,"resize").subscribe(()=>{this.canvas.style.height=document.documentElement.clientHeight+"px",this.refresh()}),this.scheduler.onDocChanged.subscribe(()=>{this.refresh()}))}nativeSelection;scheduler;selection;awarenessDelegate;host=y("div",{styles:{position:"absolute",left:0,top:0,width:"100%",height:"100%",pointerEvents:"none",zIndex:1}});canvasContainer=y("div",{styles:{position:"absolute",left:0,top:0,width:"100%",height:"100%",overflow:"hidden"}});canvas=y("canvas",{styles:{position:"absolute",opacity:.5,left:0,top:0,width:"100%",height:document.documentElement.clientHeight+"px",pointerEvents:"none"}});context=this.canvas.getContext("2d");tooltips=y("div",{styles:{position:"absolute",left:0,top:0,width:"100%",height:"100%",pointerEvents:"none",fontSize:"12px",zIndex:10}});onRectsChange=new c.Subject;subscription=new c.Subscription;selectionCursors=[];container;ratio=window.devicePixelRatio||1;refresh(){this.draw(this.selectionCursors)}destroy(){this.subscription.unsubscribe()}draw(t){this.selectionCursors=t;const s=this.container.getBoundingClientRect();this.canvas.style.top=s.top*-1+"px",this.canvas.width=this.canvas.offsetWidth*this.ratio,this.canvas.height=this.canvas.offsetHeight*this.ratio,this.context.scale(this.ratio,this.ratio),this.context.clearRect(0,0,this.canvas.width,this.canvas.height);const i=[];t.filter(e=>e.selection.anchor.length&&e.selection.focus.length).forEach(e=>{const o=[...e.selection.anchor],n=[...e.selection.focus],r=o.pop(),a=this.selection.findSlotByPaths(o),l=n.pop(),d=this.selection.findSlotByPaths(n);if(!a||!d)return;const{focus:m,anchor:h}=this.nativeSelection.getPositionByRange({focusOffset:l,anchorOffset:r,focusSlot:d,anchorSlot:a});if(!m||!h)return;const p=document.createRange();try{p.setStart(h.node,h.offset),p.setEnd(m.node,m.offset)}catch{return}(h.node!==m.node||h.offset!==m.offset)&&p.collapsed&&(p.setStart(m.node,m.offset),p.setEnd(h.node,h.offset));let S=!1;this.awarenessDelegate&&(S=this.awarenessDelegate.getRects({focusOffset:l,anchorOffset:r,focusSlot:d,anchorSlot:a},p,e)),S||(S=p.getClientRects());const T=[];for(let v=S.length-1;v>=0;v--){const E=S[v];T.push({color:e.color,username:e.username,left:E.left-s.left,top:E.top,width:E.width,height:E.height})}this.onRectsChange.next(T);const x=p.cloneRange();x.setStart(m.node,m.offset),x.collapse(!0);const g=N(x),b={username:e.username,color:e.color,left:g.left-s.left,top:g.top-s.top,width:1,height:g.height};b.left<0||b.top<0||b.left>s.width||i.push(b)}),this.drawUserCursor(i)}drawUserCursor(t){for(let s=0;s<t.length;s++){const i=t[s],{cursor:e,userTip:o,anchor:n}=this.getUserCursor(s);Object.assign(e.style,{left:i.left+"px",top:i.top+"px",width:i.width+"px",height:i.height+"px",background:i.color,display:"block"}),n.style.background=i.color,o.innerText=i.username,o.style.background=i.color}for(let s=t.length;s<this.tooltips.children.length;s++)this.tooltips.removeChild(this.tooltips.children[s])}getUserCursor(t){let s=this.tooltips.children[t];if(s){const o=s.children[0];return{cursor:s,anchor:o,userTip:o.children[0]}}const i=y("span",{styles:{position:"absolute",left:"50%",transform:"translateX(-50%)",marginBottom:"2px",bottom:"100%",whiteSpace:"nowrap",color:"#fff",boxShadow:"0 1px 2px rgba(0,0,0,.1)",opacity:.8,borderRadius:"3px",padding:"3px 5px",pointerEvents:"none"}}),e=y("span",{styles:{position:"absolute",top:"-2px",left:"-2px",width:"5px",height:"5px",borderRadius:"50%",pointerEvents:"auto",pointer:"cursor"},children:[i]});return s=y("span",{styles:{position:"absolute"},children:[e]}),this.tooltips.append(s),{cursor:s,anchor:e,userTip:i}}};exports.CollaborateCursor=J([C.Injectable(),Q(4,C.Optional())],exports.CollaborateCursor);var et=Object.getOwnPropertyDescriptor,st=(f,t,s,i)=>{for(var e=i>1?void 0:i?et(t,s):t,o=f.length-1,n;o>=0;o--)(n=f[o])&&(e=n(e)||e);return e};class it{onPositionChange;set nativeRange(t){if(this._nativeRange=t,t){const s=t.cloneRange();s.collapse(!0);const i=N(s);this.positionChangeEvent.next({left:i.left,top:i.top,height:i.height})}else this.positionChangeEvent.next(null)}get nativeRange(){return this._nativeRange}get rect(){if(this.nativeRange){const t=this.nativeRange.cloneRange();return t.collapse(!0),N(t)}return{left:0,top:0,width:0,height:0}}_nativeRange=null;subs=[];positionChangeEvent=new c.Subject;constructor(){this.onPositionChange=this.positionChangeEvent.pipe(c.distinctUntilChanged())}refresh(){}destroy(){this.subs.forEach(t=>t.unsubscribe()),this.subs=[]}}exports.NativeInput=class extends w{constructor(t,s,i,e,o,n,r){super(),this.parser=s,this.selection=i,this.keyboard=e,this.domAdapter=o,this.commander=n,this.controller=r,this.documentView=t.get(O),r.readonly||(this.documentView.contentEditable="true"),this.subscription.add(r.onReadonlyStateChange.subscribe(()=>{this.documentView.contentEditable=r.readonly?"false":"true"})),this.handleShortcut(this.documentView),this.handleInput(this.documentView),this.handleDefaultActions(this.documentView)}parser;selection;keyboard;domAdapter;commander;controller;caret=new it;composition=!1;onReady=Promise.resolve();set disabled(t){if(this._disabled=t,this.controller.readonly){this.documentView.contentEditable="false";return}this.documentView.contentEditable=t?"false":"true"}get disabled(){return this._disabled}_disabled=!1;documentView;nativeSelection=document.getSelection();subscription=new c.Subscription;nativeRange=null;isSafari=A();isMac=_();isMobileBrowser=j();ignoreComposition=!1;focus(t){this.controller.readonly||(this.caret.nativeRange=t,this.nativeRange=t)}blur(){if(this.nativeRange&&this.nativeSelection.rangeCount>0&&this.nativeSelection.getRangeAt(0)===this.nativeRange){this.nativeSelection.removeAllRanges(),this.nativeRange=null;return}}destroy(){this.caret.destroy(),this.subscription.unsubscribe()}handleDefaultActions(t){this.subscription.add(c.fromEvent(D()?t:document,"copy").subscribe(s=>{this.copyHandler(s)}),c.fromEvent(t,"paste").subscribe(s=>{this.pasteHandler(s)}))}copyHandler(t){const s=this.selection;if(s.isSelected&&s.startSlot===s.endSlot&&s.endOffset-s.startOffset===1&&typeof s.startSlot.getContentAtIndex(s.startOffset)=="object"){const e=t.clipboardData,n=document.getSelection().getRangeAt(0),r=document.createElement("div"),a=n.cloneContents();r.append(a),e.setData("text/html",r.innerHTML),e.setData("text",r.innerText),t.preventDefault()}}pasteHandler(t){const s=t.clipboardData.getData("Text"),i=Array.from(t.clipboardData.types||[]),e=Array.from(t.clipboardData.files);if(i.every(n=>n==="Files")&&e.length){Promise.all(e.filter(n=>/image/i.test(n.type)).map(n=>{const r=new FileReader;return new Promise(a=>{r.onload=l=>{a(l.target.result)},r.readAsDataURL(n)})})).then(n=>{const r=n.map(a=>`<img src=${a}>`).join("");this.paste(r,s)}),t.preventDefault();return}const o=document.createElement("div");o.style.cssText="width:1px; height:10px; overflow: hidden; position: fixed; left: 50%; top: 50%; opacity:0",o.contentEditable="true",document.body.appendChild(o),o.focus(),setTimeout(()=>{document.body.removeChild(o),o.style.cssText="",this.paste(o,s)})}paste(t,s){const i=this.parser.parse(t,new u.Slot([u.ContentType.BlockComponent,u.ContentType.InlineComponent,u.ContentType.Text]));this.commander.paste(i,s)}handleShortcut(t){let s=!1,i=!1;this.subscription.add(c.fromEvent(t,"compositionstart").subscribe(()=>{s=!0}),c.fromEvent(t,"compositionend").subscribe(()=>{s=!1}),c.fromEvent(t,"beforeinput").subscribe(e=>{this.isSafari&&e.inputType==="insertFromComposition"&&(i=!0)}),c.fromEvent(t,"keydown").pipe(c.filter(()=>this.isSafari&&i?(i=!1,!1):!s)).subscribe(e=>{this.ignoreComposition=!1;let o=e.key;o==="Process"&&/Digit\d/.test(e.code)&&e.shiftKey&&(o=")!@#$%^Z&*(".charAt(+e.code.substring(5)),e.preventDefault()),this.keyboard.execShortcut({key:o,altKey:e.altKey,shiftKey:e.shiftKey,modKey:this.isMac?e.metaKey:e.ctrlKey,agent:{key:e.key,keyCode:e.keyCode,code:e.code}})&&(this.ignoreComposition=!0,e.preventDefault())}))}handleInput(t){this.isMobileBrowser?this.handleMobileInput(t):this.handlePCInput(t)}handleMobileInput(t){let s=!0,i;const e=()=>{this.composition=!0,i=this.selection.startOffset;const r=this.selection.startSlot,a=new u.Event(r,{index:i});u.invokeListener(r.parent,"onCompositionStart",a)},o=r=>{const a=this.selection.startSlot,l=new u.Event(a,{index:i,data:r});u.invokeListener(a.parent,"onCompositionUpdate",l)},n=r=>{this.composition=!1,r&&this.commander.write(r);const a=this.selection.startSlot;if(a){const l=new u.Event(a,null);u.invokeListener(a.parent,"onCompositionEnd",l)}};this.subscription.add(c.fromEvent(t,"compositionstart").subscribe(()=>{e()}),c.fromEvent(t,"compositionupdate").subscribe(r=>{o(r.data)}),c.fromEvent(t,"compositionend").subscribe(r=>{n(r.data);const a=this.nativeSelection.focusNode;a instanceof Text&&a.textContent===r.data&&a.remove()}),c.fromEvent(t,"beforeinput").subscribe(r=>{switch(r.inputType){case"insertText":r.data&&(this.commander.write(r.data),r.preventDefault());break;case"insertCompositionText":s?(s=!1,e()):o(r.data||"");break;case"deleteCompositionText":this.composition=!1;break;case"deleteContentBackward":{this.composition=!1;const a=r.getTargetRanges()[0];if(!a)break;const l=this.domAdapter.getLocationByNativeNode(a.startContainer),d=this.selection.startSlot;d&&(this.selection.setBaseAndExtent(d,l.startIndex+a.startOffset,d,l.startIndex+a.endOffset),this.commander.delete());break}case"insertReplacementText":{this.composition=!1;const a=r.getTargetRanges()[0],l=this.domAdapter.getLocationByNativeNode(a.startContainer),d=this.selection.startSlot;this.selection.setBaseAndExtent(d,l.startIndex+a.startOffset,d,l.startIndex+a.endOffset),this.commander.delete();const m=r.dataTransfer?.getData("text")||r.data||null;m&&this.commander.write(m);break}}}))}handlePCInput(t){let s=0,i=!1;this.subscription.add(c.fromEvent(t,"compositionstart").pipe(c.filter(()=>!this.ignoreComposition)).subscribe(()=>{this.composition=!0,s=this.selection.startOffset;const e=this.selection.startSlot,o=new u.Event(e,{index:s});u.invokeListener(e.parent,"onCompositionStart",o)}),c.fromEvent(t,"compositionupdate").pipe(c.filter(()=>!this.ignoreComposition)).subscribe(e=>{const o=this.selection.startSlot,n=new u.Event(o,{index:s,data:e.data});u.invokeListener(o.parent,"onCompositionUpdate",n)}),c.merge(c.fromEvent(t,"beforeinput").pipe(c.map(e=>{if(e.preventDefault(),e.inputType==="insertCompositionText")return null;if(e.inputType==="insertReplacementText"){const o=e.getTargetRanges()[0],n=this.domAdapter.getLocationByNativeNode(o.startContainer),r=this.selection.startSlot;return this.selection.setBaseAndExtent(r,n.startIndex+o.startOffset,r,n.startIndex+o.endOffset),this.commander.delete(),e.dataTransfer?.getData("text")||e.data||null}return i=e.inputType==="insertFromComposition",i&&this.composition?null:this.isSafari&&(e.inputType==="insertText"||i)||!e.isComposing&&e.data?e.data:null}),c.filter(e=>e)),this.isSafari?new c.Observable:c.fromEvent(t,"compositionend").pipe(c.filter(()=>!this.ignoreComposition)).pipe(c.filter(()=>this.composition),c.map(e=>(i=!0,e.preventDefault(),e.data)),c.filter(()=>{const e=this.ignoreComposition;return this.ignoreComposition=!1,!e}))).subscribe(e=>{if(this.composition=!1,e){const o=this.nativeSelection.focusNode;o instanceof Text&&o.textContent===e&&o.remove(),this.commander.write(e)}if(i){const o=this.selection.startSlot;if(o){const n=new u.Event(o,null);u.invokeListener(o.parent,"onCompositionEnd",n)}}i=!1}))}};exports.NativeInput=st([C.Injectable()],exports.NativeInput);class H extends u.Adapter{onViewUpdated=new c.Subject;host=y("div",{styles:{cursor:"text",wordBreak:"break-all",boxSizing:"border-box",flex:1,outline:"none"},attrs:{"data-textbus-view":O},props:{id:"textbus-"+Number((Math.random()+"").substring(2)).toString(16)}})}const F=u.makeError("BrowserModule");class k{constructor(t){this.config=t;const{mask:s,wrapper:i}=k.createLayout();i.prepend(t.adapter.host),t.minHeight&&(t.adapter.host.style.minHeight=t.minHeight),this.providers=[{provide:B,useValue:t},{provide:I,useValue:i},{provide:O,useValue:t.adapter.host},{provide:L,useValue:s},{provide:u.NativeSelectionBridge,useExisting:exports.SelectionBridge},{provide:w,useClass:t.useContentEditable?exports.NativeInput:exports.MagicInput},{provide:u.Adapter,useValue:t.adapter},{provide:H,useValue:t.adapter},{provide:u.FocusManager,useFactory:e=>{const o=new c.Subject,n=new c.Subject;return e.caret.onPositionChange.pipe(c.map(r=>!!r),c.distinctUntilChanged()).subscribe(r=>{r?o.next():n.next()}),{onFocus:o,onBlur:n}},deps:[w]},exports.Parser,exports.SelectionBridge,exports.CollaborateCursor],this.workbench=i}config;providers;workbench;readDocumentByHTML(t,s,i){const o=i.get(exports.Parser).parseDoc(t,s);if(o instanceof u.Component)return o;throw F("rootComponentLoader must return a component instance.")}readDocumentByComponentLiteral(t,s,i){return i.get(u.Registry).createComponentByFactory(t,s)}async setup(t){const s=this.config.renderTo();if(!(s instanceof HTMLElement))throw F("view container is not a HTMLElement");return s.append(this.workbench),await t.get(w).onReady,()=>{this.workbench.remove()}}onAfterStartup(t){this.config.autoFocus&&t.focus()}onDestroy(t){t.get(w).destroy(),t.get(exports.SelectionBridge).destroy(),t.get(exports.CollaborateCursor).destroy()}static createLayout(){const t=y("div",{attrs:{"data-textbus-view":L},styles:{position:"absolute",left:0,right:0,top:0,bottom:0,pointerEvents:"none"}}),s=y("div",{styles:{position:"absolute",left:0,right:0,top:0,bottom:0,margin:"0 -2px",zIndex:1,pointerEvents:"none",overflow:"hidden"},children:[t]});return{wrapper:y("div",{attrs:{"data-textbus-view":I},styles:{display:"flex",minHeight:"100%",position:"relative",flexDirection:"column"},children:[s]}),mask:t}}}exports.BrowserModule=k;exports.CollaborateSelectionAwarenessDelegate=tt;exports.DomAdapter=H;exports.EDITOR_OPTIONS=B;exports.Input=w;exports.VIEW_CONTAINER=I;exports.VIEW_DOCUMENT=O;exports.VIEW_MASK=L;exports.createElement=y;exports.getLayoutRectByRange=N;exports.isFirefox=D;exports.isMac=_;exports.isMobileBrowser=j;exports.isSafari=A;exports.isWindows=M;
22
+ //# sourceMappingURL=index.js.map